Merge: - client: fix upstream DNS servers form

* commit '59a635f3f23bfcca583960f8ebb910d35f13e34d':
  + client: add isVersionGreater helper
  - client: fix upstream DNS servers form
This commit is contained in:
Ildar Kamalov 2019-09-17 18:27:49 +03:00
commit 74381b0cad
9 changed files with 368 additions and 300 deletions

View File

@ -2,8 +2,7 @@ import { createAction } from 'redux-actions';
import { t } from 'i18next';
import axios from 'axios';
import versionCompare from '../helpers/versionCompare';
import { normalizeTextarea, sortClients } from '../helpers/helpers';
import { normalizeTextarea, sortClients, isVersionGreater } from '../helpers/helpers';
import { SETTINGS_NAMES, CHECK_TIMEOUT } from '../helpers/constants';
import { getTlsStatus } from './encryption';
import apiClient from '../api/Api';
@ -125,7 +124,7 @@ export const getVersion = (recheck = false) => async (dispatch, getState) => {
const { dnsVersion } = getState().dashboard;
const currentVersion = dnsVersion === 'undefined' ? 0 : dnsVersion;
if (data && versionCompare(currentVersion, data.new_version) === -1) {
if (data && isVersionGreater(currentVersion, data.new_version)) {
dispatch(addSuccessToast('updates_checked'));
} else {
dispatch(addSuccessToast('updates_version_equal'));
@ -227,7 +226,22 @@ export const getDnsStatus = () => async (dispatch) => {
dispatch(getTlsStatus());
} catch (error) {
dispatch(addErrorToast({ error }));
dispatch(initSettingsFailure());
dispatch(dnsStatusFailure());
}
};
export const getDnsSettingsRequest = createAction('GET_DNS_SETTINGS_REQUEST');
export const getDnsSettingsFailure = createAction('GET_DNS_SETTINGS_FAILURE');
export const getDnsSettingsSuccess = createAction('GET_DNS_SETTINGS_SUCCESS');
export const getDnsSettings = () => async (dispatch) => {
dispatch(getDnsSettingsRequest());
try {
const dnsStatus = await apiClient.getGlobalStatus();
dispatch(getDnsSettingsSuccess(dnsStatus));
} catch (error) {
dispatch(addErrorToast({ error }));
dispatch(getDnsSettingsFailure());
}
};
@ -279,7 +293,7 @@ export const setUpstream = config => async (dispatch) => {
await apiClient.setUpstream(values);
dispatch(addSuccessToast('updated_upstream_dns_toast'));
dispatch(setUpstreamSuccess());
dispatch(setUpstreamSuccess(config));
} catch (error) {
dispatch(addErrorToast({ error }));
dispatch(setUpstreamFailure());

View File

@ -5,7 +5,9 @@ import { Trans, withNamespaces } from 'react-i18next';
import flow from 'lodash/flow';
const Form = (props) => {
const { handleSubmit, submitting, invalid } = props;
const {
handleSubmit, submitting, invalid, processingSet,
} = props;
return (
<form onSubmit={handleSubmit}>
@ -22,6 +24,7 @@ const Form = (props) => {
component="textarea"
type="text"
className="form-control form-control--textarea"
disabled={processingSet}
/>
</div>
<div className="form__group mb-5">
@ -37,6 +40,7 @@ const Form = (props) => {
component="textarea"
type="text"
className="form-control form-control--textarea"
disabled={processingSet}
/>
</div>
<div className="form__group mb-5">
@ -52,6 +56,7 @@ const Form = (props) => {
component="textarea"
type="text"
className="form-control form-control--textarea"
disabled={processingSet}
/>
</div>
<div className="card-actions">
@ -59,7 +64,7 @@ const Form = (props) => {
<button
type="submit"
className="btn btn-success btn-standard"
disabled={submitting || invalid}
disabled={submitting || invalid || processingSet}
>
<Trans>save_config</Trans>
</button>
@ -70,11 +75,12 @@ const Form = (props) => {
};
Form.propTypes = {
handleSubmit: PropTypes.func,
submitting: PropTypes.bool,
invalid: PropTypes.bool,
initialValues: PropTypes.object,
t: PropTypes.func,
handleSubmit: PropTypes.func.isRequired,
submitting: PropTypes.bool.isRequired,
invalid: PropTypes.bool.isRequired,
initialValues: PropTypes.object.isRequired,
processingSet: PropTypes.bool.isRequired,
t: PropTypes.func.isRequired,
};
export default flow([withNamespaces(), reduxForm({ form: 'accessForm' })])(Form);

View File

@ -13,11 +13,7 @@ class Access extends Component {
render() {
const { t, access } = this.props;
const {
processing,
processingSet,
...values
} = access;
const { processing, processingSet, ...values } = access;
return (
<Card
@ -28,6 +24,7 @@ class Access extends Component {
<Form
initialValues={values}
onSubmit={this.handleFormSubmit}
processingSet={processingSet}
/>
</Card>
);

View File

@ -43,6 +43,7 @@ let Form = (props) => {
type="text"
className="form-control form-control--textarea"
placeholder={t('upstream_dns')}
disabled={processingSetUpstream || processingTestUpstream}
/>
</div>
</div>
@ -53,6 +54,7 @@ let Form = (props) => {
type="checkbox"
component={renderSelectField}
placeholder={t('upstream_parallel')}
disabled={processingSetUpstream}
/>
</div>
</div>
@ -62,7 +64,10 @@ let Form = (props) => {
</div>
<div className="col-12">
<div className="form__group">
<label className="form__label form__label--with-desc" htmlFor="bootstrap_dns">
<label
className="form__label form__label--with-desc"
htmlFor="bootstrap_dns"
>
<Trans>bootstrap_dns</Trans>
</label>
<div className="form__desc form__desc--top">
@ -73,8 +78,9 @@ let Form = (props) => {
name="bootstrap_dns"
component="textarea"
type="text"
className="form-control"
className="form-control form-control--textarea form-control--textarea-small"
placeholder={t('bootstrap_dns')}
disabled={processingSetUpstream}
/>
</div>
</div>

View File

@ -10,6 +10,7 @@ import Loading from '../../ui/Loading';
class Dns extends Component {
componentDidMount() {
this.props.getDnsSettings();
this.props.getAccessList();
this.props.getRewritesList();
}
@ -30,11 +31,16 @@ class Dns extends Component {
toggleRewritesModal,
} = this.props;
const isDataLoading =
dashboard.processingDnsSettings || access.processing || rewrites.processing;
const isDataReady =
!dashboard.processingDnsSettings && !access.processing && !rewrites.processing;
return (
<Fragment>
<PageTitle title={t('dns_settings')} />
{(dashboard.processing || access.processing) && <Loading />}
{!dashboard.processing && !access.processing && (
{isDataLoading && <Loading />}
{isDataReady && (
<Fragment>
<Upstream
upstreamDns={dashboard.upstreamDns}
@ -73,6 +79,7 @@ Dns.propTypes = {
addRewrite: PropTypes.func.isRequired,
deleteRewrite: PropTypes.func.isRequired,
toggleRewritesModal: PropTypes.func.isRequired,
getDnsSettings: PropTypes.func.isRequired,
t: PropTypes.func.isRequired,
};

View File

@ -38,6 +38,11 @@
.form-control--textarea {
min-height: 110px;
transition: 0.3s ease-in-out background-color;
}
.form-control--textarea-small {
min-height: 90px;
}
.form-control--textarea-large {

View File

@ -1,5 +1,5 @@
import { connect } from 'react-redux';
import { handleUpstreamChange, setUpstream, testUpstream } from '../actions';
import { handleUpstreamChange, setUpstream, testUpstream, getDnsSettings } from '../actions';
import { getAccessList, setAccessList } from '../actions/access';
import {
getRewritesList,
@ -32,6 +32,7 @@ const mapDispatchToProps = {
addRewrite,
deleteRewrite,
toggleRewritesModal,
getDnsSettings,
};
export default connect(

View File

@ -7,6 +7,7 @@ import subDays from 'date-fns/sub_days';
import round from 'lodash/round';
import axios from 'axios';
import i18n from 'i18next';
import versionCompare from './versionCompare';
import {
STANDARD_DNS_PORT,
@ -279,3 +280,7 @@ export const secondsToMilliseconds = (seconds) => {
};
export const normalizeRulesTextarea = text => text && text.replace(/^\n/g, '').replace(/\n\s*\n/g, '\n');
export const isVersionGreater = (currentVersion, previousVersion) => (
versionCompare(currentVersion, previousVersion) === -1
);

View File

@ -2,7 +2,7 @@ import { combineReducers } from 'redux';
import { handleActions } from 'redux-actions';
import { loadingBarReducer } from 'react-redux-loading-bar';
import { reducer as formReducer } from 'redux-form';
import versionCompare from '../helpers/versionCompare';
import { isVersionGreater } from '../helpers/helpers';
import * as actions from '../actions';
import toasts from './toasts';
@ -15,299 +15,326 @@ import stats from './stats';
import queryLogs from './queryLogs';
import filtering from './filtering';
const settings = handleActions({
[actions.initSettingsRequest]: state => ({ ...state, processing: true }),
[actions.initSettingsFailure]: state => ({ ...state, processing: false }),
[actions.initSettingsSuccess]: (state, { payload }) => {
const { settingsList } = payload;
const newState = { ...state, settingsList, processing: false };
return newState;
},
[actions.toggleSettingStatus]: (state, { payload }) => {
const { settingsList } = state;
const { settingKey } = payload;
const settings = handleActions(
{
[actions.initSettingsRequest]: state => ({ ...state, processing: true }),
[actions.initSettingsFailure]: state => ({ ...state, processing: false }),
[actions.initSettingsSuccess]: (state, { payload }) => {
const { settingsList } = payload;
const newState = { ...state, settingsList, processing: false };
return newState;
},
[actions.toggleSettingStatus]: (state, { payload }) => {
const { settingsList } = state;
const { settingKey } = payload;
const setting = settingsList[settingKey];
const setting = settingsList[settingKey];
const newSetting = { ...setting, enabled: !setting.enabled };
const newSettingsList = { ...settingsList, [settingKey]: newSetting };
return { ...state, settingsList: newSettingsList };
},
[actions.setUpstreamRequest]: state => ({ ...state, processingUpstream: true }),
[actions.setUpstreamFailure]: state => ({ ...state, processingUpstream: false }),
[actions.setUpstreamSuccess]: state => ({ ...state, processingUpstream: false }),
[actions.testUpstreamRequest]: state => ({ ...state, processingTestUpstream: true }),
[actions.testUpstreamFailure]: state => ({ ...state, processingTestUpstream: false }),
[actions.testUpstreamSuccess]: state => ({ ...state, processingTestUpstream: false }),
}, {
processing: true,
processingTestUpstream: false,
processingSetUpstream: false,
processingDhcpStatus: false,
settingsList: {},
});
const dashboard = handleActions({
[actions.dnsStatusRequest]: state => ({ ...state, processing: true }),
[actions.dnsStatusFailure]: state => ({ ...state, processing: false }),
[actions.dnsStatusSuccess]: (state, { payload }) => {
const {
version,
running,
dns_port: dnsPort,
dns_addresses: dnsAddresses,
upstream_dns: upstreamDns,
bootstrap_dns: bootstrapDns,
all_servers: allServers,
protection_enabled: protectionEnabled,
language,
http_port: httpPort,
} = payload;
const newState = {
const newSetting = { ...setting, enabled: !setting.enabled };
const newSettingsList = { ...settingsList, [settingKey]: newSetting };
return { ...state, settingsList: newSettingsList };
},
[actions.setUpstreamRequest]: state => ({ ...state, processingSetUpstream: true }),
[actions.setUpstreamFailure]: state => ({ ...state, processingSetUpstream: false }),
[actions.setUpstreamSuccess]: (state, { payload }) => ({
...state,
isCoreRunning: running,
processing: false,
dnsVersion: version,
dnsPort,
dnsAddresses,
upstreamDns: upstreamDns.join('\n'),
bootstrapDns: bootstrapDns.join('\n'),
allServers,
protectionEnabled,
language,
httpPort,
};
return newState;
...payload,
processingSetUpstream: false,
}),
[actions.testUpstreamRequest]: state => ({ ...state, processingTestUpstream: true }),
[actions.testUpstreamFailure]: state => ({ ...state, processingTestUpstream: false }),
[actions.testUpstreamSuccess]: state => ({ ...state, processingTestUpstream: false }),
},
[actions.enableDnsRequest]: state => ({ ...state, processing: true }),
[actions.enableDnsFailure]: state => ({ ...state, processing: false }),
[actions.enableDnsSuccess]: (state) => {
const newState = { ...state, isCoreRunning: !state.isCoreRunning, processing: false };
return newState;
{
processing: true,
processingTestUpstream: false,
processingSetUpstream: false,
processingDhcpStatus: false,
settingsList: {},
},
);
[actions.disableDnsRequest]: state => ({ ...state, processing: true }),
[actions.disableDnsFailure]: state => ({ ...state, processing: false }),
[actions.disableDnsSuccess]: (state) => {
const newState = { ...state, isCoreRunning: !state.isCoreRunning, processing: false };
return newState;
},
[actions.getVersionRequest]: state => ({ ...state, processingVersion: true }),
[actions.getVersionFailure]: state => ({ ...state, processingVersion: false }),
[actions.getVersionSuccess]: (state, { payload }) => {
const currentVersion = state.dnsVersion === 'undefined' ? 0 : state.dnsVersion;
if (payload && versionCompare(currentVersion, payload.new_version) === -1) {
const dashboard = handleActions(
{
[actions.dnsStatusRequest]: state => ({ ...state, processing: true }),
[actions.dnsStatusFailure]: state => ({ ...state, processing: false }),
[actions.dnsStatusSuccess]: (state, { payload }) => {
const {
announcement_url: announcementUrl,
new_version: newVersion,
can_autoupdate: canAutoUpdate,
version,
running,
dns_port: dnsPort,
dns_addresses: dnsAddresses,
upstream_dns: upstreamDns,
bootstrap_dns: bootstrapDns,
all_servers: allServers,
protection_enabled: protectionEnabled,
language,
http_port: httpPort,
} = payload;
const newState = {
...state,
isCoreRunning: running,
processing: false,
dnsVersion: version,
dnsPort,
dnsAddresses,
upstreamDns: upstreamDns.join('\n'),
bootstrapDns: bootstrapDns.join('\n'),
allServers,
protectionEnabled,
language,
httpPort,
};
return newState;
},
[actions.enableDnsRequest]: state => ({ ...state, processing: true }),
[actions.enableDnsFailure]: state => ({ ...state, processing: false }),
[actions.enableDnsSuccess]: (state) => {
const newState = { ...state, isCoreRunning: !state.isCoreRunning, processing: false };
return newState;
},
[actions.disableDnsRequest]: state => ({ ...state, processing: true }),
[actions.disableDnsFailure]: state => ({ ...state, processing: false }),
[actions.disableDnsSuccess]: (state) => {
const newState = { ...state, isCoreRunning: !state.isCoreRunning, processing: false };
return newState;
},
[actions.getVersionRequest]: state => ({ ...state, processingVersion: true }),
[actions.getVersionFailure]: state => ({ ...state, processingVersion: false }),
[actions.getVersionSuccess]: (state, { payload }) => {
const currentVersion = state.dnsVersion === 'undefined' ? 0 : state.dnsVersion;
if (payload && isVersionGreater(currentVersion, payload.new_version)) {
const {
announcement_url: announcementUrl,
new_version: newVersion,
can_autoupdate: canAutoUpdate,
} = payload;
const newState = {
...state,
announcementUrl,
newVersion,
canAutoUpdate,
isUpdateAvailable: true,
processingVersion: false,
};
return newState;
}
return {
...state,
processingVersion: false,
};
},
[actions.getUpdateRequest]: state => ({ ...state, processingUpdate: true }),
[actions.getUpdateFailure]: state => ({ ...state, processingUpdate: false }),
[actions.getUpdateSuccess]: (state) => {
const newState = { ...state, processingUpdate: false };
return newState;
},
[actions.toggleProtectionRequest]: state => ({ ...state, processingProtection: true }),
[actions.toggleProtectionFailure]: state => ({ ...state, processingProtection: false }),
[actions.toggleProtectionSuccess]: (state) => {
const newState = {
...state,
protectionEnabled: !state.protectionEnabled,
processingProtection: false,
};
return newState;
},
[actions.handleUpstreamChange]: (state, { payload }) => {
const { upstreamDns } = payload;
return { ...state, upstreamDns };
},
[actions.getLanguageSuccess]: (state, { payload }) => {
const newState = { ...state, language: payload };
return newState;
},
[actions.getClientsRequest]: state => ({ ...state, processingClients: true }),
[actions.getClientsFailure]: state => ({ ...state, processingClients: false }),
[actions.getClientsSuccess]: (state, { payload }) => {
const newState = {
...state,
clients: payload.clients,
autoClients: payload.autoClients,
processingClients: false,
};
return newState;
},
[actions.getDnsSettingsRequest]: state => ({ ...state, processingDnsSettings: true }),
[actions.getDnsSettingsFailure]: state => ({ ...state, processingDnsSettings: false }),
[actions.getDnsSettingsSuccess]: (state, { payload }) => {
const {
upstream_dns: upstreamDns,
bootstrap_dns: bootstrapDns,
all_servers: allServers,
} = payload;
return {
...state,
allServers,
upstreamDns: (upstreamDns && upstreamDns.join('\n')) || '',
bootstrapDns: (bootstrapDns && bootstrapDns.join('\n')) || '',
processingDnsSettings: false,
};
},
},
{
processing: true,
isCoreRunning: false,
processingVersion: true,
processingFiltering: true,
processingClients: true,
processingUpdate: false,
processingDnsSettings: true,
upstreamDns: '',
bootstrapDns: '',
allServers: false,
protectionEnabled: false,
processingProtection: false,
httpPort: 80,
dnsPort: 53,
dnsAddresses: [],
dnsVersion: '',
clients: [],
autoClients: [],
},
);
const dhcp = handleActions(
{
[actions.getDhcpStatusRequest]: state => ({ ...state, processing: true }),
[actions.getDhcpStatusFailure]: state => ({ ...state, processing: false }),
[actions.getDhcpStatusSuccess]: (state, { payload }) => {
const { static_leases: staticLeases, ...values } = payload;
const newState = {
...state,
announcementUrl,
newVersion,
canAutoUpdate,
isUpdateAvailable: true,
processingVersion: false,
staticLeases,
processing: false,
...values,
};
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;
}
},
return {
...state,
processingVersion: false,
};
[actions.findActiveDhcpRequest]: state => ({ ...state, processingStatus: true }),
[actions.findActiveDhcpFailure]: state => ({ ...state, processingStatus: false }),
[actions.findActiveDhcpSuccess]: (state, { payload }) => {
const { other_server: otherServer, static_ip: staticIP } = payload;
const newState = {
...state,
check: {
otherServer,
staticIP,
},
processingStatus: false,
};
return newState;
},
[actions.toggleDhcpRequest]: state => ({ ...state, processingDhcp: true }),
[actions.toggleDhcpFailure]: state => ({ ...state, processingDhcp: false }),
[actions.toggleDhcpSuccess]: (state) => {
const { config } = state;
const newConfig = { ...config, enabled: !config.enabled };
const newState = {
...state,
config: newConfig,
check: null,
processingDhcp: false,
};
return newState;
},
[actions.setDhcpConfigRequest]: state => ({ ...state, processingConfig: true }),
[actions.setDhcpConfigFailure]: state => ({ ...state, processingConfig: false }),
[actions.setDhcpConfigSuccess]: (state, { payload }) => {
const { config } = state;
const newConfig = { ...config, ...payload };
const newState = { ...state, config: newConfig, processingConfig: false };
return newState;
},
[actions.toggleLeaseModal]: (state) => {
const newState = {
...state,
isModalOpen: !state.isModalOpen,
};
return newState;
},
[actions.addStaticLeaseRequest]: state => ({ ...state, processingAdding: true }),
[actions.addStaticLeaseFailure]: state => ({ ...state, processingAdding: false }),
[actions.addStaticLeaseSuccess]: (state, { payload }) => {
const { ip, mac, hostname } = payload;
const newLease = {
ip,
mac,
hostname: hostname || '',
};
const leases = [...state.staticLeases, newLease];
const newState = {
...state,
staticLeases: leases,
processingAdding: false,
};
return newState;
},
[actions.removeStaticLeaseRequest]: state => ({ ...state, processingDeleting: true }),
[actions.removeStaticLeaseFailure]: state => ({ ...state, processingDeleting: false }),
[actions.removeStaticLeaseSuccess]: (state, { payload }) => {
const leaseToRemove = payload.ip;
const leases = state.staticLeases.filter(item => item.ip !== leaseToRemove);
const newState = {
...state,
staticLeases: leases,
processingDeleting: false,
};
return newState;
},
},
[actions.getUpdateRequest]: state => ({ ...state, processingUpdate: true }),
[actions.getUpdateFailure]: state => ({ ...state, processingUpdate: false }),
[actions.getUpdateSuccess]: (state) => {
const newState = { ...state, processingUpdate: false };
return newState;
{
processing: true,
processingStatus: false,
processingInterfaces: false,
processingDhcp: false,
processingConfig: false,
processingAdding: false,
processingDeleting: false,
config: {
enabled: false,
},
check: null,
leases: [],
staticLeases: [],
isModalOpen: false,
},
[actions.toggleProtectionRequest]: state => ({ ...state, processingProtection: true }),
[actions.toggleProtectionFailure]: state => ({ ...state, processingProtection: false }),
[actions.toggleProtectionSuccess]: (state) => {
const newState = {
...state,
protectionEnabled: !state.protectionEnabled,
processingProtection: false,
};
return newState;
},
[actions.handleUpstreamChange]: (state, { payload }) => {
const { upstreamDns } = payload;
return { ...state, upstreamDns };
},
[actions.getLanguageSuccess]: (state, { payload }) => {
const newState = { ...state, language: payload };
return newState;
},
[actions.getClientsRequest]: state => ({ ...state, processingClients: true }),
[actions.getClientsFailure]: state => ({ ...state, processingClients: false }),
[actions.getClientsSuccess]: (state, { payload }) => {
const newState = {
...state,
clients: payload.clients,
autoClients: payload.autoClients,
processingClients: false,
};
return newState;
},
}, {
processing: true,
isCoreRunning: false,
processingVersion: true,
processingFiltering: true,
processingClients: true,
processingUpdate: false,
upstreamDns: '',
bootstrapDns: '',
allServers: false,
protectionEnabled: false,
processingProtection: false,
httpPort: 80,
dnsPort: 53,
dnsAddresses: [],
dnsVersion: '',
clients: [],
autoClients: [],
});
const dhcp = handleActions({
[actions.getDhcpStatusRequest]: state => ({ ...state, processing: true }),
[actions.getDhcpStatusFailure]: state => ({ ...state, processing: false }),
[actions.getDhcpStatusSuccess]: (state, { payload }) => {
const {
static_leases: staticLeases,
...values
} = payload;
const newState = {
...state,
staticLeases,
processing: false,
...values,
};
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 }) => {
const {
other_server: otherServer,
static_ip: staticIP,
} = payload;
const newState = {
...state,
check: {
otherServer,
staticIP,
},
processingStatus: false,
};
return newState;
},
[actions.toggleDhcpRequest]: state => ({ ...state, processingDhcp: true }),
[actions.toggleDhcpFailure]: state => ({ ...state, processingDhcp: false }),
[actions.toggleDhcpSuccess]: (state) => {
const { config } = state;
const newConfig = { ...config, enabled: !config.enabled };
const newState = {
...state, config: newConfig, check: null, processingDhcp: false,
};
return newState;
},
[actions.setDhcpConfigRequest]: state => ({ ...state, processingConfig: true }),
[actions.setDhcpConfigFailure]: state => ({ ...state, processingConfig: false }),
[actions.setDhcpConfigSuccess]: (state, { payload }) => {
const { config } = state;
const newConfig = { ...config, ...payload };
const newState = { ...state, config: newConfig, processingConfig: false };
return newState;
},
[actions.toggleLeaseModal]: (state) => {
const newState = {
...state,
isModalOpen: !state.isModalOpen,
};
return newState;
},
[actions.addStaticLeaseRequest]: state => ({ ...state, processingAdding: true }),
[actions.addStaticLeaseFailure]: state => ({ ...state, processingAdding: false }),
[actions.addStaticLeaseSuccess]: (state, { payload }) => {
const {
ip, mac, hostname,
} = payload;
const newLease = {
ip,
mac,
hostname: hostname || '',
};
const leases = [...state.staticLeases, newLease];
const newState = {
...state,
staticLeases: leases,
processingAdding: false,
};
return newState;
},
[actions.removeStaticLeaseRequest]: state => ({ ...state, processingDeleting: true }),
[actions.removeStaticLeaseFailure]: state => ({ ...state, processingDeleting: false }),
[actions.removeStaticLeaseSuccess]: (state, { payload }) => {
const leaseToRemove = payload.ip;
const leases = state.staticLeases.filter(item => item.ip !== leaseToRemove);
const newState = {
...state,
staticLeases: leases,
processingDeleting: false,
};
return newState;
},
}, {
processing: true,
processingStatus: false,
processingInterfaces: false,
processingDhcp: false,
processingConfig: false,
processingAdding: false,
processingDeleting: false,
config: {
enabled: false,
},
check: null,
leases: [],
staticLeases: [],
isModalOpen: false,
});
);
export default combineReducers({
settings,