mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-11-26 23:28:08 +03:00
+ client: handle static IP while doing initial setup
This commit is contained in:
parent
5c385521c4
commit
cc2d953c9d
7 changed files with 119 additions and 31 deletions
41
client/package-lock.json
generated
vendored
41
client/package-lock.json
generated
vendored
|
@ -5458,7 +5458,8 @@
|
|||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
|
@ -5479,12 +5480,14 @@
|
|||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
|
@ -5499,17 +5502,20 @@
|
|||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
|
@ -5626,7 +5632,8 @@
|
|||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
|
@ -5638,6 +5645,7 @@
|
|||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
|
@ -5652,6 +5660,7 @@
|
|||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
|
@ -5659,12 +5668,14 @@
|
|||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
|
@ -5683,6 +5694,7 @@
|
|||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
|
@ -5763,7 +5775,8 @@
|
|||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
|
@ -5775,6 +5788,7 @@
|
|||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
|
@ -5860,7 +5874,8 @@
|
|||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
|
@ -5896,6 +5911,7 @@
|
|||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
|
@ -5915,6 +5931,7 @@
|
|||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
|
@ -5958,12 +5975,14 @@
|
|||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -462,5 +462,8 @@
|
|||
"client_confirm_block": "Are you sure you want to block the client \"{{ip}}\"?",
|
||||
"client_confirm_unblock": "Are you sure you want to unblock the client \"{{ip}}\"?",
|
||||
"client_blocked": "Client \"{{ip}}\" successfully blocked",
|
||||
"client_unblocked": "Client \"{{ip}}\" successfully unblocked"
|
||||
"client_unblocked": "Client \"{{ip}}\" successfully unblocked",
|
||||
"set_static_ip": "Set static IP address",
|
||||
"install_static_error": "We failed to determine if this network interface is configured using static IP address. Please set a static IP address manually.",
|
||||
"install_static_configure": "We have detected that a dynamic IP address is used — {{ip}}. We suggest that you set this IP as static."
|
||||
}
|
||||
|
|
|
@ -240,6 +240,13 @@ export const port = (value) => {
|
|||
return undefined;
|
||||
};
|
||||
|
||||
export const validInstallPort = (value) => {
|
||||
if (value < 1 || value > 65535) {
|
||||
return <Trans>form_error_port</Trans>;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const portTLS = (value) => {
|
||||
if (value === 0) {
|
||||
return undefined;
|
||||
|
|
|
@ -7,26 +7,18 @@ import flow from 'lodash/flow';
|
|||
|
||||
import Controls from './Controls';
|
||||
import AddressList from './AddressList';
|
||||
import Accordion from '../../components/ui/Accordion';
|
||||
|
||||
import { getInterfaceIp } from '../../helpers/helpers';
|
||||
import { ALL_INTERFACES_IP } from '../../helpers/constants';
|
||||
import { renderInputField } from '../../helpers/form';
|
||||
import { renderInputField, required, validInstallPort, toNumber } from '../../helpers/form';
|
||||
|
||||
const required = (value) => {
|
||||
if (value || value === 0) {
|
||||
return false;
|
||||
}
|
||||
return <Trans>form_error_required</Trans>;
|
||||
const STATIC_STATUS = {
|
||||
ENABLED: 'yes',
|
||||
DISABLED: 'no',
|
||||
ERROR: 'error',
|
||||
};
|
||||
|
||||
const port = (value) => {
|
||||
if (value < 1 || value > 65535) {
|
||||
return <Trans>form_error_port</Trans>;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const toNumber = value => value && parseInt(value, 10);
|
||||
|
||||
const renderInterfaces = (interfaces => (
|
||||
Object.keys(interfaces).map((item) => {
|
||||
const option = interfaces[item];
|
||||
|
@ -79,11 +71,54 @@ class Settings extends Component {
|
|||
});
|
||||
}
|
||||
|
||||
getStaticIpMessage = (staticIp, handleStaticIp) => {
|
||||
const { static: status, ip, error } = staticIp;
|
||||
|
||||
if (!status || status === STATIC_STATUS.ENABLED) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="col-12">
|
||||
<Fragment>
|
||||
<div className="text-danger">
|
||||
{status === STATIC_STATUS.DISABLED && (
|
||||
<Fragment>
|
||||
<Trans values={{ ip }}>
|
||||
install_static_configure
|
||||
</Trans>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-secondary btn-sm ml-2"
|
||||
onClick={() => handleStaticIp()}
|
||||
>
|
||||
<Trans>set_static_ip</Trans>
|
||||
</button>
|
||||
</Fragment>
|
||||
)}
|
||||
{status === STATIC_STATUS.ERROR && (
|
||||
<Fragment>
|
||||
<Trans>install_static_error</Trans>
|
||||
<div className="mt-2 mb-2">
|
||||
<Accordion label={this.props.t('error_details')}>
|
||||
<span>{error}</span>
|
||||
</Accordion>
|
||||
</div>
|
||||
</Fragment>
|
||||
)}
|
||||
<hr className="divider divider--small" />
|
||||
</div>
|
||||
</Fragment>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
handleSubmit,
|
||||
handleChange,
|
||||
handleAutofix,
|
||||
handleStaticIp,
|
||||
webIp,
|
||||
webPort,
|
||||
dnsIp,
|
||||
|
@ -100,6 +135,7 @@ class Settings extends Component {
|
|||
status: dnsStatus,
|
||||
can_autofix: isDnsFixAvailable,
|
||||
} = config.dns;
|
||||
const { staticIp } = config;
|
||||
|
||||
return (
|
||||
<form className="setup__step" onSubmit={handleSubmit}>
|
||||
|
@ -137,7 +173,7 @@ class Settings extends Component {
|
|||
type="number"
|
||||
className="form-control"
|
||||
placeholder="80"
|
||||
validate={[port, required]}
|
||||
validate={[validInstallPort, required]}
|
||||
normalize={toNumber}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
|
@ -205,12 +241,13 @@ class Settings extends Component {
|
|||
type="number"
|
||||
className="form-control"
|
||||
placeholder="80"
|
||||
validate={[port, required]}
|
||||
validate={[validInstallPort, required]}
|
||||
normalize={toNumber}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{this.getStaticIpMessage(staticIp, handleStaticIp)}
|
||||
<div className="col-12">
|
||||
{dnsStatus &&
|
||||
<Fragment>
|
||||
|
@ -237,6 +274,7 @@ class Settings extends Component {
|
|||
<Trans>autofix_warning_result</Trans>
|
||||
</p>
|
||||
</div>
|
||||
<hr className="divider--small" />
|
||||
</Fragment>
|
||||
}
|
||||
</div>
|
||||
|
@ -278,6 +316,8 @@ Settings.propTypes = {
|
|||
interfaces: PropTypes.object.isRequired,
|
||||
invalid: PropTypes.bool.isRequired,
|
||||
initialValues: PropTypes.object,
|
||||
t: PropTypes.func.isRequired,
|
||||
handleStaticIp: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const selector = formValueSelector('install');
|
||||
|
|
|
@ -119,3 +119,8 @@
|
|||
.setup__error {
|
||||
margin: -5px 0 5px;
|
||||
}
|
||||
|
||||
.divider--small {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,12 @@ class Setup extends Component {
|
|||
}
|
||||
};
|
||||
|
||||
handleStaticIp = () => {
|
||||
this.props.checkConfig({
|
||||
set_static_ip: true,
|
||||
});
|
||||
};
|
||||
|
||||
openDashboard = (ip, port) => {
|
||||
let address = getWebAddress(ip, port);
|
||||
|
||||
|
@ -96,6 +102,7 @@ class Setup extends Component {
|
|||
onChange={this.handleFormChange}
|
||||
validateForm={this.handleFormChange}
|
||||
handleAutofix={this.handleAutofix}
|
||||
handleStaticIp={this.handleStaticIp}
|
||||
/>
|
||||
);
|
||||
case 3:
|
||||
|
@ -117,6 +124,7 @@ class Setup extends Component {
|
|||
step,
|
||||
web,
|
||||
dns,
|
||||
staticIp,
|
||||
interfaces,
|
||||
} = this.props.install;
|
||||
|
||||
|
@ -128,7 +136,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 }, interfaces)}
|
||||
{this.renderPage(step, { web, dns, staticIp }, interfaces)}
|
||||
<Progress step={step} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -32,9 +32,10 @@ const install = handleActions({
|
|||
[actions.checkConfigSuccess]: (state, { payload }) => {
|
||||
const web = { ...state.web, ...payload.web };
|
||||
const dns = { ...state.dns, ...payload.dns };
|
||||
const staticIp = { ...state.staticIp, ...payload.static_ip };
|
||||
|
||||
const newState = {
|
||||
...state, web, dns, processingCheck: false,
|
||||
...state, web, dns, staticIp, processingCheck: false,
|
||||
};
|
||||
return newState;
|
||||
},
|
||||
|
@ -55,6 +56,11 @@ const install = handleActions({
|
|||
status: '',
|
||||
can_autofix: false,
|
||||
},
|
||||
staticIp: {
|
||||
static: '',
|
||||
ip: '',
|
||||
error: '',
|
||||
},
|
||||
interfaces: {},
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue