Show list of addresses

This commit is contained in:
Ildar Kamalov 2019-02-04 17:13:59 +03:00 committed by Eugene Bujak
parent f379d34813
commit 31b855f9ab
9 changed files with 166 additions and 72 deletions

View File

@ -164,10 +164,10 @@
"install_settings_title": "Admin Web Interface",
"install_settings_listen": "Listen interface",
"install_settings_port": "Port",
"install_settings_interface_link": "Your AdGuard Home admin web interface will be available on the following addresses: <0>{{link}}</0>",
"install_settings_interface_link": "Your AdGuard Home admin web interface will be available on the following addresses:",
"form_error_port": "Enter valid port value",
"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 on the following addresses:",
"install_settings_all_interfaces": "All interfaces",
"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.",

View File

@ -70,3 +70,5 @@ export const SETTINGS_NAMES = {
parental: 'parental',
safesearch: 'safesearch',
};
export const STANDARD_DNS_PORT = 53;

View File

@ -4,7 +4,7 @@ import subHours from 'date-fns/sub_hours';
import addHours from 'date-fns/add_hours';
import round from 'lodash/round';
import { STATS_NAMES } from './constants';
import { STATS_NAMES, STANDARD_DNS_PORT } from './constants';
export const formatTime = (time) => {
const parsedTime = dateParse(time);
@ -85,3 +85,46 @@ export const getPercent = (amount, number) => {
};
export const captitalizeWords = text => text.split(/[ -_]/g).map(str => str.charAt(0).toUpperCase() + str.substr(1)).join(' ');
export const getInterfaceIp = (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 interfaceIP;
};
export const getIpList = (interfaces) => {
let list = [];
Object.keys(interfaces).forEach((item) => {
list = [...list, ...interfaces[item].ip_addresses];
});
return list.sort();
};
export const getAddress = (ip, port = '', isDns = false) => {
if (!port) {
return isDns ? ip : `http://${ip}`;
}
if (isDns) {
if (ip.includes(':') && port !== STANDARD_DNS_PORT) {
return `[${ip}]:${port}`;
} else if (port !== STANDARD_DNS_PORT) {
return `${ip}:${port}`;
}
return ip;
}
return ip.includes(':') ? `http://[${ip}]:${port}` : `http://${ip}:${port}`;
};

View File

@ -0,0 +1,60 @@
import React from 'react';
import PropTypes from 'prop-types';
import { getIpList, getAddress } from '../../helpers/helpers';
const AddressList = (props) => {
let webAddress = getAddress(props.address, props.port);
let dnsAddress = getAddress(props.address, props.port, true);
if (props.address === '0.0.0.0') {
return getIpList(props.interfaces).map((ip) => {
webAddress = getAddress(ip, props.port);
dnsAddress = getAddress(ip, props.port, true);
if (props.isDns) {
return (
<li key={ip}>
<strong>
{dnsAddress}
</strong>
</li>
);
}
return (
<li key={ip}>
<a href={webAddress}>
{webAddress}
</a>
</li>
);
});
}
if (props.isDns) {
return (
<strong>
{dnsAddress}
</strong>
);
}
return (
<a href={webAddress}>
{webAddress}
</a>
);
};
AddressList.propTypes = {
interfaces: PropTypes.object.isRequired,
address: PropTypes.string.isRequired,
port: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
isDns: PropTypes.bool,
};
export default AddressList;

View File

@ -4,26 +4,12 @@ import PropTypes from 'prop-types';
import { Trans } from 'react-i18next';
import * as actionCreators from '../../actions/install';
import { INSTALL_FIRST_STEP, INSTALL_TOTAL_STEPS } from '../../helpers/constants';
class Controls extends Component {
nextStep = () => {
if (this.props.step < INSTALL_TOTAL_STEPS) {
this.props.nextStep();
}
}
prevStep = () => {
if (this.props.step > INSTALL_FIRST_STEP) {
this.props.prevStep();
}
}
renderPrevButton(step) {
switch (step) {
case 2:
case 3:
case 4:
return (
<button
type="button"
@ -76,7 +62,7 @@ class Controls extends Component {
<button
type="button"
className="btn btn-success btn-standard btn-lg"
onClick={this.props.openDashboard}
onClick={() => this.props.openDashboard(this.props.address)}
>
<Trans>open_dashboard</Trans>
</button>
@ -106,6 +92,7 @@ Controls.propTypes = {
submitting: PropTypes.bool,
invalid: PropTypes.bool,
pristine: PropTypes.bool,
address: PropTypes.string,
};
const mapStateToProps = (state) => {

View File

@ -8,6 +8,7 @@ import flow from 'lodash/flow';
import Tabs from '../../components/ui/Tabs';
import Icons from '../../components/ui/Icons';
import Controls from './Controls';
import AddressList from './AddressList';
let Devices = props => (
<div className="setup__step">
@ -20,8 +21,13 @@ let Devices = props => (
<div className="mt-1">
<Trans>install_devices_address</Trans>:
</div>
<div>
<strong>{`${props.dnsIp}:${props.dnsPort}`}</strong>
<div className="mt-1">
<AddressList
interfaces={props.interfaces}
address={props.dnsIp}
port={props.dnsPort}
isDns={true}
/>
</div>
</div>
<Icons />
@ -101,6 +107,7 @@ let Devices = props => (
);
Devices.propTypes = {
interfaces: PropTypes.object.isRequired,
dnsIp: PropTypes.string.isRequired,
dnsPort: PropTypes.number.isRequired,
};

View File

@ -6,7 +6,9 @@ import { Trans, withNamespaces } from 'react-i18next';
import flow from 'lodash/flow';
import Controls from './Controls';
import AddressList from './AddressList';
import renderField from './renderField';
import { getInterfaceIp } from '../../helpers/helpers';
const required = (value) => {
if (value || value === 0) {
@ -28,20 +30,11 @@ 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;
}
});
}
const ip = getInterfaceIp(option);
return (
<option value={interfaceIP} key={name}>
{name} - {interfaceIP}
<option value={ip} key={name}>
{name} - {ip}
</option>
);
})
@ -50,8 +43,8 @@ const renderInterfaces = (interfaces => (
let Settings = (props) => {
const {
handleSubmit,
interfaceIp,
interfacePort,
webIp,
webPort,
dnsIp,
dnsPort,
interfaces,
@ -59,8 +52,6 @@ let Settings = (props) => {
webWarning,
dnsWarning,
} = props;
const dnsAddress = dnsPort && dnsPort !== 53 ? `${dnsIp}:${dnsPort}` : dnsIp;
const interfaceAddress = interfacePort ? `http://${interfaceIp}:${interfacePort}` : `http://${interfaceIp}`;
return (
<form className="setup__step" onSubmit={handleSubmit}>
@ -104,12 +95,14 @@ let Settings = (props) => {
</div>
</div>
<div className="setup__desc">
<Trans
components={[<a href={`http://${interfaceIp}`} key="0">link</a>]}
values={{ link: interfaceAddress }}
>
install_settings_interface_link
</Trans>
<Trans>install_settings_interface_link</Trans>
<div className="mt-1">
<AddressList
interfaces={interfaces}
address={webIp}
port={webPort}
/>
</div>
{webWarning &&
<div className="text-danger mt-2">
{webWarning}
@ -132,7 +125,7 @@ let Settings = (props) => {
component="select"
className="form-control custom-select"
>
<option value="0.0.0.0" defaultValue>
<option value="0.0.0.0">
<Trans>install_settings_all_interfaces</Trans>
</option>
{renderInterfaces(interfaces)}
@ -157,12 +150,15 @@ let Settings = (props) => {
</div>
</div>
<div className="setup__desc">
<Trans
components={[<strong key="0">ip</strong>]}
values={{ ip: dnsAddress }}
>
install_settings_dns_desc
</Trans>
<Trans>install_settings_dns_desc</Trans>
<div className="mt-1">
<AddressList
interfaces={interfaces}
address={dnsIp}
port={dnsPort}
isDns={true}
/>
</div>
{dnsWarning &&
<div className="text-danger mt-2">
{dnsWarning}
@ -177,9 +173,9 @@ let Settings = (props) => {
Settings.propTypes = {
handleSubmit: PropTypes.func.isRequired,
interfaceIp: PropTypes.string.isRequired,
webIp: PropTypes.string.isRequired,
dnsIp: PropTypes.string.isRequired,
interfacePort: PropTypes.oneOfType([
webPort: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
@ -197,14 +193,14 @@ Settings.propTypes = {
const selector = formValueSelector('install');
Settings = connect((state) => {
const interfaceIp = selector(state, 'web.ip');
const interfacePort = selector(state, 'web.port');
const webIp = selector(state, 'web.ip');
const webPort = selector(state, 'web.port');
const dnsIp = selector(state, 'dns.ip');
const dnsPort = selector(state, 'dns.port');
return {
interfaceIp,
interfacePort,
webIp,
webPort,
dnsIp,
dnsPort,
};

View File

@ -6,6 +6,7 @@ import { Trans, withNamespaces } from 'react-i18next';
import flow from 'lodash/flow';
import Controls from './Controls';
import { getAddress } from '../../helpers/helpers';
let Submit = props => (
<div className="setup__step">
@ -17,33 +18,31 @@ let Submit = props => (
<Trans>install_submit_desc</Trans>
</p>
</div>
<form onSubmit={props.handleSubmit}>
<Controls
submitting={props.submitting}
pristine={props.pristine}
address={`http://${props.interfaceIp}`}
/>
</form>
<Controls
openDashboard={props.openDashboard}
address={getAddress(props.webIp, props.webPort)}
/>
</div>
);
Submit.propTypes = {
interfaceIp: PropTypes.string.isRequired,
interfacePort: PropTypes.number.isRequired,
webIp: PropTypes.string.isRequired,
webPort: PropTypes.number.isRequired,
handleSubmit: PropTypes.func.isRequired,
pristine: PropTypes.bool.isRequired,
submitting: PropTypes.bool.isRequired,
openDashboard: PropTypes.func.isRequired,
};
const selector = formValueSelector('install');
Submit = connect((state) => {
const interfaceIp = selector(state, 'web.ip');
const interfacePort = selector(state, 'web.port');
const webIp = selector(state, 'web.ip');
const webPort = selector(state, 'web.port');
return {
interfaceIp,
interfacePort,
webIp,
webPort,
};
})(Submit);

View File

@ -29,8 +29,8 @@ class Setup extends Component {
this.props.setAllSettings(values);
};
openDashboard = () => {
console.log('Open dashboard');
openDashboard = (address) => {
window.location.replace(address);
}
nextStep = () => {
@ -64,9 +64,9 @@ class Setup extends Component {
<Auth onSubmit={this.handleFormSubmit} />
);
case 4:
return <Devices />;
return <Devices interfaces={interfaces} />;
case 5:
return <Submit onSubmit={this.openDashboard} />;
return <Submit openDashboard={this.openDashboard} />;
default:
return false;
}