Added select for listen interfaces
This commit is contained in:
parent
5abe5af707
commit
f379d34813
|
@ -164,10 +164,11 @@
|
||||||
"install_settings_title": "Admin Web Interface",
|
"install_settings_title": "Admin Web Interface",
|
||||||
"install_settings_listen": "Listen interface",
|
"install_settings_listen": "Listen interface",
|
||||||
"install_settings_port": "Port",
|
"install_settings_port": "Port",
|
||||||
"install_settings_interface_link": "Your AdGuard Home admin web interface is available on <0>{{link}}</0>",
|
"install_settings_interface_link": "Your AdGuard Home admin web interface will be available on the following addresses: <0>{{link}}</0>",
|
||||||
"form_error_port": "Enter valid port value",
|
"form_error_port": "Enter valid port value",
|
||||||
"install_settings_dns": "DNS server",
|
"install_settings_dns": "DNS server",
|
||||||
"install_settings_dns_desc": "You will need to configure your devices or router to use the DNS server at <0>{{ip}}</0>",
|
"install_settings_dns_desc": "You will need to configure your devices or router to use the DNS server at <0>{{ip}}</0>",
|
||||||
|
"install_settings_all_interfaces": "All interfaces",
|
||||||
"install_auth_title": "Authentication",
|
"install_auth_title": "Authentication",
|
||||||
"install_auth_desc": "It is highly recommended to configure password authentication to your AdGuard Home admin web interface. Even if it is accessible only in your local network, it is still important to have it protected from unrestricted access.",
|
"install_auth_desc": "It is highly recommended to configure password authentication to your AdGuard Home admin web interface. Even if it is accessible only in your local network, it is still important to have it protected from unrestricted access.",
|
||||||
"install_auth_username": "Username",
|
"install_auth_username": "Username",
|
||||||
|
@ -182,6 +183,7 @@
|
||||||
"install_submit_desc": "The setup procedure is finished and you are ready to start using AdGuard Home.",
|
"install_submit_desc": "The setup procedure is finished and you are ready to start using AdGuard Home.",
|
||||||
"install_devices_router": "Router",
|
"install_devices_router": "Router",
|
||||||
"install_devices_router_desc": "This setup will automatically cover all the devices connected to your home router and you will not need to configure each of them manually.",
|
"install_devices_router_desc": "This setup will automatically cover all the devices connected to your home router and you will not need to configure each of them manually.",
|
||||||
|
"install_devices_address": "AdGuard Home DNS server is listening to the following addresses",
|
||||||
"install_devices_router_list_1": "Open the preferences for your router. Usually, you can access it from your browser via a URL (like http://192.168.0.1/ or http://192.168.1.1/). You may be asked to enter the password. If you don't remember it, you can often reset the password by pressing a button on the router itself. Some routers require a specific application, which in that case should be already installed on your computer/phone.",
|
"install_devices_router_list_1": "Open the preferences for your router. Usually, you can access it from your browser via a URL (like http://192.168.0.1/ or http://192.168.1.1/). You may be asked to enter the password. If you don't remember it, you can often reset the password by pressing a button on the router itself. Some routers require a specific application, which in that case should be already installed on your computer/phone.",
|
||||||
"install_devices_router_list_2": "Find the DHCP/DNS settings. Look for the DNS letters next to a field which allows two or three sets of numbers, each broken into four groups of one to three digits.",
|
"install_devices_router_list_2": "Find the DHCP/DNS settings. Look for the DNS letters next to a field which allows two or three sets of numbers, each broken into four groups of one to three digits.",
|
||||||
"install_devices_router_list_3": "Enter your AdGuard Home server addresses there.",
|
"install_devices_router_list_3": "Enter your AdGuard Home server addresses there.",
|
||||||
|
|
|
@ -48,8 +48,10 @@ export const setAllSettings = values => async (dispatch) => {
|
||||||
await apiClient.setAllSettings(config);
|
await apiClient.setAllSettings(config);
|
||||||
dispatch(setAllSettingsSuccess());
|
dispatch(setAllSettingsSuccess());
|
||||||
dispatch(addSuccessToast('install_saved'));
|
dispatch(addSuccessToast('install_saved'));
|
||||||
|
dispatch(nextStep());
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
dispatch(addErrorToast({ error }));
|
dispatch(addErrorToast({ error }));
|
||||||
dispatch(setAllSettingsFailure());
|
dispatch(setAllSettingsFailure());
|
||||||
|
dispatch(prevStep());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -338,16 +338,16 @@ export default class Api {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Installation
|
// Installation
|
||||||
GET_DEFAULT_ADDRESSES = { path: 'install/get_default_addresses', method: 'GET' };
|
INSTALL_GET_ADDRESSES = { path: 'install/get_addresses', method: 'GET' };
|
||||||
SET_ALL_SETTINGS = { path: 'install/set_all_settings', method: 'POST' };
|
INSTALL_CONFIGURE = { path: 'install/configure', method: 'POST' };
|
||||||
|
|
||||||
getDefaultAddresses() {
|
getDefaultAddresses() {
|
||||||
const { path, method } = this.GET_DEFAULT_ADDRESSES;
|
const { path, method } = this.INSTALL_GET_ADDRESSES;
|
||||||
return this.makeRequest(path, method);
|
return this.makeRequest(path, method);
|
||||||
}
|
}
|
||||||
|
|
||||||
setAllSettings(config) {
|
setAllSettings(config) {
|
||||||
const { path, method } = this.SET_ALL_SETTINGS;
|
const { path, method } = this.INSTALL_CONFIGURE;
|
||||||
const parameters = {
|
const parameters = {
|
||||||
data: config,
|
data: config,
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
|
|
@ -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) {
|
switch (step) {
|
||||||
case 1:
|
case 1:
|
||||||
return (
|
return (
|
||||||
|
@ -34,48 +53,30 @@ class Controls extends Component {
|
||||||
case 2:
|
case 2:
|
||||||
case 3:
|
case 3:
|
||||||
return (
|
return (
|
||||||
<div className="btn-list">
|
<button
|
||||||
<button
|
type="submit"
|
||||||
type="button"
|
className="btn btn-success btn-standard btn-lg"
|
||||||
className="btn btn-secondary btn-standard btn-lg"
|
disabled={this.props.invalid || this.props.pristine}
|
||||||
onClick={this.props.prevStep}
|
>
|
||||||
>
|
<Trans>next</Trans>
|
||||||
<Trans>back</Trans>
|
</button>
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="submit"
|
|
||||||
className="btn btn-success btn-standard btn-lg"
|
|
||||||
disabled={this.props.invalid || this.props.pristine}
|
|
||||||
>
|
|
||||||
<Trans>next</Trans>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
case 4:
|
case 4:
|
||||||
return (
|
return (
|
||||||
<div className="btn-list">
|
<button
|
||||||
<button
|
type="button"
|
||||||
type="button"
|
className="btn btn-success btn-standard btn-lg"
|
||||||
className="btn btn-secondary btn-standard btn-lg"
|
onClick={this.props.nextStep}
|
||||||
onClick={this.props.prevStep}
|
>
|
||||||
>
|
<Trans>next</Trans>
|
||||||
<Trans>back</Trans>
|
</button>
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="btn btn-success btn-standard btn-lg"
|
|
||||||
onClick={this.props.nextStep}
|
|
||||||
>
|
|
||||||
<Trans>next</Trans>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
case 5:
|
case 5:
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="button"
|
||||||
className="btn btn-success btn-standard btn-lg"
|
className="btn btn-success btn-standard btn-lg"
|
||||||
disabled={this.props.submitting || this.props.pristine}
|
onClick={this.props.openDashboard}
|
||||||
>
|
>
|
||||||
<Trans>open_dashboard</Trans>
|
<Trans>open_dashboard</Trans>
|
||||||
</button>
|
</button>
|
||||||
|
@ -88,7 +89,10 @@ class Controls extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="setup__nav">
|
<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>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -98,9 +102,10 @@ Controls.propTypes = {
|
||||||
step: PropTypes.number.isRequired,
|
step: PropTypes.number.isRequired,
|
||||||
nextStep: PropTypes.func,
|
nextStep: PropTypes.func,
|
||||||
prevStep: PropTypes.func,
|
prevStep: PropTypes.func,
|
||||||
pristine: PropTypes.bool,
|
openDashboard: PropTypes.func,
|
||||||
submitting: PropTypes.bool,
|
submitting: PropTypes.bool,
|
||||||
invalid: PropTypes.bool,
|
invalid: PropTypes.bool,
|
||||||
|
pristine: PropTypes.bool,
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state) => {
|
const mapStateToProps = (state) => {
|
||||||
|
|
|
@ -1,19 +1,29 @@
|
||||||
import React from 'react';
|
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 { Trans, withNamespaces } from 'react-i18next';
|
||||||
|
import flow from 'lodash/flow';
|
||||||
|
|
||||||
import Tabs from '../../components/ui/Tabs';
|
import Tabs from '../../components/ui/Tabs';
|
||||||
import Icons from '../../components/ui/Icons';
|
import Icons from '../../components/ui/Icons';
|
||||||
import Controls from './Controls';
|
import Controls from './Controls';
|
||||||
|
|
||||||
const Devices = () => (
|
let Devices = props => (
|
||||||
<div className="setup__step">
|
<div className="setup__step">
|
||||||
<div className="setup__group">
|
<div className="setup__group">
|
||||||
<div className="setup__subtitle">
|
<div className="setup__subtitle">
|
||||||
<Trans>install_devices_title</Trans>
|
<Trans>install_devices_title</Trans>
|
||||||
</div>
|
</div>
|
||||||
<p className="setup__desc">
|
<div className="setup__desc">
|
||||||
<Trans>install_devices_desc</Trans>
|
<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 />
|
<Icons />
|
||||||
<Tabs>
|
<Tabs>
|
||||||
<div label="Router">
|
<div label="Router">
|
||||||
|
@ -90,4 +100,28 @@ const Devices = () => (
|
||||||
</div>
|
</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 Controls from './Controls';
|
||||||
import renderField from './renderField';
|
import renderField from './renderField';
|
||||||
import { R_IPV4 } from '../../helpers/constants';
|
|
||||||
|
|
||||||
const required = (value) => {
|
const required = (value) => {
|
||||||
if (value || value === 0) {
|
if (value || value === 0) {
|
||||||
|
@ -16,13 +15,6 @@ const required = (value) => {
|
||||||
return <Trans>form_error_required</Trans>;
|
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) => {
|
const port = (value) => {
|
||||||
if (value < 1 || value > 65535) {
|
if (value < 1 || value > 65535) {
|
||||||
return <Trans>form_error_port</Trans>;
|
return <Trans>form_error_port</Trans>;
|
||||||
|
@ -32,6 +24,29 @@ const port = (value) => {
|
||||||
|
|
||||||
const toNumber = value => value && parseInt(value, 10);
|
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) => {
|
let Settings = (props) => {
|
||||||
const {
|
const {
|
||||||
handleSubmit,
|
handleSubmit,
|
||||||
|
@ -39,7 +54,10 @@ let Settings = (props) => {
|
||||||
interfacePort,
|
interfacePort,
|
||||||
dnsIp,
|
dnsIp,
|
||||||
dnsPort,
|
dnsPort,
|
||||||
|
interfaces,
|
||||||
invalid,
|
invalid,
|
||||||
|
webWarning,
|
||||||
|
dnsWarning,
|
||||||
} = props;
|
} = props;
|
||||||
const dnsAddress = dnsPort && dnsPort !== 53 ? `${dnsIp}:${dnsPort}` : dnsIp;
|
const dnsAddress = dnsPort && dnsPort !== 53 ? `${dnsIp}:${dnsPort}` : dnsIp;
|
||||||
const interfaceAddress = interfacePort ? `http://${interfaceIp}:${interfacePort}` : `http://${interfaceIp}`;
|
const interfaceAddress = interfacePort ? `http://${interfaceIp}:${interfacePort}` : `http://${interfaceIp}`;
|
||||||
|
@ -58,12 +76,14 @@ let Settings = (props) => {
|
||||||
</label>
|
</label>
|
||||||
<Field
|
<Field
|
||||||
name="web.ip"
|
name="web.ip"
|
||||||
component={renderField}
|
component="select"
|
||||||
type="text"
|
className="form-control custom-select"
|
||||||
className="form-control"
|
>
|
||||||
placeholder="0.0.0.0"
|
<option value="0.0.0.0">
|
||||||
validate={[ipv4, required]}
|
<Trans>install_settings_all_interfaces</Trans>
|
||||||
/>
|
</option>
|
||||||
|
{renderInterfaces(interfaces)}
|
||||||
|
</Field>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-4">
|
<div className="col-4">
|
||||||
|
@ -90,6 +110,11 @@ let Settings = (props) => {
|
||||||
>
|
>
|
||||||
install_settings_interface_link
|
install_settings_interface_link
|
||||||
</Trans>
|
</Trans>
|
||||||
|
{webWarning &&
|
||||||
|
<div className="text-danger mt-2">
|
||||||
|
{webWarning}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="setup__group">
|
<div className="setup__group">
|
||||||
|
@ -104,12 +129,14 @@ let Settings = (props) => {
|
||||||
</label>
|
</label>
|
||||||
<Field
|
<Field
|
||||||
name="dns.ip"
|
name="dns.ip"
|
||||||
component={renderField}
|
component="select"
|
||||||
type="text"
|
className="form-control custom-select"
|
||||||
className="form-control"
|
>
|
||||||
placeholder="0.0.0.0"
|
<option value="0.0.0.0" defaultValue>
|
||||||
validate={[ipv4, required]}
|
<Trans>install_settings_all_interfaces</Trans>
|
||||||
/>
|
</option>
|
||||||
|
{renderInterfaces(interfaces)}
|
||||||
|
</Field>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-4">
|
<div className="col-4">
|
||||||
|
@ -129,14 +156,19 @@ let Settings = (props) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="setup__desc">
|
<div className="setup__desc">
|
||||||
<Trans
|
<Trans
|
||||||
components={[<strong key="0">ip</strong>]}
|
components={[<strong key="0">ip</strong>]}
|
||||||
values={{ ip: dnsAddress }}
|
values={{ ip: dnsAddress }}
|
||||||
>
|
>
|
||||||
install_settings_dns_desc
|
install_settings_dns_desc
|
||||||
</Trans>
|
</Trans>
|
||||||
</p>
|
{dnsWarning &&
|
||||||
|
<div className="text-danger mt-2">
|
||||||
|
{dnsWarning}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Controls invalid={invalid} />
|
<Controls invalid={invalid} />
|
||||||
</form>
|
</form>
|
||||||
|
@ -155,17 +187,13 @@ Settings.propTypes = {
|
||||||
PropTypes.string,
|
PropTypes.string,
|
||||||
PropTypes.number,
|
PropTypes.number,
|
||||||
]),
|
]),
|
||||||
|
webWarning: PropTypes.string.isRequired,
|
||||||
|
dnsWarning: PropTypes.string.isRequired,
|
||||||
|
interfaces: PropTypes.object.isRequired,
|
||||||
invalid: PropTypes.bool.isRequired,
|
invalid: PropTypes.bool.isRequired,
|
||||||
initialValues: PropTypes.object,
|
initialValues: PropTypes.object,
|
||||||
};
|
};
|
||||||
|
|
||||||
Settings.defaultProps = {
|
|
||||||
interfaceIp: '192.168.0.1',
|
|
||||||
interfacePort: 3000,
|
|
||||||
dnsIp: '192.168.0.1',
|
|
||||||
dnsPort: 53,
|
|
||||||
};
|
|
||||||
|
|
||||||
const selector = formValueSelector('install');
|
const selector = formValueSelector('install');
|
||||||
|
|
||||||
Settings = connect((state) => {
|
Settings = connect((state) => {
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.setup__desc {
|
.setup__desc {
|
||||||
|
margin-bottom: 20px;
|
||||||
font-size: 15px;
|
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 PropTypes from 'prop-types';
|
||||||
import { reduxForm } from 'redux-form';
|
import { reduxForm, formValueSelector } from 'redux-form';
|
||||||
import { Trans, withNamespaces } from 'react-i18next';
|
import { Trans, withNamespaces } from 'react-i18next';
|
||||||
import flow from 'lodash/flow';
|
import flow from 'lodash/flow';
|
||||||
|
|
||||||
import Controls from './Controls';
|
import Controls from './Controls';
|
||||||
|
|
||||||
class Submit extends Component {
|
let Submit = props => (
|
||||||
render() {
|
<div className="setup__step">
|
||||||
const {
|
<div className="setup__group">
|
||||||
handleSubmit,
|
<h1 className="setup__title">
|
||||||
pristine,
|
<Trans>install_submit_title</Trans>
|
||||||
submitting,
|
</h1>
|
||||||
} = this.props;
|
<p className="setup__desc">
|
||||||
|
<Trans>install_submit_desc</Trans>
|
||||||
return (
|
</p>
|
||||||
<div className="setup__step">
|
</div>
|
||||||
<div className="setup__group">
|
<form onSubmit={props.handleSubmit}>
|
||||||
<h1 className="setup__title">
|
<Controls
|
||||||
<Trans>install_submit_title</Trans>
|
submitting={props.submitting}
|
||||||
</h1>
|
pristine={props.pristine}
|
||||||
<p className="setup__desc">
|
address={`http://${props.interfaceIp}`}
|
||||||
<Trans>install_submit_desc</Trans>
|
/>
|
||||||
</p>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<form onSubmit={handleSubmit}>
|
);
|
||||||
<Controls submitting={submitting} pristine={pristine} />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Submit.propTypes = {
|
Submit.propTypes = {
|
||||||
|
interfaceIp: PropTypes.string.isRequired,
|
||||||
|
interfacePort: PropTypes.number.isRequired,
|
||||||
handleSubmit: PropTypes.func.isRequired,
|
handleSubmit: PropTypes.func.isRequired,
|
||||||
pristine: PropTypes.bool.isRequired,
|
pristine: PropTypes.bool.isRequired,
|
||||||
submitting: 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([
|
export default flow([
|
||||||
withNamespaces(),
|
withNamespaces(),
|
||||||
reduxForm({
|
reduxForm({
|
||||||
|
|
|
@ -29,6 +29,10 @@ class Setup extends Component {
|
||||||
this.props.setAllSettings(values);
|
this.props.setAllSettings(values);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
openDashboard = () => {
|
||||||
|
console.log('Open dashboard');
|
||||||
|
}
|
||||||
|
|
||||||
nextStep = () => {
|
nextStep = () => {
|
||||||
if (this.props.install.step < INSTALL_TOTAL_STEPS) {
|
if (this.props.install.step < INSTALL_TOTAL_STEPS) {
|
||||||
this.props.nextStep();
|
this.props.nextStep();
|
||||||
|
@ -41,7 +45,7 @@ class Setup extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPage(step, config) {
|
renderPage(step, config, interfaces) {
|
||||||
switch (step) {
|
switch (step) {
|
||||||
case 1:
|
case 1:
|
||||||
return <Greeting />;
|
return <Greeting />;
|
||||||
|
@ -49,17 +53,20 @@ class Setup extends Component {
|
||||||
return (
|
return (
|
||||||
<Settings
|
<Settings
|
||||||
initialValues={config}
|
initialValues={config}
|
||||||
|
interfaces={interfaces}
|
||||||
|
webWarning={config.web.warning}
|
||||||
|
dnsWarning={config.dns.warning}
|
||||||
onSubmit={this.nextStep}
|
onSubmit={this.nextStep}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
case 3:
|
case 3:
|
||||||
return (
|
return (
|
||||||
<Auth onSubmit={this.nextStep} />
|
<Auth onSubmit={this.handleFormSubmit} />
|
||||||
);
|
);
|
||||||
case 4:
|
case 4:
|
||||||
return <Devices />;
|
return <Devices />;
|
||||||
case 5:
|
case 5:
|
||||||
return <Submit onSubmit={this.handleFormSubmit} />;
|
return <Submit onSubmit={this.openDashboard} />;
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -71,6 +78,7 @@ class Setup extends Component {
|
||||||
step,
|
step,
|
||||||
web,
|
web,
|
||||||
dns,
|
dns,
|
||||||
|
interfaces,
|
||||||
} = this.props.install;
|
} = this.props.install;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -81,7 +89,7 @@ class Setup extends Component {
|
||||||
<div className="setup">
|
<div className="setup">
|
||||||
<div className="setup__container">
|
<div className="setup__container">
|
||||||
<img src={logo} className="setup__logo" alt="logo" />
|
<img src={logo} className="setup__logo" alt="logo" />
|
||||||
{this.renderPage(step, { web, dns })}
|
{this.renderPage(step, { web, dns }, interfaces)}
|
||||||
<Progress step={step} />
|
<Progress step={step} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,10 @@ const install = handleActions({
|
||||||
[actions.getDefaultAddressesRequest]: state => ({ ...state, processingDefault: true }),
|
[actions.getDefaultAddressesRequest]: state => ({ ...state, processingDefault: true }),
|
||||||
[actions.getDefaultAddressesFailure]: state => ({ ...state, processingDefault: false }),
|
[actions.getDefaultAddressesFailure]: state => ({ ...state, processingDefault: false }),
|
||||||
[actions.getDefaultAddressesSuccess]: (state, { payload }) => {
|
[actions.getDefaultAddressesSuccess]: (state, { payload }) => {
|
||||||
const newState = { ...state, ...payload, processingDefault: false };
|
const values = payload;
|
||||||
|
values.web.ip = state.web.ip;
|
||||||
|
values.dns.ip = state.dns.ip;
|
||||||
|
const newState = { ...state, ...values, processingDefault: false };
|
||||||
return newState;
|
return newState;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -23,6 +26,17 @@ const install = handleActions({
|
||||||
}, {
|
}, {
|
||||||
step: INSTALL_FIRST_STEP,
|
step: INSTALL_FIRST_STEP,
|
||||||
processingDefault: true,
|
processingDefault: true,
|
||||||
|
web: {
|
||||||
|
ip: '0.0.0.0',
|
||||||
|
port: 80,
|
||||||
|
warning: '',
|
||||||
|
},
|
||||||
|
dns: {
|
||||||
|
ip: '0.0.0.0',
|
||||||
|
port: 53,
|
||||||
|
warning: '',
|
||||||
|
},
|
||||||
|
interfaces: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const toasts = handleActions({
|
const toasts = handleActions({
|
||||||
|
|
Loading…
Reference in New Issue