Updated react UI and UX part.

This commit is contained in:
Alexander 2021-10-27 11:13:28 +03:00
commit 91e7d9ff4a
101 changed files with 1524 additions and 832 deletions

View file

@ -3,7 +3,7 @@ import { getAuthToken } from "src/utils/token";
const BASE_URL = window.location.origin;
const webApiUri = '/api/v1/list/backup/index.php';
const scheduleBackupUri = '/schedule/backup/';
const scheduleBackupUri = '/api/v1/schedule/restore/';
const backupDetailsUri = '/api/v1/list/backup/index.php';
const backupExclusionsUri = '/api/v1/list/backup/exclusions/index.php';
const backupExclusionsInfoUri = '/api/v1/edit/backup/exclusions/index.php';

View file

@ -19,13 +19,26 @@ export const getDNSRecordInfo = (domain, recordId) => {
return axios.get(`${BASE_URL}${updateDNSUri}?domain=${domain}&record_id=${recordId}`);
}
export const bulkAction = (action, domainNameSystems) => {
export const bulkDomainAction = (action, domains) => {
const formData = new FormData();
formData.append("action", action);
formData.append("token", getAuthToken());
domainNameSystems.forEach(domainNameSystem => {
formData.append("domain[]", domainNameSystem);
domains.forEach(record => {
formData.append("domain[]", record);
});
return axios.post(BASE_URL + '/api/v1/bulk/dns/', formData);
};
export const bulkAction = (action, records, domain) => {
const formData = new FormData();
formData.append("action", action);
formData.append("token", getAuthToken());
formData.append("domain", domain);
records.forEach(record => {
formData.append("record[]", record);
});
return axios.post(BASE_URL + '/api/v1/bulk/dns/', formData);

View file

@ -2,7 +2,7 @@ import axios from "axios";
import { getAuthToken } from "src/utils/token";
const BASE_URL = window.location.origin;
const webApiUri = '/search/search.php';
const webApiUri = '/api/v1/search/';
export const getSearchResultsList = term => {
return axios.get(BASE_URL + webApiUri + '?q=' + term);

View file

@ -0,0 +1,27 @@
import { REFRESH_COUNTERS } from './menuCounterTypes';
import { checkAuth } from 'src/services/session';
import { setAuthToken } from 'src/utils/token';
export const refreshCounters = () => (dispatch, getState) => {
return new Promise((resolve, reject) => {
checkAuth()
.then(res => {
const { data, token } = res.data;
if (token) setAuthToken(token);
dispatch({
type: REFRESH_COUNTERS,
value: {
user: data
}
});
resolve(token);
})
.catch(err => {
reject();
console.error(err);
});
});
}

View file

@ -0,0 +1 @@
export const REFRESH_COUNTERS = 'REFRESH_COUNTERS';

View file

@ -2,6 +2,7 @@ import { LOGIN, LOGOUT, LOGGED_OUT_AS, CHECK_AUTH, RESET_PASSWORD } from './sess
import { checkAuth, signIn, signInAs, signOut } from 'src/services/session';
import { resetPassword } from 'src/ControlPanelService/ResetPassword';
import { resetAuthToken, setAuthToken } from 'src/utils/token';
import { REFRESH_COUNTERS } from '../MenuCounters/menuCounterTypes';
const LOGOUT_RESPONSE = 'logged_out';
const LOGOUT_AS_RESPONSE = 'logged_out_as';
@ -21,10 +22,15 @@ export const login = (user, password) => dispatch => {
session,
i18n: i18n || {},
userName: user,
user: data,
error
},
});
dispatch({
type: REFRESH_COUNTERS,
value: {
user: data,
}
});
resolve(token);
}, (error) => {
reject(error);
@ -44,10 +50,15 @@ export const reset = ({ user = '', code = '', password = '', password_confirm =
panel,
session,
userName: user,
user: {},
error
},
});
dispatch({
type: REFRESH_COUNTERS,
value: {
user: {},
}
});
resolve(token);
}, (error) => {
reject(error);
@ -65,7 +76,6 @@ export const loginAs = username => dispatch => {
type: LOGIN,
value: {
userName: user,
user: data,
i18n,
session,
panel,
@ -73,6 +83,12 @@ export const loginAs = username => dispatch => {
error
}
});
dispatch({
type: REFRESH_COUNTERS,
value: {
user: data,
}
});
resolve(token);
}, (error) => {
@ -94,7 +110,6 @@ export const logout = () => (dispatch, getState) => {
type: LOGOUT,
value: {
userName: '',
user: {},
token: '',
panel: {},
session: {},
@ -102,6 +117,12 @@ export const logout = () => (dispatch, getState) => {
error,
},
});
dispatch({
type: REFRESH_COUNTERS,
value: {
user: {},
}
});
resolve();
} else if (logout_response === LOGOUT_AS_RESPONSE) {
@ -109,7 +130,6 @@ export const logout = () => (dispatch, getState) => {
type: LOGGED_OUT_AS,
value: {
userName,
user,
session,
panel,
token: '',
@ -117,6 +137,12 @@ export const logout = () => (dispatch, getState) => {
error,
},
});
dispatch({
type: REFRESH_COUNTERS,
value: {
user,
}
});
resolve();
} else {
@ -135,11 +161,12 @@ export const checkAuthHandler = () => (dispatch, getState) => {
.then(res => {
const { user, data, session, panel, error, i18n, token } = res.data;
if (token) setAuthToken(token);
dispatch({
type: CHECK_AUTH,
value: {
userName: user,
user: data,
i18n,
session,
panel,
@ -147,6 +174,12 @@ export const checkAuthHandler = () => (dispatch, getState) => {
error
}
});
dispatch({
type: REFRESH_COUNTERS,
value: {
user: data,
}
});
resolve(token);
})

View file

@ -57,7 +57,7 @@ const Backup = props => {
{data.UPDATED === 'no' && <div><a href={`/update/vesta/?pkg=${data.NAME}`}>{i18n.update} <FontAwesomeIcon icon="wrench" /></a></div>}
<div>
<a className="link-download" href={`/download/backup/?backup=${data.NAME}&token=${token}`}>
<a className="link-download" href={`/api/v1/download/backup/?backup=${data.NAME}&token=${token}`}>
{i18n.download}
{data.FOCUSED ? <span className="shortcut-button">D</span> : <FontAwesomeIcon icon={faFileDownload} />}
</a>

View file

@ -11,6 +11,7 @@ import { useDispatch, useSelector } from 'react-redux';
import { Helmet } from 'react-helmet';
import './style.scss';
import HtmlParser from 'react-html-parser';
const EditBackupExclusions = () => {
const token = localStorage.getItem("token");
@ -90,7 +91,7 @@ const EditBackupExclusions = () => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -32,7 +32,7 @@ $errorColor: #BE5ABF;
div.error,
div.success {
width: fit-content !important;
width: max-content !important;
span {
font-weight: bold;
@ -40,6 +40,7 @@ $errorColor: #BE5ABF;
svg {
font-size: 13px;
margin-right: 10px;
}
}
@ -151,10 +152,24 @@ $errorColor: #BE5ABF;
}
}
textarea {
&:focus {
background: #D7F9FF;
}
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus,
input:-webkit-autofill:active {
background-color: $primaryLight;
border-color: $primaryActive;
filter: none;
box-shadow: none;
}
input:autofill,
input:autofill:hover,
input:autofill:focus,
input:autofill:active {
background-color: $primaryLight;
border-color: $primaryActive;
filter: none;
box-shadow: none;
}
button {
@ -180,7 +195,7 @@ $errorColor: #BE5ABF;
&:active {
box-shadow: unset;
border-color: $primaryActive;
background: #D7F9FF;
background: #d7dcef9e;
}
}

View file

@ -7,11 +7,7 @@ const TextInputWithExtraButton = props => {
});
useEffect(() => {
if (props.value !== 'unlimited') {
setState({ ...state, value: state.previousValue });
} else {
setState({ ...state, value: props.value });
}
setState({ ...state, value: props.value });
}, [props.value]);
useEffect(() => {

View file

@ -27,7 +27,7 @@ const TextInputWithTextOnTheRight = ({ id, title, name, defaultValue = '', optio
onChange={event => setInputValue(event.target.value)}
disabled={disabled}
name={name} />
<span><i>{`admin_${inputValue}`}</i></span>
<span><i>{`${inputValue}`}</i></span>
</div>
</div>
);

View file

@ -12,6 +12,8 @@ import { useDispatch, useSelector } from 'react-redux';
import './AddCronJob.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const AddCronJob = props => {
const { i18n } = useSelector(state => state.session);
@ -46,18 +48,17 @@ const AddCronJob = props => {
if (Object.keys(newCronJob).length !== 0 && newCronJob.constructor === Object) {
setState({ ...state, loading: true });
addCronJob(newCronJob)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false })
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -100,7 +101,7 @@ const AddCronJob = props => {
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
<span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
<span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -25,11 +25,11 @@ const CronJob = props => {
const handleSuspend = () => {
let suspendedStatus = data.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend' === 'yes' ? 'unsuspend' : 'suspend';
props.handleModal(data.suspend_conf, `/${suspendedStatus}/cron/index.php?job=${data.NAME}`);
props.handleModal(data.suspend_conf, `/api/v1/${suspendedStatus}/cron/index.php?job=${data.NAME}`);
}
const handleDelete = () => {
props.handleModal(data.delete_conf, `/delete/cron/index.php?job=${data.NAME}`);
props.handleModal(data.delete_conf, `/api/v1/delete/cron/index.php?job=${data.NAME}`);
}
return (

View file

@ -13,6 +13,9 @@ import QS from 'qs';
import './EditCronJob.scss';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const EditMail = props => {
const token = localStorage.getItem("token");
@ -79,14 +82,14 @@ const EditMail = props => {
updateCronJob(updatedJob, state.data.job)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false });
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -128,7 +131,7 @@ const EditMail = props => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -5,7 +5,6 @@ import SelectInput from 'src/components/ControlPanel/AddItemLayout/Form/SelectIn
import TextInput from 'src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput';
import AddItemLayout from '../../ControlPanel/AddItemLayout/AddItemLayout';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { addMail } from '../../../ControlPanelService/Mail';
import { addDomainNameSystemRecord } from '../../../ControlPanelService/Dns';
import Toolbar from '../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
@ -14,6 +13,8 @@ import { useDispatch, useSelector } from 'react-redux';
import './AddDNSRecord.scss'
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
export default function AddDNSRecord(props) {
const { i18n } = useSelector(state => state.session);
@ -61,16 +62,18 @@ export default function AddDNSRecord(props) {
newDnsRecord['v_domain'] = props.domain;
if (Object.keys(newDnsRecord).length !== 0 && newDnsRecord.constructor === Object) {
setState({ loading: true });
setState({ ...state, loading: true });
addDomainNameSystemRecord(newDnsRecord)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -94,7 +97,7 @@ export default function AddDNSRecord(props) {
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
<span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
<span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -7,7 +7,6 @@ import { useSelector } from 'react-redux';
export default function DnsRecord({ data, domain, handleModal, ...props }) {
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const toggleFav = (starred) => {
if (starred) {
@ -25,6 +24,10 @@ export default function DnsRecord({ data, domain, handleModal, ...props }) {
handleModal(data.delete_conf, `/api/v1/delete/dns/?domain=${domain}&record_id=${data.ID}`);
}
const handleSuspend = () => {
handleModal(data.suspend_conf, `/api/v1/${data.suspend_action}/dns/?domain=${domain}&record_id=${data.ID}`);
}
return (
<ListItem
id={data.NAME}
@ -62,6 +65,15 @@ export default function DnsRecord({ data, domain, handleModal, ...props }) {
</Link>
</div>
<div>
<button
className="link-gray"
onClick={handleSuspend}>
{data.suspend_action}
{data.FOCUSED ? <span className="shortcut-button">S</span> : <FontAwesomeIcon icon={data.SUSPENDED === 'yes' ? 'unlock' : 'lock'} />}
</button>
</div>
<div>
<button className="link-delete" onClick={() => handleDelete()}>
{i18n.Delete}

View file

@ -11,6 +11,9 @@ import { useHistory } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import QS from 'qs';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
export default function EditDNSRecord(props) {
const token = localStorage.getItem("token");
@ -81,14 +84,14 @@ export default function EditDNSRecord(props) {
updateDNS(updatedRecord, props.domain, props.record_id)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false });
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -111,7 +114,7 @@ export default function EditDNSRecord(props) {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -1,4 +1,4 @@
import React, { useEffect, useState } from 'react';
import React, { memo, useEffect, useState } from 'react';
import { addActiveElement, removeFocusedElement } from "../../../actions/MainNavigation/mainNavigationActions";
import { dbCharsets, addDatabase, getDbOptionalInfo } from '../../../ControlPanelService/Db';
@ -9,11 +9,12 @@ import Toolbar from '../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
import Spinner from '../../Spinner/Spinner';
import { useDispatch, useSelector } from 'react-redux';
import './AddDatabase.scss'
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
import './AddDatabase.scss'
const AddDatabase = props => {
const AddDatabase = memo(props => {
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const dispatch = useDispatch();
@ -91,23 +92,22 @@ const AddDatabase = props => {
newDatabase[name] = value;
}
newDatabase['v_database'] = `${state.user}_${state.databaseInputValue}`;
newDatabase['v_dbuser'] = `${state.user}_${state.databaseUserInputValue}`;
newDatabase['v_database'] = state.databaseInputValue;
newDatabase['v_dbuser'] = state.databaseUserInputValue;
if (Object.keys(newDatabase).length !== 0 && newDatabase.constructor === Object) {
setState({ ...state, loading: true });
addDatabase(newDatabase)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage: '', loading: false });
} else {
setState({ ...state, loading: false })
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -131,7 +131,7 @@ const AddDatabase = props => {
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
<span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
<span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>
@ -141,7 +141,7 @@ const AddDatabase = props => {
<input type="hidden" name="ok" value="add" />
<input type="hidden" name="token" value={token} />
<span className="prefix" dangerouslySetInnerHTML={{ __html: state.prefixI18N }}></span>
<span className="prefix">{HtmlParser(state.prefixI18N)}</span>
<div className="form-group database">
<label htmlFor="database">{i18n.Database}</label>
@ -215,6 +215,6 @@ const AddDatabase = props => {
</AddItemLayout>
</div>
);
}
});
export default AddDatabase;

View file

@ -14,15 +14,18 @@ import QS from 'qs';
import './EditDatabase.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const EditDatabase = props => {
const token = localStorage.getItem("token");
const { i18n } = useSelector(state => state.session);
const { i18n, userName } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
data: {},
loading: false,
databaseUserInputValue: '',
errorMessage: '',
okMessage: ''
});
@ -42,6 +45,7 @@ const EditDatabase = props => {
setState({
...state,
data: response.data,
databaseUserInputValue: response.data.dbuser.split('_').splice(1).join('_'),
errorMessage: response.data['error_msg'],
okMessage: response.data['ok_msg'],
loading: false
@ -60,6 +64,7 @@ const EditDatabase = props => {
}
updatedDatabase['v_database'] = state.data.database;
updatedDatabase['v_dbuser'] = `${userName}_${state.databaseUserInputValue}`;
if (Object.keys(updatedDatabase).length !== 0 && updatedDatabase.constructor === Object) {
setState({ ...state, loading: true });
@ -67,14 +72,14 @@ const EditDatabase = props => {
updateDatabase(updatedDatabase, state.data.database)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false });
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -82,6 +87,10 @@ const EditDatabase = props => {
}
}
const databaseUserInputHandler = value => {
setState({ ...state, databaseUserInputValue: value });
}
return (
<div className="edit-template edit-db">
<Helmet>
@ -97,7 +106,7 @@ const EditDatabase = props => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>
@ -109,7 +118,21 @@ const EditDatabase = props => {
<TextInputWithTextOnTheRight id="database" name="v_database" title={i18n['Database']} defaultValue={state.data.database} disabled />
<TextInputWithTextOnTheRight id="username" name="v_dbuser" title={i18n['User']} defaultValue={state.data.dbuser} />
<div className="form-group">
<div className="label-wrapper">
<label htmlFor="user">{i18n.User}</label>
</div>
<div className="input-wrapper">
<input
type="text"
className="form-control"
id="user"
value={state.databaseUserInputValue}
onChange={event => databaseUserInputHandler(event.target.value)}
name="v_dbuser" />
<span className="italic"><i>{`${userName}_${state.databaseUserInputValue}`}</i></span>
</div>
</div>
<Password name="v_password" defaultValue={state.data.password} />

View file

@ -0,0 +1,9 @@
.input-wrapper {
display: flex;
align-items: center;
span.italic {
margin-left: 15px;
color: #777;
}
}

View file

@ -13,6 +13,8 @@ import './AddDomainNameSystem.scss';
import AdvancedOptions from './AdvancedOptions/AdvancedOptions';
import { addDomainNameSystem } from '../../../ControlPanelService/Dns';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const AddDomainNameSystem = props => {
const { i18n } = useSelector(state => state.session);
@ -33,7 +35,6 @@ const AddDomainNameSystem = props => {
dispatch(removeFocusedElement());
setState({ ...state, loading: true });
getUserNS()
.then(result => {
if (result.data.length) {
@ -53,18 +54,17 @@ const AddDomainNameSystem = props => {
if (Object.keys(domainNameSystem).length !== 0 && domainNameSystem.constructor === Object) {
setState({ ...state, loading: true });
addDomainNameSystem(domainNameSystem)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false });
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -98,7 +98,7 @@ const AddDomainNameSystem = props => {
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
<span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
<span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -13,6 +13,9 @@ import QS from 'qs';
import './EditDomainNameSystem.scss';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const EditDomainNameSystem = props => {
const token = localStorage.getItem("token");
@ -66,14 +69,14 @@ const EditDomainNameSystem = props => {
updateDNS(updatedDomain, state.data.domain)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false });
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -96,7 +99,7 @@ const EditDomainNameSystem = props => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -12,6 +12,8 @@ import { useDispatch, useSelector } from 'react-redux';
import './AddFirewall.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const AddFirewall = props => {
const token = localStorage.getItem("token");
@ -48,18 +50,17 @@ const AddFirewall = props => {
if (Object.keys(newFirewall).length !== 0 && newFirewall.constructor === Object) {
setState({ ...state, loading: true });
addFirewall(newFirewall)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false })
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -83,7 +84,7 @@ const AddFirewall = props => {
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
<span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
<span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -8,6 +8,7 @@ import Toolbar from '../../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { Helmet } from 'react-helmet';
import HtmlParser from 'react-html-parser';
const AddBanIP = () => {
const { i18n } = useSelector(state => state.session);
@ -74,7 +75,7 @@ const AddBanIP = () => {
<div className="search-toolbar-name">{i18n['Adding IP Address to Banlist']}</div>
<div className="error"><span className="error-message">{state.errorMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} {state.errorMessage}</span></div>
<div className="success">
<span className="ok-message">{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span> </span>
<span className="ok-message">{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span> </span>
</div>
</Toolbar>
<AddItemLayout>

View file

@ -13,6 +13,9 @@ import QS from 'qs';
import './EditFirewall.scss';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const EditFirewall = props => {
const token = localStorage.getItem("token");
@ -64,14 +67,14 @@ const EditFirewall = props => {
updateFirewall(updatedDomain, state.data.domain)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false });
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -94,7 +97,7 @@ const EditFirewall = props => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -14,6 +14,8 @@ import { useDispatch, useSelector } from 'react-redux';
import './AddInternetProtocol.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const AddInternetProtocol = props => {
const token = localStorage.getItem("token");
@ -49,18 +51,17 @@ const AddInternetProtocol = props => {
if (Object.keys(newIp).length !== 0 && newIp.constructor === Object) {
setState({ ...state, loading: true });
addInternetProtocol(newIp)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false })
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -96,7 +97,7 @@ const AddInternetProtocol = props => {
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
<span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
<span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -15,6 +15,9 @@ import QS from 'qs';
import './EditInternetProtocol.scss';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const EditInternetProtocol = () => {
const token = localStorage.getItem("token");
@ -72,8 +75,15 @@ const EditInternetProtocol = () => {
updateInternetProtocol(updatedIP, state.data.ip)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
setState({ ...state, errorMessage: error_msg || '', okMessage: ok_msg || '', loading: false });
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
.catch(err => console.error(err));
@ -99,7 +109,7 @@ const EditInternetProtocol = () => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -169,7 +169,7 @@ li.inactive {
background: rgb(220, 220, 220);
}
@media (max-width: 1200px){
@media (max-width: 1320px){
.fPermissions, .fOwner {
display: none;
}

View file

@ -1,4 +1,8 @@
.logs-list {
.toolbar {
padding: 6px 12.5%;
}
.statistic-item {
.l-col {
font-size: 13px;
@ -26,3 +30,9 @@
}
}
}
@media (max-width: 1350px) {
.logs-list .toolbar {
padding: 6px 9.5%;
}
}

View file

@ -11,6 +11,9 @@ import { useDispatch, useSelector } from 'react-redux';
import './AddMail.scss'
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const AddMail = props => {
const { i18n } = useSelector(state => state.session);
@ -40,15 +43,18 @@ const AddMail = props => {
}
if (Object.keys(newMailDomain).length !== 0 && newMailDomain.constructor === Object) {
setState({ ...state, loading: true });
addMail(newMailDomain)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '' });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -72,7 +78,7 @@ const AddMail = props => {
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
<span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
<span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -13,6 +13,9 @@ import QS from 'qs';
import './EditMail.scss';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const EditMail = props => {
const token = localStorage.getItem("token");
@ -66,14 +69,14 @@ const EditMail = props => {
updateMail(updatedDomain, state.data.domain)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false });
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -96,7 +99,7 @@ const EditMail = props => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -62,7 +62,7 @@ const Mail = props => {
</Container>
<Container className="c-3">
{printStat(i18n['AntiSpam Support'], data.ANTISPAM)}
<div>{i18n['Catchall email']}: <span className="stat">{data.CATCHALL}</span></div>
<div>{i18n['Catchall email']}: <span className="stat catchall-mail">{data.CATCHALL}</span></div>
</Container>
</div>
</Container>

View file

@ -1,3 +1,7 @@
.crossed {
text-decoration: line-through;
}
.catchall-mail {
text-transform: none;
}

View file

@ -17,6 +17,8 @@ import { useDispatch, useSelector } from 'react-redux';
import './AddMailAccount.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
export default function AddMailAccount(props) {
const { i18n } = useSelector(state => state.session);
@ -26,6 +28,7 @@ export default function AddMailAccount(props) {
const [state, setState] = useState({
data: {},
advancedOptions: false,
autoreplyChecked: false,
quotaValue: '',
loading: false,
password: '',
@ -54,15 +57,18 @@ export default function AddMailAccount(props) {
newMailDomain['Password'] = newMailDomain['v_password'];
if (Object.keys(newMailDomain).length !== 0 && newMailDomain.constructor === Object) {
setState({ ...state, loading: true });
addMailAccount(newMailDomain, props.domain)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '' });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -114,7 +120,7 @@ export default function AddMailAccount(props) {
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
<span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
<span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -21,10 +21,25 @@
}
}
}
.form-group:nth-child(3) {
> div {
display: flex;
input {
width: 100%;
}
input + button {
padding-left: 10px;
}
}
}
}
.c-2 {
width: 45%;
height: 100%;
border: 1px solid #d9d9d9;
padding: 0px 5px 12px 20px;
}

View file

@ -15,6 +15,9 @@ import { useHistory } from 'react-router-dom';
import Spinner from '../../Spinner/Spinner';
import { useDispatch, useSelector } from 'react-redux';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
export default function EditMailAccount(props) {
const [autoreplyChecked, setAutoreplyChecked] = useState(false);
@ -56,13 +59,14 @@ export default function EditMailAccount(props) {
editMailAccount(newMailDomain, props.domain, props.account)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
goBack();
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -88,12 +92,9 @@ export default function EditMailAccount(props) {
.catch(err => console.error(err));
}
const toggleQuotaValue = () => {
if (state.quotaValue !== 'unlimited') {
setState({ ...state, quotaValue: 'unlimited' });
} else {
setState({ ...state, quotaValue: '' });
}
const toggleQuota = () => {
const value = state.data.quota === 'unlimited' ? '1000' : 'unlimited';
setState({ ...state, data: { ...state.data, quota: value } });
}
const goBack = () => {
@ -116,7 +117,7 @@ export default function EditMailAccount(props) {
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
<span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
<span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>
@ -135,13 +136,58 @@ export default function EditMailAccount(props) {
id="domain"
disabled />
<TextInput
title={i18n['Account']}
value={props.account}
name="v_account"
id="account" />
<Password name="v_password" onChange={password => setState({ ...state, password })} />
<TextInputWithExtraButton title={i18n['Quota']} optionalTitle={i18n['in megabytes']} id="quota" name="v_quota" value={state.data.quota}>
<button type="button" onClick={toggleQuota}>
<FontAwesomeIcon icon="infinity" />
</button>
</TextInputWithExtraButton>
<TextArea
optionalTitle={`${i18n['use local-part']}`}
defaultValue={state.data.aliases}
title={i18n['Aliases']}
name="v_aliases"
id="aliases" />
<TextArea
optionalTitle={`${i18n['one or more email addresses']}`}
defaultValue={state.data.fwd}
title={i18n['Forward to']}
name="v_fwd"
id="fwd" />
<Checkbox
title={i18n['Do not store forwarded mail']}
defaultChecked={state.data.fwd_only === 'yes'}
name="v_fwd_only"
id="fwd_only" />
<Checkbox
title={i18n['Autoreply']}
checked={autoreplyChecked}
onChange={checked => setAutoreplyChecked(checked)}
name="v_autoreply"
id="autoreply" />
{
autoreplyChecked && (
<div style={{ transform: 'translateX(3rem)' }}>
<TextArea
defaultValue={state.data.autoreply_message}
title={i18n['Message']}
name="v_autoreply_message"
id="autoreply_message" />
</div>
)
}
<TextInput
title={i18n['Send login credentials to email address']}
value={state.data.send_email}
name="v_credentials"
id="credentials" />
</div>
<div className="c-2">
@ -153,59 +199,6 @@ export default function EditMailAccount(props) {
</div>
</div>
<div className="r-2">
<TextInputWithExtraButton title={i18n['Quota']} optionalTitle={i18n['in megabytes']} id="quota" name="v_quota" value={state.data.quota}>
<button type="button" onClick={toggleQuotaValue}>
<FontAwesomeIcon icon="infinity" />
</button>
</TextInputWithExtraButton>
<TextArea
optionalTitle={`${i18n['use local-part']}`}
defaultValue={state.data.aliases}
title={i18n['Aliases']}
name="v_aliases"
id="aliases" />
<TextArea
optionalTitle={`${i18n['one or more email addresses']}`}
defaultValue={state.data.fwd}
title={i18n['Forward to']}
name="v_fwd"
id="fwd" />
<Checkbox
title={i18n['Do not store forwarded mail']}
defaultChecked={state.data.fwd_only === 'yes'}
name="v_fwd_only"
id="fwd_only" />
<Checkbox
title={i18n['Autoreply']}
checked={autoreplyChecked}
onChange={checked => setAutoreplyChecked(checked)}
name="v_fwd_only"
id="fwd_only" />
{
autoreplyChecked && (
<div style={{ transform: 'translateX(3rem)' }}>
<TextArea
defaultValue={state.data.autoreply_message}
title={i18n['Message']}
name="v_autoreply_message"
id="autoreply_message" />
</div>
)
}
<TextInput
title={i18n['Send login credentials to email address']}
value={state.data.send_email}
name="v_credentials"
id="credentials" />
</div>
<div className="buttons-wrapper">
<button type="submit" className="add">{i18n.Add}</button>
<button type="button" className="back" onClick={goBack}>{i18n.Back}</button>

View file

@ -1,3 +1,5 @@
$primary: #2c54ac;
.mail-info-block {
.select-group {
select {
@ -5,7 +7,7 @@
margin-top: 5px;
padding: 0;
border: none;
color: #2c9491;
color: $primary;
text-transform: uppercase;
font-size: 11px;
font-weight: bold;

View file

@ -18,7 +18,8 @@ const MainNav = () => {
showTopNav: false
});
const { userName, user, session: { look } } = useSelector(state => state.session);
const { userName, session: { look } } = useSelector(state => state.session);
const { user } = useSelector(state => state.menuCounters);
const { activeElement, focusedElement, adminMenuTabs, userMenuTabs } = useSelector(state => state.mainNavigation);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const dispatch = useDispatch();

View file

@ -5,6 +5,7 @@ import Bell from './Bell';
import BellUnread from './BellUnread';
import { useDispatch, useSelector } from 'react-redux';
import './Notifications.scss';
import HtmlParser from 'react-html-parser';
const Notifications = () => {
const { i18n } = useSelector(state => state.session);
@ -13,8 +14,10 @@ const Notifications = () => {
const [loading, setLoading] = useState(false);
useEffect(() => {
fetchData();
}, []);
if (!notifications) {
fetchData();
}
}, [notifications]);
const fetchData = () => {
setLoading(true);
@ -32,7 +35,7 @@ const Notifications = () => {
.catch(err => {
console.error(err);
setLoading(false);
})
});
}
const removeNotification = id => {
@ -44,7 +47,7 @@ const Notifications = () => {
}
const renderOptions = () => {
if (notifications.length) {
if (notifications && notifications.length) {
return notifications.map(item => {
return (
<>
@ -52,7 +55,7 @@ const Notifications = () => {
<span className="title"><b>{item.TOPIC}</b></span>
<span className="delete-notification" onClick={() => removeNotification(item.ID)}></span>
</div>
<div dangerouslySetInnerHTML={{ __html: item.NOTICE }}></div>
<div>{HtmlParser(item.NOTICE)}</div>
<div className="dropdown-divider"></div>
</>
);
@ -71,7 +74,7 @@ const Notifications = () => {
<button type="button" className="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<div className="bell">
{
notifications.length
notifications && notifications.length
? <BellUnread />
: <Bell />
}

View file

@ -56,7 +56,6 @@ const Panel = props => {
dispatch(logout())
.then(() => {
history.push('/login/');
setLoading(false);
},
error => {
@ -69,7 +68,7 @@ const Panel = props => {
<div className="panel-wrapper">
{loading && <Spinner />}
<div className={`top-panel ${user ? 'long-profile' : ''}`}>
<div className={`top-panel ${look ? 'long-profile' : ''}`}>
<div className="container left-menu">
<div className="logo">
<Link to="/list/user/" onClick={() => dispatch(addActiveElement('/list/user/'))}>
@ -103,7 +102,7 @@ const Panel = props => {
<Link to="/list/firewall/" onClick={event => handleState("/list/firewall/", event)} onKeyPress={event => event.preventDefault()}>{i18n.Firewall}</Link>
</div>}
</>)}
{session.session.FILEMANAGER_KEY && <div className={className("/list/directory/", "fm")}>
{session.session.FILEMANAGER_KEY && <div className={className("/list/directory/")}>
<Link to="/list/directory/">{i18n['File Manager']}</Link>
</div>}
{session.session.SOFTACULOUS === "yes" && <div className={className("/softaculous/")}><a href="/softaculous/">{i18n.Apps ?? 'Apps'}</a>

View file

@ -52,7 +52,7 @@ $textColor: #555;
display: flex;
justify-content: center;
align-items: center;
padding: 0 5px;
padding: 0 10px !important;
width: 100%;
height: 100%;
text-decoration: none;
@ -93,14 +93,15 @@ $textColor: #555;
}
.left-menu {
width: 80%;
width: 75%;
padding-left: 0;
margin-left: 0;
justify-content: space-between;
div {
width: 7rem;
flex: 1 1 auto;
height: 100%;
transform: translateX(-5px);
padding-right: 5px;
&:hover {
background: $secondaryLight;
@ -108,8 +109,19 @@ $textColor: #555;
}
div.logo {
img {
width: 90%;
width: 7rem;
padding-left: 0;
a {
div {
padding: 0;
width: 6rem;
flex: none;
img {
width: 90%;
}
}
}
&:hover {
@ -129,7 +141,7 @@ $textColor: #555;
}
.profile-menu {
width: 20%;
width: auto;
div {
width: 4rem;
@ -189,11 +201,24 @@ $textColor: #555;
.top-panel.long-profile {
.left-menu {
width: 75%;
justify-content: start;
> div {
width: max-content;
flex: unset;
padding: 0 1rem;
}
.logo {
width: 7rem;
padding: 0;
margin-right: 1rem;
}
}
.profile-menu {
width: 25%;
justify-content: space-between;
align-items: center;
> div + div {
width: max-content;

View file

@ -27,7 +27,8 @@ const style = ({ menuHeight, mobile }) => {
const Menu = props => {
const { activeElement, focusedElement } = useSelector(state => state.mainNavigation);
const { user, i18n, session: { look } } = useSelector(state => state.session);
const { i18n, session: { look } } = useSelector(state => state.session);
const { user } = useSelector(state => state.menuCounters);
const dispatch = useDispatch();
useEffect(() => {

View file

@ -81,12 +81,6 @@ $textColor: #555;
.servers-list,
.exclusions-list {
.l-menu {
&.server-icon {
a, span.add {
background: $primary;
}
}
&.backup-details-icon {
transform: translateX(2px);
}

View file

@ -20,6 +20,14 @@ const SearchInput = props => {
return () => window.removeEventListener("keyup", focusInput);
}, []);
const onSubmit = e => {
e.preventDefault();
if (searchTerm) {
handleClick();
}
}
const focusInput = event => {
if (event.keyCode === 70) {
return inputElement.current.focus();
@ -27,10 +35,12 @@ const SearchInput = props => {
}
return (
<div className="search-input-form">
<input type="text" className="form-control" onChange={e => setSearchTerm(e.target.value)} ref={inputElement} />
<button className="btn btn-outline-secondary" type="submit" onClick={() => handleClick()}><FontAwesomeIcon icon="search" /></button>
</div>
<form onSubmit={onSubmit}>
<div className="search-input-form">
<input type="text" className="form-control" onChange={e => setSearchTerm(e.target.value)} ref={inputElement} />
<button className="btn btn-outline-secondary" type="submit" onClick={() => handleClick()}><FontAwesomeIcon icon="search" /></button>
</div>
</form>
);
}

View file

@ -4,7 +4,7 @@ import { values } from '../../../../ControlPanelService/Select';
import { useSelector } from 'react-redux';
import './Select.scss';
const Select = props => {
const Select = ({ cronReports, ...props }) => {
const { i18n } = useSelector(state => state.session);
const listValues = values(i18n);
@ -44,6 +44,14 @@ const Select = props => {
const { list } = props;
let activeList = state[list];
if (list === 'cronList') {
if (cronReports) {
activeList = activeList.filter((item, index) => index !== 0);
} else {
activeList = activeList.filter((item, index) => index !== 1);
}
}
if (list === 'statisticsList') {
return props.users.map((item, index) => { return <option key={index} value={item}>{item}</option> });
} else {

View file

@ -1,3 +1,16 @@
$primary: #2c54ac;
$whiteBackground: #ececec;
$primary: #2c54ac;
$primaryLight: #d7dcef;
$primaryActive: #1e5cb2;
$secondary: #fcac04;
$secondaryLight: #f8b014;
$danger: #b00e5b;
$secondaryActive: #fdb51c;
$hoverButtonText: #2c54ac;
$activeButtonText: #fff;
$textColor: #555;
.toolbar {
display: flex;
flex-direction: row;
@ -8,16 +21,17 @@
left: 0;
width: 100%;
z-index: 1;
padding: 0 13%;
padding: 3px 10% 1px;
border-top: 1px solid #e0e0e0;
border-bottom: 1px solid #e0e0e0;
padding-top: 5px;
.r-menu {
display: flex;
justify-content: center;
align-items: center;
a.button-extra, button.button-extra {
a.button-extra,
button.button-extra {
background: none;
border: none;
padding: 0 0.75rem;
@ -27,9 +41,17 @@
display: flex;
justify-content: center;
align-items: center;
margin-right: 10px;
border-radius: 3px;
&:hover {
color: rgb(78, 76, 76);
background: $primaryLight;
color: $hoverButtonText;
}
&:active {
background: $primaryActive;
color: $activeButtonText;
}
}
@ -131,7 +153,7 @@
@media (max-width: 1350px) {
.toolbar {
padding: 5px 10% 0;
padding: 3px 10% 1px;
}
}

View file

@ -36,6 +36,8 @@ $black: #000;
margin-top: 100px;
.modal-body {
overflow-wrap: anywhere;
font-size: 17px;
margin-bottom: 40px;
input {

View file

@ -15,6 +15,8 @@ import { useDispatch, useSelector } from 'react-redux';
import './AddPackage.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const AddPackage = props => {
const token = localStorage.getItem("token");
@ -89,18 +91,17 @@ const AddPackage = props => {
if (Object.keys(newPackage).length !== 0 && newPackage.constructor === Object) {
setState({ ...state, loading: true });
addPackage(newPackage)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false })
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -141,7 +142,7 @@ const AddPackage = props => {
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
<span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
<span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -16,6 +16,9 @@ import QS from 'qs';
import './EditPackage.scss';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const EditPackage = props => {
const token = localStorage.getItem("token");
@ -70,9 +73,15 @@ const EditPackage = props => {
updatePackage(updatedPackage, state.data.package)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
setState({ ...state, errorMessage: error_msg || '', okMessage: ok_msg || '', loading: false });
history.push('/list/package/');
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
.catch(err => console.error(err));
@ -113,7 +122,7 @@ const EditPackage = props => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -9,7 +9,6 @@ import { useSelector } from 'react-redux';
const Package = props => {
const { data } = props;
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const printNameServers = servers => {
let serversArray = servers.split(',');
@ -32,7 +31,7 @@ const Package = props => {
}
const handleDelete = () => {
props.handleModal(data.delete_conf, `/api/v1/delete/package?package=${data.NAME}`);
props.handleModal(data.delete_conf, `/api/v1/delete/package/index.php?package=${data.NAME}`);
}
return (

View file

@ -5,13 +5,13 @@ import Dropdown from './Dropdown/Dropdown';
import './Path.scss';
const Path = ({ path, isActive, className, openDirectory, changeSorting, sorting, order }) => {
const session = useSelector(state => state.session);
const { user } = useSelector(state => state.menuCounters);
const clickablePath = () => {
let splitPath = path.split('/');
splitPath.splice(0, 3);
if (path !== session.user.HOME) {
if (path !== user.HOME) {
return (
splitPath.map((item, index) => <span className="clickable" key={index} onClick={() => openDirectoryHandler(index)}>&nbsp;/&nbsp;{item}</span>)
);
@ -36,7 +36,7 @@ const Path = ({ path, isActive, className, openDirectory, changeSorting, sorting
<div className={className}>
<div className="clickable-wrapper">
<span className="clickable-path">
<span className="clickable" onClick={() => openDirectory(session.user.HOME)}>{session.user.HOME}</span>
<span className="clickable" onClick={() => openDirectory(user.HOME)}>{user.HOME}</span>
{clickablePath()}
</span>
</div>

View file

@ -1,13 +1,54 @@
import React from 'react';
import { loginAs, logout } from 'src/actions/Session/sessionActions';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import ListItem from '../ControlPanel/ListItem/ListItem';
import Container from '../ControlPanel/Container/Container';
import { useSelector } from 'react-redux';
import ListItem from '../ControlPanel/ListItem/ListItem';
import { useDispatch, useSelector } from 'react-redux';
import { Link, useHistory } from 'react-router-dom';
import './SearchItem.scss';
import { Link } from 'react-router-dom';
const SearchItem = ({ data, handleModal }) => {
const { i18n } = useSelector(state => state.session);
const { i18n, userName } = useSelector(state => state.session);
const dispatch = useDispatch();
const history = useHistory()
const signInAs = user => {
dispatch(loginAs(user)).then(() => history.push('/'));
}
const signOut = () => {
dispatch(logout()).then(() => history.push('/'));
}
const handleDelete = () => {
handleModal(data.delete_confirmation, `/api/v1/${data.TYPE === 'user' ? `/api/v1/delete/user/index.php?user=${data.USER}` : data.delete_link}`);
}
const handleSuspend = () => {
handleModal(data.spnd_confirmation, `/api/v1/${data.TYPE === 'user' ? `${data.spnd_action}/user/index.php?user=${data.USER}` : data.spnd_link}`);
}
const printLoginActionButton = () => {
if (data.TYPE !== 'user') return;
if (userName === data.USER) {
return (
<div>
<button onClick={signOut}>{i18n['Log out']}
{data.FOCUSED ? <span className="shortcut-button">L</span> : <FontAwesomeIcon icon="user-lock" />}
</button>
</div>
);
} else {
return (
<div>
<button onClick={() => signInAs(data.USER)}>{i18n['login as']} {data.USER}
{data.FOCUSED ? <span className="shortcut-button">L</span> : <FontAwesomeIcon icon="user-lock" />}
</button>
</div>
);
}
}
return (
<ListItem date={data.DATE} suspended={data.SUSPENDED === 'yes'}>
@ -15,7 +56,7 @@ const SearchItem = ({ data, handleModal }) => {
<div className="name">{data.RESULT}</div>
<div className="stats">
<Container className="c-1">
<div className="object">{i18n[data.object]}</div>
<div className="object">{data.TYPE === 'user' ? i18n['USER'] : i18n[data.object]}</div>
</Container>
<Container className="c-2">
<div className="owner">{i18n.Owner}: <span>{data.USER}</span></div>
@ -26,17 +67,20 @@ const SearchItem = ({ data, handleModal }) => {
</div>
</Container>
<div className="actions">
{printLoginActionButton()}
<div><Link className="link-edit" to={data.edit_link}>{i18n.edit} <FontAwesomeIcon icon="pen" /></Link></div>
<div>
<button
className="link-gray"
onClick={() => handleModal(data.spnd_confirmation, '/api/v1' + data.spnd_link)}>
onClick={handleSuspend}>
{data.spnd_action}
<FontAwesomeIcon icon={data.SUSPENDED === 'yes' ? 'unlock' : 'lock'} />
</button>
</div>
<div>
<button className="link-delete" onClick={() => this.props.handleModal(data.delete_confirmation, data, data.delete_link)}>
<button
className="link-delete"
onClick={handleDelete}>
{i18n.Delete}
<FontAwesomeIcon icon="times" />
</button>

View file

@ -12,6 +12,7 @@ import { useDispatch, useSelector } from 'react-redux';
import './Bind9.scss';
import { Helmet } from 'react-helmet';
import HtmlParser from 'react-html-parser';
const Bind9 = () => {
const token = localStorage.getItem("token");
@ -94,7 +95,7 @@ const Bind9 = () => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -12,6 +12,7 @@ import { useDispatch, useSelector } from 'react-redux';
import './Dovecot.scss';
import { Helmet } from 'react-helmet';
import HtmlParser from 'react-html-parser';
const Dovecot = () => {
const token = localStorage.getItem("token");
@ -94,7 +95,7 @@ const Dovecot = () => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -19,6 +19,7 @@ import { useDispatch, useSelector } from 'react-redux';
import './EditServer.scss';
import { Helmet } from 'react-helmet';
import HtmlParser from 'react-html-parser';
const EditServer = props => {
const token = localStorage.getItem("token");
@ -106,7 +107,7 @@ const EditServer = props => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -12,6 +12,7 @@ import { useDispatch, useSelector } from 'react-redux';
import './EditHttpd.scss';
import { Helmet } from 'react-helmet';
import HtmlParser from 'react-html-parser';
const EditHttpd = props => {
const token = localStorage.getItem("token");
@ -89,7 +90,7 @@ const EditHttpd = props => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -13,6 +13,7 @@ import { useDispatch, useSelector } from 'react-redux';
import './Mysql.scss';
import { Helmet } from 'react-helmet';
import HtmlParser from 'react-html-parser';
const Mysql = ({ serviceName = '' }) => {
const token = localStorage.getItem("token");
@ -107,7 +108,7 @@ const Mysql = ({ serviceName = '' }) => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -13,6 +13,7 @@ import { useDispatch, useSelector } from 'react-redux';
import './EditServerNginx.scss';
import { Helmet } from 'react-helmet';
import HtmlParser from 'react-html-parser';
const EditServerNginx = props => {
const token = localStorage.getItem("token");
@ -100,7 +101,7 @@ const EditServerNginx = props => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -13,6 +13,7 @@ import { useDispatch, useSelector } from 'react-redux';
import './EditPhp.scss';
import { Helmet } from 'react-helmet';
import HtmlParser from 'react-html-parser';
const EditPhp = ({ serviceName = '' }) => {
const token = localStorage.getItem("token");
@ -104,7 +105,7 @@ const EditPhp = ({ serviceName = '' }) => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -12,6 +12,7 @@ import { useDispatch, useSelector } from 'react-redux';
import './Postgresql.scss';
import { Helmet } from 'react-helmet';
import HtmlParser from 'react-html-parser';
const Postgresql = () => {
const token = localStorage.getItem("token");
@ -94,7 +95,7 @@ const Postgresql = () => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -12,6 +12,7 @@ import { useDispatch, useSelector } from 'react-redux';
import './Service.scss';
import { Helmet } from 'react-helmet';
import HtmlParser from 'react-html-parser';
const Service = ({ serviceName = '' }) => {
const token = localStorage.getItem("token");
@ -100,7 +101,7 @@ const Service = ({ serviceName = '' }) => {
</div>
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -10,10 +10,9 @@ import './TopPanel.scss';
const TopPanel = ({ menuItems = [], extraMenuItems = [] }) => {
const mainNavigation = useSelector(state => state.mainNavigation);
const [loading, setLoading] = useState(false);
const { i18n } = useSelector(state => state.session);
const { i18n, userName } = useSelector(state => state.session);
const dispatch = useDispatch();
const history = useHistory();
const { userName } = useSelector(state => state.session);
const className = cls => {
let className = 'nav-link';

View file

@ -13,6 +13,9 @@ import { useDispatch, useSelector } from 'react-redux';
import './AddUser.scss';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const AddUser = props => {
const { i18n } = useSelector(state => state.session);
@ -71,19 +74,23 @@ const AddUser = props => {
}
if (Object.keys(newUser).length !== 0 && newUser.constructor === Object) {
setState({ ...state, loading: true });
addUser(newUser)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '' });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg });
}
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
})
.catch(err => console.error(err));
.catch(err => {
setState({ ...state, loading: false });
console.error(err);
});
}
}
@ -133,7 +140,7 @@ const AddUser = props => {
<div className="search-toolbar-name">{i18n['Adding User']}</div>
<div className="error"><span className="error-message">{state.errorMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} {state.errorMessage}</span></div>
<div className="success">
<span className="ok-message">{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span> </span>
<span className="ok-message">{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span> </span>
</div>
</Toolbar>
<AddItemLayout>

View file

@ -15,6 +15,9 @@ import QS from 'qs';
import './EditUser.scss';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const EditUser = props => {
const token = localStorage.getItem("token");
@ -68,14 +71,14 @@ const EditUser = props => {
updateUser(updatedUser, state.username)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false });
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -103,7 +106,7 @@ const EditUser = props => {
<div className="search-toolbar-name">{i18n['Editing User']}</div>
<div className="error"><span className="error-message">{state.data.errorMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} {state.errorMessage}</span></div>
<div className="success">
<span className="ok-message">{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span> </span>
<span className="ok-message">{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span> </span>
</div>
</Toolbar>
<AddItemLayout date={state.data.date} time={state.data.time} status={state.data.status}>

View file

@ -9,9 +9,8 @@ import { Link } from 'react-router-dom';
import './User.scss';
const User = ({ data, toggleFav, handleModal, checkItem }) => {
const { i18n } = useSelector(state => state.session);
const { i18n, userName } = useSelector(state => state.session);
const session = useSelector(state => state.session);
const token = localStorage.getItem("token");
const dispatch = useDispatch();
const printNameServers = servers => {

View file

@ -39,6 +39,7 @@ $textColor: #555;
span.stat.email{
display: block;
width: max-content;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;

View file

@ -13,6 +13,8 @@ import { useDispatch, useSelector } from 'react-redux';
import './AddWebDomain.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const AddWebDomain = props => {
const { i18n } = useSelector(state => state.session);
@ -37,7 +39,6 @@ const AddWebDomain = props => {
dispatch(removeFocusedElement());
setState({ ...state, loading: true });
Promise.all([getWebStats(), getIpList()])
.then(result => {
const [webStats, internetProtocols] = result;
@ -94,12 +95,14 @@ const AddWebDomain = props => {
addWeb(newWebDomain)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -123,7 +126,7 @@ const AddWebDomain = props => {
<div className="success">
<span className="ok-message">
{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''}
<span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span>
<span>{HtmlParser(state.okMessage)}</span>
</span>
</div>
</Toolbar>

View file

@ -5,10 +5,10 @@ import Password from '../../../../components/ControlPanel/AddItemLayout/Form/Pas
import './AdditionalFtpForEditing.scss';
const AdditionalFtpForEditing = ({ domain, data = {}, onDeleteAdditionalFtp, prefixI18N, prePath, checked }) => {
const { userName, i18n } = useSelector(state => state.session);
const AdditionalFtpForEditing = ({ domain, data = {}, onDeleteAdditionalFtp, prefixI18N, prePath, checked, ...props }) => {
const { i18n, userName } = useSelector(state => state.session);
const [state, setState] = useState({
username: data.v_ftp_user,
username: data.v_ftp_user || '',
path: ''
});
@ -29,72 +29,73 @@ const AdditionalFtpForEditing = ({ domain, data = {}, onDeleteAdditionalFtp, pre
return <></>;
}
return (<div className="additional-ftp">
<div className="title">
<input type="hidden" name={`v_ftp_user[${data.id}][delete]`} value="0" />
<input type="hidden" name={`v_ftp_user[${data.id}][is_new]`} value="1" />
return (
<div className="additional-ftp">
<div className="title">
<input type="hidden" name={`v_ftp_user[${data.id}][delete]`} value="0" />
<input type="hidden" name={`v_ftp_user[${data.id}][is_new]`} value="1" />
<span className="data.indexed-name">{i18n.FTP} #{data.id + 1}</span>
<span>
&nbsp;
<button
type="button"
onClick={() => onDeleteAdditionalFtp(data.id)}>
({i18n.Delete ?? 'Delete'})
</button>
</span>
</div>
<div className="form-transform">
<div className="form-group username">
<label htmlFor={`ftp_user_${data.id}`}>{i18n.Username}</label>
<span className="prefix-note">{prefixI18N}</span>
<div className="input-wrapper">
<input
defaultValue={state.username}
onChange={event => setState({ ...state, username: event.target.value })}
type="text"
disabled={data.v_ftp_user}
className="form-control"
id={`ftp_user_${data.id}`}
name={`v_ftp_user[${data.id}][v_ftp_user]`} />
<span>{`${userName}_${state.username}`}</span>
</div>
<span className="data.indexed-name">{i18n.FTP} #{data.id + 1}</span>
<span>
&nbsp;
<button
type="button"
onClick={() => onDeleteAdditionalFtp(data.id)}>
({i18n.Delete ?? 'Delete'})
</button>
</span>
</div>
<Password name={`v_ftp_user[${data.id}][v_ftp_password]`} id={data.id} />
<div className="form-group">
<input type="hidden" name="v_ftp_pre_path" value={prePath} />
<input type="hidden" name={`v_ftp_user[${data.id}][v_ftp_path_prev]`} value={data.v_ftp_path !== '/' ? '/' : ''} />
<label htmlFor={`path${data.id}`}>{i18n.Path}</label>
<input
type="text"
value={state.path}
onChange={event => setState({ ...state, path: event.target.value })}
className="form-control"
id={`path${data.id}`}
name={`v_ftp_user[${data.id}][v_ftp_path]`} />
<span className="path-note">{`${data.v_ftp_pre_path ? data.v_ftp_pre_path : ''}/${state.path}`}</span>
</div>
{
data.is_new === 1 && (
<div className="form-group">
<label htmlFor={`sendLoginCredentialsToEmailAddress_${data.id}`}>{i18n['Send login credentials to email address']}</label>
<div className="form-transform">
<div className="form-group username">
<label htmlFor={`ftp_user_${data.id}`}>{i18n.Username}</label>
<span className="prefix-note">{prefixI18N}</span>
<div className="input-wrapper">
<input
type="email"
defaultValue={state.username}
onChange={event => setState({ ...state, username: event.target.value })}
type="text"
disabled={data.v_ftp_user}
className="form-control"
id={`sendLoginCredentialsToEmailAddress_${data.id}`}
defaultValue={data.v_ftp_email}
name={`v_ftp_user[${data.id}][v_ftp_email]`} />
id={`ftp_user_${data.id}`}
name={`v_ftp_user[${data.id}][v_ftp_user]`} />
<span>{data.v_ftp_user ? data.v_ftp_user : `${userName}_${state.username}`}</span>
</div>
)
}
</div>
</div>
</div >);
<Password name={`v_ftp_user[${data.id}][v_ftp_password]`} id={data.id} />
<div className="form-group">
<input type="hidden" name="v_ftp_pre_path" value={prePath} />
<input type="hidden" name={`v_ftp_user[${data.id}][v_ftp_path_prev]`} value={data.v_ftp_path !== '/' ? '/' : ''} />
<label htmlFor={`path${data.id}`}>{i18n.Path}</label>
<input
type="text"
value={state.path}
onChange={event => setState({ ...state, path: event.target.value })}
className="form-control"
id={`path${data.id}`}
name={`v_ftp_user[${data.id}][v_ftp_path]`} />
<span className="path-note">{prePath}</span>
</div>
{
data.is_new === 1 && (
<div className="form-group">
<label htmlFor={`sendLoginCredentialsToEmailAddress_${data.id}`}>{i18n['Send login credentials to email address']}</label>
<input
type="email"
className="form-control"
id={`sendLoginCredentialsToEmailAddress_${data.id}`}
defaultValue={data.v_ftp_email}
name={`v_ftp_user[${data.id}][v_ftp_email]`} />
</div>
)
}
</div>
</div >);
}
return <></>;

View file

@ -1,34 +1,35 @@
import React, { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import AdditionalFtp from '../AdditionalFtp/AdditionalFtp';
import AdditionalFtpForEditing from '../AdditionalFtpForEditing/AdditionalFtpForEditing';
import './AdditionalFtpWrapper.scss';
const AdditionalFtpWrapper = props => {
const AdditionalFtpWrapper = ({ checked, ftps, unCheckAdditionalFtpBox, prefixI18N, ftpUserPrePath, domain, ...props }) => {
const { i18n } = useSelector(state => state.session);
const [state, setState] = useState({
additionalFtp: []
});
useEffect(() => {
if (props.ftps) {
const data = props.ftps.map((item, index) => {
item['deleted'] = false;
if (ftps) {
const data = ftps.map((item, index) => {
item['deleted'] = !checked;
item['id'] = index;
return item;
});
setState({ ...state, additionalFtp: data });
}
}, [props.ftps]);
}, [checked, ftps]);
const renderAdditionalFtps = () => {
return state.additionalFtp.map(ftp => {
return <AdditionalFtpForEditing
key={ftp.id}
prefixI18N={props.prefixI18N}
prefixI18N={prefixI18N}
data={ftp}
checked={props.checked}
prePath={props.ftpUserPrePath}
domain={props.domain}
checked={checked}
prePath={ftpUserPrePath}
domain={domain}
onDeleteAdditionalFtp={id => onDeleteFtp(id)} />;
});
}
@ -45,7 +46,7 @@ const AdditionalFtpWrapper = props => {
});
if (!updatedAdditionalFtps.length) {
props.unCheckAdditionalFtpBox();
unCheckAdditionalFtpBox();
}
setState({ ...state, additionalFtp: updatedAdditionalFtps });
@ -64,7 +65,7 @@ const AdditionalFtpWrapper = props => {
<div>
{renderAdditionalFtps()}
{props.checked && (
{checked && (
<button type="button" onClick={() => addAdditionalFtp()}>
{i18n['Add one more FTP Account'] ?? 'Add'}
</button>)}

View file

@ -0,0 +1,48 @@
.additional-ftp {
.title {
span:nth-child(1) {
color: #555;
font-size: 15px;
font-weight: bold;
}
}
.form-transform {
margin-top: 15px;
transform: translateX(3rem);
.form-group.username {
display: flex;
flex-direction: column;
label {
margin: 0;
}
span {
font-size: 10pt;
color: #777;
font-weight: bold;
margin-bottom: 10px;
}
.input-wrapper {
display: flex;
align-items: center;
span {
color: #777;
font-size: 15px;
font-style: italic;
font-weight: normal;
margin-left: 15px;
}
}
}
}
.path-note {
font-weight: bold;
color: #555;
}
}

View file

@ -18,6 +18,9 @@ import QS from 'qs';
import './EditWeb.scss';
import TextArea from '../../ControlPanel/AddItemLayout/Form/TextArea/TextArea';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser';
const EditWeb = props => {
const token = localStorage.getItem("token");
@ -83,14 +86,14 @@ const EditWeb = props => {
updateWebDomain(updatedDomain, state.domain)
.then(result => {
if (result.status === 200) {
const { error_msg, ok_msg } = result.data;
const { error_msg: errorMessage, ok_msg: okMessage } = result.data;
if (error_msg) {
setState({ ...state, errorMessage: error_msg, okMessage: '', loading: false });
} else if (ok_msg) {
setState({ ...state, errorMessage: '', okMessage: ok_msg, loading: false });
if (errorMessage) {
setState({ ...state, errorMessage, okMessage, loading: false });
} else {
setState({ ...state, loading: false });
dispatch(refreshCounters()).then(() => {
setState({ ...state, okMessage, errorMessage: '', loading: false });
});
}
}
})
@ -134,7 +137,7 @@ const EditWeb = props => {
<div className="search-toolbar-name">{i18n['Editing Domain']}</div>
<div className="error"><span className="error-message">{state.data.errorMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} {state.errorMessage}</span></div>
<div className="success">
<span className="ok-message">{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span dangerouslySetInnerHTML={{ __html: state.okMessage }}></span> </span>
<span className="ok-message">{state.okMessage ? <FontAwesomeIcon icon="long-arrow-alt-right" /> : ''} <span>{HtmlParser(state.okMessage)}</span> </span>
</div>
</Toolbar>
<AddItemLayout date={state.data.date} time={state.data.time} status={state.data.status}>

View file

@ -93,10 +93,10 @@ export default function WebDomain(props) {
</Link>
</div>
<div>
<a className="link-gray" href={`/list/web-log?domain=${data.NAME}&type=access`}>
<Link className="link-gray" to={`/list/web-log?domain=${data.NAME}&type=access`}>
{i18n['view logs']}
{data.FOCUSED ? <span className="shortcut-button">L</span> : <FontAwesomeIcon icon="list" />}
</a>
</Link>
</div>
{
data.STATS && (

View file

@ -22,7 +22,7 @@
align-items: center;
> div:nth-child(1) {
width: 34%;
margin-right: 2rem;
}
.dns-name-span {

View file

@ -71,10 +71,6 @@ const App = () => {
useEffect(() => {
if (!Object.entries(session.i18n).length) {
dispatch(checkAuthHandler()).then(token => {
if (token) {
setAuthToken(token);
}
setLoading(false);
});
}

View file

@ -10,6 +10,10 @@ $hoverButtonText: #2c54ac;
$activeButtonText: #fff;
$textColor: #555;
html {
overflow-y: scroll;
}
.App {
font-size: 25px;
font-family: Arial;

View file

@ -16,13 +16,14 @@ import Backup from '../../components/Backup/Backup';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import './Backups.scss';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const Backups = props => {
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -31,7 +32,6 @@ const Backups = props => {
const [state, setState] = useState({
backups: [],
backupFav: [],
loading: true,
toggledAll: false,
selection: [],
totalAmount: ''
@ -41,7 +41,7 @@ const Backups = props => {
dispatch(addActiveElement('/list/backup/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -146,7 +146,7 @@ const Backups = props => {
}
const download = () => {
props.history.push(`/download/backup?backup=${controlPanelFocusedElement}`);
window.open(`/api/v1/download/backup?backup=${controlPanelFocusedElement}`);
}
const handleDelete = () => {
@ -157,19 +157,22 @@ const Backups = props => {
}
const fetchData = () => {
getBackupList()
.then(result => {
setState({
...state,
backups: reformatData(result.data.data),
backupFav: result.data.backup_fav,
totalAmount: result.data.totalAmount,
selection: [],
toggledAll: false,
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getBackupList()
.then(result => {
setState({
...state,
backups: reformatData(result.data.data),
backupFav: result.data.backup_fav,
totalAmount: result.data.totalAmount,
selection: [],
toggledAll: false
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = data => {
@ -278,12 +281,14 @@ const Backups = props => {
const { selection } = state;
if (selection.length && action) {
setState({ ...state, loading: true });
setLoading(true);
bulkAction(action, selection)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -291,7 +296,7 @@ const Backups = props => {
}
const displayModal = (text, url) => {
setState({ ...state, loading: false });
setLoading(false);
setModal({
...modal,
visible: true,
@ -301,13 +306,25 @@ const Backups = props => {
}
const modalConfirmHandler = () => {
if (!modal.actionUrl) return;
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(() => fetchData())
.catch(err => console.error(err));
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -320,10 +337,15 @@ const Backups = props => {
}
const scheduleBackupButton = () => {
setState({ ...state, loading: true });
setLoading(true);
scheduleBackup()
.then(result => displayModal(result.data.error_msg, ''))
.then(result => {
if (result.data.error) {
displayModal(result.data.error, '');
} else {
displayModal(result.data.ok, '');
}
})
.catch(err => console.error(err));
}
@ -349,9 +371,13 @@ const Backups = props => {
</div>
</Toolbar>
<div className="backups-wrapper">
{state.loading ? <Spinner /> : backups()}
{loading
? <Spinner />
: (<>
{backups()}
<div className="total">{state.totalAmount}</div>
</>)}
</div>
<div className="total">{state.totalAmount}</div>
<Modal
onSave={modalConfirmHandler}
onCancel={modalCancelHandler}

View file

@ -66,10 +66,10 @@ const ControlPanelContent = props => {
const dispatch = useDispatch();
useEffect(() => {
if (userName) {
setLoading(false);
if (!userName) {
return history.push('/login');
} else {
history.push('/login');
setLoading(false);
}
if (look) {
@ -102,7 +102,6 @@ const ControlPanelContent = props => {
return;
}
console.log(event);
switch (event.keyCode) {
case 49: return history.push('/list/user/');
case 50: return history.push('/list/web/');
@ -200,7 +199,7 @@ const ControlPanelContent = props => {
})
}
<Route path="/list/user" component={props => <Users changeSearchTerm={handleSearchTerm} loading={loading} {...props} />} />
<Route path="/list/user" component={props => <Users changeSearchTerm={handleSearchTerm} {...props} />} />
<Route path="/add/user" component={() => <AddUser />} />
<Route path="/edit/user" component={() => <EditUser />} />
<Route path="/list/web" component={props => <Web {...props} changeSearchTerm={handleSearchTerm} />} />

View file

@ -16,13 +16,14 @@ import Spinner from '../../components/Spinner/Spinner';
import { useSelector, useDispatch } from 'react-redux';
import './CronJobs.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const CronJobs = props => {
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -31,7 +32,6 @@ const CronJobs = props => {
const [state, setState] = useState({
cronJobs: [],
cronFav: [],
loading: true,
toggledAll: false,
cronReports: '',
sorting: i18n.Date,
@ -44,7 +44,7 @@ const CronJobs = props => {
dispatch(addActiveElement('/list/cron/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -164,20 +164,23 @@ const CronJobs = props => {
}
const fetchData = () => {
getCronList()
.then(result => {
setState({
...state,
cronJobs: reformatData(result.data.data),
cronReports: result.data.cron_reports,
cronFav: result.data.cron_fav,
selection: [],
toggledAll: false,
totalAmount: result.data.totalAmount,
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getCronList()
.then(result => {
setState({
...state,
cronJobs: reformatData(result.data.data),
cronReports: result.data.cron_reports,
cronFav: result.data.cron_fav,
selection: [],
toggledAll: false,
totalAmount: result.data.totalAmount
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = data => {
@ -316,13 +319,21 @@ const CronJobs = props => {
const bulk = action => {
const { selection } = state;
const notifications = state.cronReports === 'yes' ? 'delete-cron-reports' : 'add-cron-reports';
if (action === notifications) {
return handleCronNotifications();
}
if (selection.length && action) {
setLoading(true);
bulkAction(action, selection)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -340,15 +351,24 @@ const CronJobs = props => {
const modalConfirmHandler = () => {
if (!modal.actionUrl) {
modalCancelHandler();
return modalCancelHandler();
}
setState({ ...state, loading: true });
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(() => fetchData())
.catch(err => console.error(err));
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -385,16 +405,20 @@ const CronJobs = props => {
{state.cronReports === 'yes' ? i18n['turn off notifications'] : i18n['turn on notifications']}
</button>
<Checkbox toggleAll={toggleAll} toggled={state.toggledAll} />
<Select list='cronList' bulkAction={bulk} />
<Select list='cronList' bulkAction={bulk} cronReports={state.cronReports === 'yes'} />
<DropdownFilter changeSorting={changeSorting} sorting={state.sorting} order={state.order} list="cronList" />
<SearchInput handleSearchTerm={term => props.changeSearchTerm(term)} />
</div>
</div>
</Toolbar>
<div className="cron-wrapper">
{state.loading ? <Spinner /> : cronJobs()}
{loading
? <Spinner />
: (<>
{cronJobs()}
<div className="total">{state.totalAmount}</div>
</>)}
</div>
<div className="total">{state.totalAmount}</div>
<Modal
showCancelButton={modal.actionUrl}
onCancel={modalCancelHandler}

View file

@ -17,14 +17,15 @@ import QueryString from 'qs';
import './DNSRecords.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
export default function DnsRecords(props) {
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem('token');
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const history = useHistory();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -34,7 +35,6 @@ export default function DnsRecords(props) {
dnsRecords: [],
dnsRecordFav: [],
domain: '',
loading: true,
toggledAll: false,
sorting: i18n.Date,
order: "descending",
@ -44,7 +44,7 @@ export default function DnsRecords(props) {
useEffect(() => {
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -156,23 +156,23 @@ export default function DnsRecords(props) {
const fetchData = () => {
let parsedQueryString = QueryString.parse(history.location.search, { ignoreQueryPrefix: true });
setState({ ...state, loading: true });
getDNSRecordsList(parsedQueryString.domain || '')
.then(result => {
setState({
...state,
dnsRecords: reformatData(result.data.data),
dnsRecordFav: result.data.dnsRecordsFav,
totalAmount: result.data.totalAmount,
domain: parsedQueryString.domain,
toggledAll: false,
selection: [],
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getDNSRecordsList(parsedQueryString.domain || '')
.then(result => {
setState({
...state,
dnsRecords: reformatData(result.data.data),
dnsRecordFav: result.data.dnsRecordsFav,
totalAmount: result.data.totalAmount,
domain: parsedQueryString.domain,
toggledAll: false,
selection: []
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = data => {
@ -281,11 +281,14 @@ export default function DnsRecords(props) {
const { selection } = state;
if (selection.length && action) {
bulkAction(action, selection)
setLoading(true);
bulkAction(action, selection, state.domain)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -302,12 +305,25 @@ export default function DnsRecords(props) {
}
const modalConfirmHandler = () => {
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(() => {
fetchData();
modalCancelHandler();
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => console.error(err));
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -334,7 +350,7 @@ export default function DnsRecords(props) {
</div>
</div>
</Toolbar>
{state.loading
{loading
? <Spinner />
: (
<>

View file

@ -70,6 +70,7 @@ $textColor: #555;
display: flex;
align-items: center;
margin-top: 2rem;
padding-bottom: 1.5rem;
.total {
margin: 0 3.5rem 0 14.3%;

View file

@ -16,13 +16,14 @@ import { useSelector, useDispatch } from 'react-redux';
import Spinner from '../../components/Spinner/Spinner';
import './Databases.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const Databases = props => {
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -31,7 +32,6 @@ const Databases = props => {
const [state, setState] = useState({
databases: [],
dbFav: [],
loading: true,
toggledAll: false,
dbAdmin: '',
dbAdminLink: '',
@ -45,7 +45,7 @@ const Databases = props => {
dispatch(addActiveElement('/list/db/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -165,21 +165,24 @@ const Databases = props => {
}
const fetchData = () => {
getDatabaseList()
.then(result => {
setState({
...state,
databases: reformatData(result.data.data),
dbAdmin: result.data.db_admin,
dbAdminLink: result.data.db_admin_link,
dbFav: result.data.dbFav,
selection: [],
toggledAll: false,
totalAmount: result.data.totalAmount,
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getDatabaseList()
.then(result => {
setState({
...state,
databases: reformatData(result.data.data),
dbAdmin: result.data.db_admin,
dbAdminLink: result.data.db_admin_link,
dbFav: result.data.dbFav,
selection: [],
toggledAll: false,
totalAmount: result.data.totalAmount
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = data => {
@ -323,12 +326,14 @@ const Databases = props => {
const { selection } = state;
if (selection.length && action) {
setState({ ...state, loading: true });
setLoading(true);
bulkAction(action, selection)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -345,13 +350,25 @@ const Databases = props => {
}
const modalConfirmHandler = () => {
setState({ ...state, loading: true });
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(() => {
fetchData();
modalCancelHandler();
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => console.error(err));
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -381,7 +398,7 @@ const Databases = props => {
</div>
</Toolbar>
<div className="mails-wrapper">
{state.loading
{loading
? <Spinner />
: (<>
{databases()}

View file

@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import { addControlPanelContentFocusedElement, removeControlPanelContentFocusedElement } from '../../actions/ControlPanelContent/controlPanelContentActions';
import { addActiveElement, removeFocusedElement } from '../../actions/MainNavigation/mainNavigationActions';
import DropdownFilter from '../../components/MainNav/Toolbar/DropdownFilter/DropdownFilter';
import { bulkAction, getDnsList, handleAction } from '../../ControlPanelService/Dns';
import { bulkDomainAction, getDnsList, handleAction } from '../../ControlPanelService/Dns';
import * as MainNavigation from '../../actions/MainNavigation/mainNavigationActions';
import SearchInput from '../../components/MainNav/Toolbar/SearchInput/SearchInput';
import DomainNameSystem from '../../components/DomainNameSystem/DomainNameSystem';
@ -17,13 +17,14 @@ import './DomainNameSystems.scss';
import { useDispatch, useSelector } from 'react-redux';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const DomainNameSystems = props => {
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -32,7 +33,6 @@ const DomainNameSystems = props => {
const [state, setState] = useState({
domainNameSystems: [],
dnsFav: [],
loading: false,
toggledAll: false,
sorting: i18n.Date,
order: "descending",
@ -44,7 +44,7 @@ const DomainNameSystems = props => {
dispatch(addActiveElement('/list/dns/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -174,21 +174,22 @@ const DomainNameSystems = props => {
}
const fetchData = () => {
setState({ ...state, loading: true });
getDnsList()
.then(result => {
setState({
...state,
domainNameSystems: reformatData(result.data.data),
dnsFav: result.data.dnsFav,
selection: [],
toggledAll: false,
totalAmount: result.data.totalAmount,
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getDnsList()
.then(result => {
setState({
...state,
domainNameSystems: reformatData(result.data.data),
dnsFav: result.data.dnsFav,
selection: [],
toggledAll: false,
totalAmount: result.data.totalAmount
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = data => {
@ -341,12 +342,14 @@ const DomainNameSystems = props => {
const { selection } = state;
if (selection.length && action) {
setState({ loading: true });
bulkAction(action, selection)
setLoading(true);
bulkDomainAction(action, selection)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -363,12 +366,25 @@ const DomainNameSystems = props => {
}
const modalConfirmHandler = () => {
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(() => {
fetchData();
modalCancelHandler();
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => console.error(err));
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -397,7 +413,7 @@ const DomainNameSystems = props => {
</div>
</Toolbar>
<div className="dns-wrapper">
{state.loading ? <Spinner /> : dns()}
{loading ? <Spinner /> : dns()}
</div>
<div className="total">{state.totalAmount}</div>
<Modal

View file

@ -20,15 +20,15 @@ class FileManager extends Component {
super(props);
this.state = {
leftList: {
path: this.props.session.user.HOME,
path: this.props.menuCounters.user.HOME,
files: { listing: [] },
},
rightList: {
path: this.props.session.user.HOME,
path: this.props.menuCounters.user.HOME,
files: { listing: [] },
},
currentPath: this.props.session.user.HOME,
currentUser: this.props.session.user.HOME,
currentPath: this.props.menuCounters.user.HOME,
currentUser: this.props.menuCounters.user.HOME,
activeWindow: "left",
modalWindow: null,
modalVisible: false,
@ -44,7 +44,7 @@ class FileManager extends Component {
}
UNSAFE_componentWillMount = () => {
FM.cacheData(this.state.currentUser, this.props.history, this.props.session.user.HOME);
FM.cacheData(this.state.currentUser, this.props.history, this.props.menuCounters.user.HOME);
let currentPath = FM.activeWindowPath();
this.setState({ currentPath });
this.changeDirectoryOnLoading();
@ -435,7 +435,7 @@ class FileManager extends Component {
addToPath={this.addToPath}
cursor={this.state.cursor}
passData={this.passData}
rootDir={this.props.session.user.HOME}
rootDir={this.props.menuCounters.user.HOME}
ref={el => this[`${side}List`] = el}
download={this.download}
moveBack={this.moveBack}
@ -480,7 +480,8 @@ class FileManager extends Component {
function mapStateToProps(state) {
return {
session: state.session
session: state.session,
menuCounters: state.menuCounters
}
}

View file

@ -16,6 +16,7 @@ import { Helmet } from 'react-helmet';
import { useHistory } from 'react-router';
import './styles.scss';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const BanLists = props => {
const { i18n } = useSelector(state => state.session);
@ -23,6 +24,7 @@ const BanLists = props => {
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -31,7 +33,6 @@ const BanLists = props => {
const [state, setState] = useState({
banIps: [],
selection: [],
loading: false,
toggledAll: false,
sorting: i18n.Action,
order: "descending",
@ -42,7 +43,7 @@ const BanLists = props => {
dispatch(addActiveElement('/list/firewall/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -148,20 +149,21 @@ const BanLists = props => {
}
const fetchData = () => {
setState({ ...state, loading: true });
getBanList()
.then(result => {
setState({
...state,
banIps: reformatData(result.data.data),
totalAmount: result.data.total_amount,
toggledAll: false,
selection: [],
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getBanList()
.then(result => {
setState({
...state,
banIps: reformatData(result.data.data),
totalAmount: result.data.total_amount,
toggledAll: false,
selection: []
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = data => {
@ -234,8 +236,10 @@ const BanLists = props => {
bulkAction(action, selection)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -247,12 +251,25 @@ const BanLists = props => {
}
const modalConfirmHandler = () => {
modalCancelHandler();
setState({ ...state, loading: true });
if (!modal.actionUrl) {
return modalCancelHandler();
}
handleAction(state.modalActionUrl)
.then(() => fetchData())
.catch(err => console.error(err));
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -275,7 +292,7 @@ const BanLists = props => {
</div>
</Toolbar>
<div className="banlist-wrapper">
{state.loading
{loading
? <Spinner />
: (<>
{banIps()}

View file

@ -17,13 +17,14 @@ import { useDispatch, useSelector } from 'react-redux';
import './Firewalls.scss';
import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const Firewalls = props => {
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -34,7 +35,6 @@ const Firewalls = props => {
firewallFav: [],
selection: [],
firewallExtension: '',
loading: false,
toggledAll: false,
sorting: i18n.Action,
order: "descending",
@ -45,7 +45,7 @@ const Firewalls = props => {
dispatch(addActiveElement('/list/firewall/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -165,22 +165,23 @@ const Firewalls = props => {
}
const fetchData = () => {
setState({ ...state, loading: true });
getFirewallList()
.then(result => {
setState({
...state,
firewalls: reformatData(result.data.data),
firewallFav: result.data.firewallFav,
selection: [],
firewallExtension: result.data.firewallExtension,
totalAmount: result.data.totalAmount,
toggledAll: false,
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getFirewallList()
.then(result => {
setState({
...state,
firewalls: reformatData(result.data.data),
firewallFav: result.data.firewallFav,
selection: [],
firewallExtension: result.data.firewallExtension,
totalAmount: result.data.totalAmount,
toggledAll: false
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = data => {
@ -319,11 +320,14 @@ const Firewalls = props => {
const { selection } = state;
if (selection.length && action) {
setLoading(true);
bulkAction(action, selection)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -335,12 +339,25 @@ const Firewalls = props => {
}
const modalConfirmHandler = () => {
modalCancelHandler();
setState({ ...state, loading: true });
if (!modal.actionUrl) {
return modalCancelHandler();
}
handleAction(state.modalActionUrl)
.then(() => fetchData())
.catch(err => console.error(err));
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -365,9 +382,13 @@ const Firewalls = props => {
</div>
</Toolbar>
<div className="firewalls-wrapper">
{state.loading ? <Spinner /> : firewalls()}
{loading
? <Spinner />
: (<>
{firewalls()}
<div className="total">{state.totalAmount}</div>
</>)}
</div>
<div className="total">{state.totalAmount}</div>
<Modal
onSave={modalConfirmHandler}
onCancel={modalCancelHandler}

View file

@ -16,12 +16,14 @@ import Spinner from '../../components/Spinner/Spinner';
import { useDispatch, useSelector } from 'react-redux';
import './InternetProtocols.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const InternetProtocols = props => {
const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -30,7 +32,6 @@ const InternetProtocols = props => {
const [state, setState] = useState({
internetProtocols: [],
ipFav: [],
loading: false,
toggledAll: false,
sorting: i18n.Date,
order: "descending",
@ -42,7 +43,7 @@ const InternetProtocols = props => {
dispatch(addActiveElement('/list/ip/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -153,21 +154,22 @@ const InternetProtocols = props => {
}
const fetchData = () => {
setState({ ...state, loading: true });
getIpList()
.then(result => {
setState({
...state,
internetProtocols: reformatData(result.data.data),
ipFav: result.data.ipFav,
selection: [],
totalAmount: result.data.totalAmount,
toggledAll: false,
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getIpList()
.then(result => {
setState({
...state,
internetProtocols: reformatData(result.data.data),
ipFav: result.data.ipFav,
selection: [],
totalAmount: result.data.totalAmount,
toggledAll: false
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = data => {
@ -312,13 +314,14 @@ const InternetProtocols = props => {
const { selection } = state;
if (selection.length && action) {
setState({ ...state, loading: true });
setLoading(true);
bulkAction(action, selection)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -330,12 +333,25 @@ const InternetProtocols = props => {
}
const modalConfirmHandler = () => {
modalCancelHandler();
setState({ ...state, loading: true });
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(() => fetchData())
.catch(err => console.error(err));
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -359,9 +375,13 @@ const InternetProtocols = props => {
</div>
</Toolbar>
<div className="ip-wrapper">
{state.loading ? <Spinner /> : internetProtocols()}
{loading
? <Spinner />
: (<>
{internetProtocols()}
<div className="total">{state.totalAmount}</div>
</>)}
</div>
<div className="total">{state.totalAmount}</div>
<Modal
onSave={modalConfirmHandler}
onCancel={modalCancelHandler}

View file

@ -17,13 +17,15 @@ import { Link } from 'react-router-dom';
import './MailAccounts.scss';
import { Helmet } from 'react-helmet';
import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
export default function MailAccounts(props) {
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -32,7 +34,6 @@ export default function MailAccounts(props) {
const [state, setState] = useState({
mailAccounts: [],
mailAccountsFav: [],
loading: false,
domain: props.domain,
toggledAll: false,
sorting: i18n.Date,
@ -43,7 +44,7 @@ export default function MailAccounts(props) {
useEffect(() => {
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -131,7 +132,6 @@ export default function MailAccounts(props) {
}
const handleFocusedElementShortcuts = event => {
event.preventDefault();
let isSearchInputFocused = document.querySelector('input:focus') || document.querySelector('textarea:focus');
if (controlPanelFocusedElement && !isSearchInputFocused) {
@ -164,22 +164,23 @@ export default function MailAccounts(props) {
}
const fetchData = () => {
setState({ ...state, loading: true });
getMailAccountList(props.domain)
.then(result => {
setState({
...state,
mailAccounts: reformatData(result.data.data),
webMail: result.data.webMail,
selection: [],
toggledAll: false,
mailAccountsFav: result.data.mailAccountsFav,
totalAmount: result.data.totalAmount,
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getMailAccountList(props.domain)
.then(result => {
setState({
...state,
mailAccounts: reformatData(result.data.data),
webMail: result.data.webmail,
selection: [],
toggledAll: false,
mailAccountsFav: result.data.mailAccountsFav,
totalAmount: result.data.totalAmount
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = data => {
@ -319,11 +320,14 @@ export default function MailAccounts(props) {
const bulk = action => {
const { selection } = state;
if (selection.length && action) {
setLoading(true);
bulkMailAccountAction(action, props.domain, selection)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -340,12 +344,25 @@ export default function MailAccounts(props) {
}
const modalConfirmHandler = () => {
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(() => {
fetchData();
modalCancelHandler();
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => console.error(err));
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -374,7 +391,7 @@ export default function MailAccounts(props) {
</div>
</div>
</Toolbar>
{state.loading
{loading
? <Spinner />
: (
<>

View file

@ -17,6 +17,7 @@ $primary: #2c54ac;
div.list-item {
.r-col {
.stat.email {
width: max-content;
text-transform: none;
}
}
@ -27,6 +28,7 @@ $primary: #2c54ac;
display: flex;
align-items: center;
margin-top: 2rem;
padding-bottom: 1.5rem;
.total {
margin: 0 3.5rem 0 14.3%;

View file

@ -17,13 +17,14 @@ import './Mails.scss';
import { useSelector, useDispatch } from 'react-redux';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const Mails = props => {
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -32,7 +33,6 @@ const Mails = props => {
const [state, setState] = useState({
mails: [],
mailFav: [],
loading: false,
toggledAll: false,
webMail: '',
sorting: i18n.Date,
@ -45,7 +45,7 @@ const Mails = props => {
dispatch(addActiveElement('/list/mail/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -175,22 +175,23 @@ const Mails = props => {
}
const fetchData = () => {
setState({ ...state, loading: true });
getMailList()
.then(result => {
setState({
...state,
mails: reformatData(result.data.data),
webMail: result.data.webMail,
mailFav: result.data.mailFav,
selection: [],
toggledAll: false,
totalAmount: result.data.totalAmount,
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getMailList()
.then(result => {
setState({
...state,
mails: reformatData(result.data.data),
webMail: result.data.webMail,
mailFav: result.data.mailFav,
selection: [],
toggledAll: false,
totalAmount: result.data.totalAmount
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = data => {
@ -332,12 +333,14 @@ const Mails = props => {
const { selection } = state;
if (selection.length && action) {
setState({ ...state, loading: true });
setLoading(true);
bulkAction(action, selection)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -354,12 +357,25 @@ const Mails = props => {
}
const modalConfirmHandler = () => {
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(() => {
fetchData();
modalCancelHandler();
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => console.error(err));
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -389,7 +405,7 @@ const Mails = props => {
</div>
</Toolbar>
<div className="mails-wrapper">
{state.loading
{loading
? <Spinner />
: (<>
{mails()}

View file

@ -16,12 +16,14 @@ import Spinner from '../../components/Spinner/Spinner';
import { useDispatch, useSelector } from 'react-redux';
import './Packages.scss';
import { Helmet } from 'react-helmet';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const Packages = props => {
const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -30,7 +32,6 @@ const Packages = props => {
const [state, setState] = useState({
packages: [],
packagesFav: [],
loading: true,
toggledAll: false,
sorting: i18n.Date,
order: "descending",
@ -42,7 +43,7 @@ const Packages = props => {
dispatch(addActiveElement('/list/package/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -149,23 +150,26 @@ const Packages = props => {
const { packages } = state;
let currentPackageData = packages.filter(pack => pack.NAME === controlPanelFocusedElement)[0];
displayModal(currentPackageData.delete_conf, `/api/v1/delete/package/?package=${controlPanelFocusedElement}`);
displayModal(currentPackageData.delete_conf, `/api/v1/delete/package/index.php?package=${controlPanelFocusedElement}`);
}
const fetchData = () => {
getPackageList()
.then(result => {
setState({
...state,
packages: reformatData(result.data.data),
packagesFav: result.data.packagesFav,
totalAmount: result.data.totalAmount,
selection: [],
toggledAll: false,
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getPackageList()
.then(result => {
setState({
...state,
packages: reformatData(result.data.data),
packagesFav: result.data.packagesFav,
totalAmount: result.data.totalAmount,
selection: [],
toggledAll: false
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = data => {
@ -306,13 +310,14 @@ const Packages = props => {
const { selection } = state;
if (selection.length && action) {
setState({ ...state, loading: true });
setLoading(true);
bulkAction(action, selection)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -324,12 +329,25 @@ const Packages = props => {
}
const modalConfirmHandler = () => {
modalCancelHandler();
setState({ ...state, loading: true });
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(() => fetchData())
.catch(err => console.error(err));
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -354,7 +372,7 @@ const Packages = props => {
</Toolbar>
<div className="packages-wrapper">
{
state.loading
loading
? <Spinner />
: (<>
{packages()}

View file

@ -18,7 +18,7 @@ div.content {
color: $textColor;
.toolbar {
padding-bottom: 10px;
padding: 6px 12.5%;
}
.rrd-item {
@ -90,3 +90,9 @@ div.content {
color: $secondaryActive;
}
}
@media (max-width: 1350px) {
.rrd-list .toolbar {
padding: 6px 9.5%;
}
}

View file

@ -7,18 +7,20 @@ import Toolbar from '../../components/MainNav/Toolbar/Toolbar';
import Modal from '../../components/ControlPanel/Modal/Modal';
import Spinner from '../../components/Spinner/Spinner';
import './Search.scss';
import { useSelector } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const Search = props => {
const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [state, setState] = useState({
searchResults: [],
totalAmount: '',
sorting: i18n.Date,
order: "descending",
loading: false,
total: 0
});
const [modal, setModal] = useState({
@ -34,29 +36,31 @@ const Search = props => {
let searchTerm = search.split('=')[1];
if (searchTerm !== '') {
fetchData(searchTerm);
fetchData(searchTerm).then(() => setLoading(false));
} else {
return history.push({ pathname: '/list/user/', search: '' });
}
} else if (props.searchTerm !== '') {
fetchData(props.searchTerm);
fetchData(props.searchTerm).then(() => setLoading(false));
} else {
return history.push({ pathname: '/list/user/', search: '' });
}
}, []);
const fetchData = searchTerm => {
setState({ ...state, loading: true });
getSearchResultsList(searchTerm)
.then(result => {
setState({
...state,
searchResults: result.data.data,
totalAmount: result.data.total_amount,
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getSearchResultsList(searchTerm)
.then(result => {
setState({
...state,
searchResults: result.data.data,
totalAmount: result.data.total
});
resolve();
})
.catch(err => console.error(err));
});
}
const searchResults = () => {
@ -99,7 +103,6 @@ const Search = props => {
switch (sorting) {
case Date: return 'DATE';
case Name: return 'RESULT';
case Starred: return 'STARRED';
default: break;
}
}
@ -114,12 +117,25 @@ const Search = props => {
}
const modalConfirmHandler = () => {
handleAction(state.modalActionUrl)
.then(() => {
fetchData();
modalCancelHandler();
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => console.error(err));
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -141,9 +157,13 @@ const Search = props => {
</div>
</Toolbar>
<div className="statistics-wrapper">
{state.loading ? <Spinner /> : searchResults()}
{loading
? <Spinner />
: (<>
{searchResults()}
<div className="total">{state.totalAmount}</div>
</>)}
</div>
<div className="total">{state.totalAmount}</div>
<Modal
onSave={modalConfirmHandler}
onCancel={modalCancelHandler}

View file

@ -15,12 +15,14 @@ import Server from '../../components/Server/Server';
import { Link } from 'react-router-dom';
import { Helmet } from 'react-helmet';
import './Servers.scss';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const Servers = props => {
const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -29,7 +31,6 @@ const Servers = props => {
const [state, setState] = useState({
servers: [],
selection: [],
loading: false,
toggledAll: false,
sorting: i18n.Action,
order: "descending",
@ -39,7 +40,7 @@ const Servers = props => {
dispatch(addActiveElement('/list/server/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -156,19 +157,20 @@ const Servers = props => {
}
const fetchData = () => {
setState({ ...state, loading: true });
getServersList()
.then(result => {
setState({
...state,
selection: [],
toggledAll: false,
servers: reformatData(result.data.data, result.data.sys),
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getServersList()
.then(result => {
setState({
...state,
selection: [],
toggledAll: false,
servers: reformatData(result.data.data, result.data.sys)
});
resolve();
})
.catch(err => console.error(err));
});
}
const reformatData = (servers, sysInfo) => {
@ -207,18 +209,17 @@ const Servers = props => {
const onHandleAction = uri => {
dispatch(removeControlPanelContentFocusedElement());
if (uri) {
setState({ ...state, loading: true });
setLoading(true);
handleAction(uri)
.then(res => {
if (res.data.error) {
displayModal(res.data.error);
}
setState({ ...state, loading: false });
setLoading(false);
})
.catch(err => {
setState({ ...state, loading: false });
setLoading(false);
console.error(err)
});
}
@ -258,8 +259,10 @@ const Servers = props => {
displayModal(res.data.error);
}
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
})
.catch(err => console.error(err));
}
@ -288,11 +291,25 @@ const Servers = props => {
}
const modalConfirmHandler = () => {
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setState({ ...state, loading: true });
setLoading(true);
handleAction(modal.actionUrl)
.then(() => fetchData())
.catch(err => console.error(err));
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -315,7 +332,7 @@ const Servers = props => {
</div>
</div>
</Toolbar>
{state.loading ? <Spinner /> : (
{loading ? <Spinner /> : (
<div className="servers-wrapper">
{servers()}
</div>

View file

@ -2,7 +2,7 @@
color: #686868;
.toolbar {
padding-bottom: 5px;
padding: 6px 12.5%;
}
.l-col {
@ -29,3 +29,9 @@
color: #5edad0;
}
}
@media (max-width: 1350px) {
.statistics-list .toolbar {
padding: 6px 9.5%;
}
}

View file

@ -16,12 +16,14 @@ import Spinner from '../../components/Spinner/Spinner';
import User from '../../components/User/User';
import { Helmet } from 'react-helmet';
import './Users.scss';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const Users = props => {
const { userName, i18n, session: { look } } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -30,7 +32,6 @@ const Users = props => {
const [state, setState] = useState({
users: [],
userFav: [],
loading: false,
toggledAll: false,
sorting: i18n.Date,
order: "descending",
@ -42,7 +43,7 @@ const Users = props => {
dispatch(addActiveElement('/list/user/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -60,21 +61,22 @@ const Users = props => {
}, [controlPanelFocusedElement, focusedElement, state.users]);
const fetchData = () => {
setState({ ...state, loading: true });
getUsersList()
.then(result => {
setState({
...state,
users: reformatData(result.data.data),
userFav: result.data.userFav,
totalAmount: result.data.totalAmount,
toggledAll: false,
selection: [],
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getUsersList()
.then(result => {
setState({
...state,
users: reformatData(result.data.data),
userFav: result.data.userFav,
totalAmount: result.data.totalAmount,
toggledAll: false,
selection: []
});
resolve();
})
.catch(err => console.error(err));
});
}
const handleFocusedElementShortcuts = event => {
@ -322,13 +324,14 @@ const Users = props => {
const bulk = action => {
if (state.selection.length && action) {
setState({ ...state, loading: true });
setLoading(true);
bulkAction(action, state.selection)
.then(result => {
if (result.status === 200) {
fetchData();
toggleAll(false);
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
});
}
})
.catch(err => console.error(err));
@ -345,13 +348,25 @@ const Users = props => {
}
const modalConfirmHandler = () => {
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setState({ ...state, loading: true });
setLoading(true);
handleAction(modal.actionUrl)
.then(() => {
fetchData();
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => console.error(err));
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -383,7 +398,7 @@ const Users = props => {
</div>
</Toolbar>
<div className="users-wrapper">
{state.loading
{loading
? <Spinner />
: (<>
{users()}

View file

@ -16,13 +16,14 @@ import Modal from '../../components/ControlPanel/Modal/Modal';
import { useDispatch, useSelector } from 'react-redux';
import { Helmet } from 'react-helmet';
import './Web.scss';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
const Web = props => {
const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({
text: '',
visible: false,
@ -31,7 +32,6 @@ const Web = props => {
const [state, setState] = useState({
webDomains: [],
webFav: [],
loading: false,
toggledAll: false,
sorting: i18n.Date,
order: "descending",
@ -43,7 +43,7 @@ const Web = props => {
dispatch(addActiveElement('/list/web/'));
dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement());
fetchData();
fetchData().then(() => setLoading(false));
return () => {
dispatch(removeControlPanelContentFocusedElement());
@ -168,21 +168,22 @@ const Web = props => {
}
const fetchData = () => {
setState({ ...state, loading: true });
getWebList()
.then(result => {
setState({
...state,
webDomains: reformatData(result.data.data),
webFav: result.data.webFav,
totalAmount: result.data.totalAmount,
toggledAll: false,
selection: [],
loading: false
});
})
.catch(err => console.error(err));
setLoading(true);
return new Promise((resolve, reject) => {
getWebList()
.then(result => {
setState({
...state,
webDomains: reformatData(result.data.data),
webFav: result.data.webFav,
totalAmount: result.data.totalAmount,
toggledAll: false,
selection: []
});
resolve();
})
.catch(err => console.error(err));
});
}
const changeSorting = (sorting, order) => {
@ -318,14 +319,13 @@ const Web = props => {
const bulk = action => {
if (state.selection.length && action) {
setState({ ...state, loading: true });
setLoading(true);
bulkAction(action, state.selection)
.then(result => {
if (result.status === 200) {
fetchData();
fetchData().then(() => {
refreshMenuCounters();
toggleAll(false);
}
});
})
.catch(err => console.error(err));
}
@ -334,20 +334,32 @@ const Web = props => {
const displayModal = (text, url) => {
setModal({
...modal,
visible: !modal.visible,
visible: true,
text,
actionUrl: url
});
}
const modalConfirmHandler = () => {
setState({ ...state, loading: true });
if (!modal.actionUrl) {
return modalCancelHandler();
}
modalCancelHandler();
setLoading(true);
handleAction(modal.actionUrl)
.then(() => {
fetchData();
.then(res => {
if (res.data.error) {
setLoading(false);
return displayModal(res.data.error, '');
}
fetchData().then(() => refreshMenuCounters())
})
.catch(err => console.error(err));
.catch(err => { setLoading(false); console.error(err); });
}
const refreshMenuCounters = () => {
dispatch(refreshCounters()).then(() => setLoading(false));
}
const modalCancelHandler = () => {
@ -376,7 +388,7 @@ const Web = props => {
</div>
</Toolbar>
<div className="web-domains-wrapper">
{state.loading
{loading
? <Spinner />
: (
<>

View file

@ -12,11 +12,10 @@ import Spinner from 'src/components/Spinner/Spinner';
import { Helmet } from 'react-helmet';
export default function WebLogs() {
const { i18n } = useSelector(state => state.session);
const { i18n, userName } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const mainNavigation = useSelector(state => state.mainNavigation);
const { userName } = useSelector(state => state.session);
const [domain, setDomain] = useState();
const [state, setState] = useState({
data: "",

View file

@ -0,0 +1,19 @@
import { REFRESH_COUNTERS } from 'src/actions/MenuCounters/menuCounterTypes';
const INITIAL_STATE = {
user: {},
};
const menuCounterReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case REFRESH_COUNTERS:
return {
...state,
user: action.value.user,
};
default: return state;
}
};
export default menuCounterReducer;

View file

@ -1,7 +1,7 @@
import { ADD_NOTIFICATIONS, REMOVE_NOTIFICATIONS } from 'src/actions/Notification/notificationTypes';
const INITIAL_STATE = {
notifications: []
notifications: null
};
const notificationReducer = (state = INITIAL_STATE, action) => {

View file

@ -2,7 +2,6 @@ import { LOGGED_OUT_AS, LOGIN, LOGOUT, CHECK_AUTH } from '../../actions/Session/
const INITIAL_STATE = {
token: '',
user: {},
error: '',
session: {},
i18n: {},
@ -16,7 +15,6 @@ const sessionReducer = (state = INITIAL_STATE, action) => {
return {
...state,
token: action.value.token,
user: action.value.user,
session: action.value.session,
userName: action.value.userName,
i18n: action.value.i18n || {},
@ -28,7 +26,6 @@ const sessionReducer = (state = INITIAL_STATE, action) => {
return {
...state,
token: action.value.token,
user: action.value.user,
session: action.value.session,
userName: action.value.userName,
i18n: action.value.i18n || {},
@ -40,7 +37,6 @@ const sessionReducer = (state = INITIAL_STATE, action) => {
return {
...state,
token: action.value.token,
user: action.value.user,
session: action.value.session,
userName: action.value.userName,
i18n: action.value.i18n || {},
@ -51,7 +47,6 @@ const sessionReducer = (state = INITIAL_STATE, action) => {
case CHECK_AUTH: return {
...state,
token: action.value.token,
user: action.value.user,
session: action.value.session,
userName: action.value.userName,
i18n: action.value.i18n || {},

Some files were not shown because too many files have changed in this diff Show more