mirror of
https://github.com/serghey-rodin/vesta.git
synced 2025-08-21 05:44:07 -07:00
Updated react UI and UX part.
This commit is contained in:
parent
4a9bfc94ad
commit
91e7d9ff4a
101 changed files with 1524 additions and 832 deletions
|
@ -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';
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
27
web/js/react/src/actions/MenuCounters/menuCounterActions.js
Normal file
27
web/js/react/src/actions/MenuCounters/menuCounterActions.js
Normal 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);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
export const REFRESH_COUNTERS = 'REFRESH_COUNTERS';
|
|
@ -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);
|
||||
})
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,11 +7,7 @@ const TextInputWithExtraButton = props => {
|
|||
});
|
||||
|
||||
useEffect(() => {
|
||||
if (props.value !== 'unlimited') {
|
||||
setState({ ...state, value: state.previousValue });
|
||||
} else {
|
||||
setState({ ...state, value: props.value });
|
||||
}
|
||||
}, [props.value]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
|
@ -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} />
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
.input-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
span.italic {
|
||||
margin-left: 15px;
|
||||
color: #777;
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -169,7 +169,7 @@ li.inactive {
|
|||
background: rgb(220, 220, 220);
|
||||
}
|
||||
|
||||
@media (max-width: 1200px){
|
||||
@media (max-width: 1320px){
|
||||
.fPermissions, .fOwner {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
@ -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%;
|
||||
}
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
.crossed {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
.catchall-mail {
|
||||
text-transform: none;
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,27 +136,10 @@ 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 })} />
|
||||
</div>
|
||||
|
||||
<div className="c-2">
|
||||
<MailInfoBlock
|
||||
webMail={state.data.webmail}
|
||||
hostName={state.data.hostname}
|
||||
password={state.password}
|
||||
domain={props.domain} />
|
||||
</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}>
|
||||
<button type="button" onClick={toggleQuota}>
|
||||
<FontAwesomeIcon icon="infinity" />
|
||||
</button>
|
||||
</TextInputWithExtraButton>
|
||||
|
@ -184,8 +168,8 @@ export default function EditMailAccount(props) {
|
|||
title={i18n['Autoreply']}
|
||||
checked={autoreplyChecked}
|
||||
onChange={checked => setAutoreplyChecked(checked)}
|
||||
name="v_fwd_only"
|
||||
id="fwd_only" />
|
||||
name="v_autoreply"
|
||||
id="autoreply" />
|
||||
|
||||
{
|
||||
autoreplyChecked && (
|
||||
|
@ -206,6 +190,15 @@ export default function EditMailAccount(props) {
|
|||
id="credentials" />
|
||||
</div>
|
||||
|
||||
<div className="c-2">
|
||||
<MailInfoBlock
|
||||
webMail={state.data.webmail}
|
||||
hostName={state.data.hostname}
|
||||
password={state.password}
|
||||
domain={props.domain} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="buttons-wrapper">
|
||||
<button type="submit" className="add">{i18n.Add}</button>
|
||||
<button type="button" className="back" onClick={goBack}>{i18n.Back}</button>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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(() => {
|
||||
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 />
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,9 +109,20 @@ $textColor: #555;
|
|||
}
|
||||
|
||||
div.logo {
|
||||
width: 7rem;
|
||||
padding-left: 0;
|
||||
|
||||
a {
|
||||
div {
|
||||
padding: 0;
|
||||
width: 6rem;
|
||||
flex: none;
|
||||
|
||||
img {
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: transparent;
|
||||
|
@ -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;
|
||||
|
|
|
@ -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(() => {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 (
|
||||
<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>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ $black: #000;
|
|||
margin-top: 100px;
|
||||
|
||||
.modal-body {
|
||||
overflow-wrap: anywhere;
|
||||
font-size: 17px;
|
||||
margin-bottom: 40px;
|
||||
|
||||
input {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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 (
|
||||
|
|
|
@ -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)}> / {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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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}>
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -39,6 +39,7 @@ $textColor: #555;
|
|||
|
||||
span.stat.email{
|
||||
display: block;
|
||||
width: max-content;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,7 +29,8 @@ const AdditionalFtpForEditing = ({ domain, data = {}, onDeleteAdditionalFtp, pre
|
|||
return <></>;
|
||||
}
|
||||
|
||||
return (<div className="additional-ftp">
|
||||
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" />
|
||||
|
@ -58,7 +59,7 @@ const AdditionalFtpForEditing = ({ domain, data = {}, onDeleteAdditionalFtp, pre
|
|||
className="form-control"
|
||||
id={`ftp_user_${data.id}`}
|
||||
name={`v_ftp_user[${data.id}][v_ftp_user]`} />
|
||||
<span>{`${userName}_${state.username}`}</span>
|
||||
<span>{data.v_ftp_user ? data.v_ftp_user : `${userName}_${state.username}`}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -76,7 +77,7 @@ const AdditionalFtpForEditing = ({ domain, data = {}, onDeleteAdditionalFtp, pre
|
|||
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>
|
||||
<span className="path-note">{prePath}</span>
|
||||
</div>
|
||||
|
||||
{
|
||||
|
|
|
@ -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>)}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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}>
|
||||
|
|
|
@ -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 && (
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
align-items: center;
|
||||
|
||||
> div:nth-child(1) {
|
||||
width: 34%;
|
||||
margin-right: 2rem;
|
||||
}
|
||||
|
||||
.dns-name-span {
|
||||
|
|
|
@ -71,10 +71,6 @@ const App = () => {
|
|||
useEffect(() => {
|
||||
if (!Object.entries(session.i18n).length) {
|
||||
dispatch(checkAuthHandler()).then(token => {
|
||||
if (token) {
|
||||
setAuthToken(token);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -10,6 +10,10 @@ $hoverButtonText: #2c54ac;
|
|||
$activeButtonText: #fff;
|
||||
$textColor: #555;
|
||||
|
||||
html {
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.App {
|
||||
font-size: 25px;
|
||||
font-family: Arial;
|
||||
|
|
|
@ -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,6 +157,8 @@ const Backups = props => {
|
|||
}
|
||||
|
||||
const fetchData = () => {
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getBackupList()
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -165,11 +167,12 @@ const Backups = props => {
|
|||
backupFav: result.data.backup_fav,
|
||||
totalAmount: result.data.totalAmount,
|
||||
selection: [],
|
||||
toggledAll: false,
|
||||
loading: false
|
||||
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();
|
||||
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()}
|
||||
</div>
|
||||
{loading
|
||||
? <Spinner />
|
||||
: (<>
|
||||
{backups()}
|
||||
<div className="total">{state.totalAmount}</div>
|
||||
</>)}
|
||||
</div>
|
||||
<Modal
|
||||
onSave={modalConfirmHandler}
|
||||
onCancel={modalCancelHandler}
|
||||
|
|
|
@ -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} />} />
|
||||
|
|
|
@ -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,6 +164,8 @@ const CronJobs = props => {
|
|||
}
|
||||
|
||||
const fetchData = () => {
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getCronList()
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -173,11 +175,12 @@ const CronJobs = props => {
|
|||
cronFav: result.data.cron_fav,
|
||||
selection: [],
|
||||
toggledAll: false,
|
||||
totalAmount: result.data.totalAmount,
|
||||
loading: 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();
|
||||
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()}
|
||||
</div>
|
||||
{loading
|
||||
? <Spinner />
|
||||
: (<>
|
||||
{cronJobs()}
|
||||
<div className="total">{state.totalAmount}</div>
|
||||
</>)}
|
||||
</div>
|
||||
<Modal
|
||||
showCancelButton={modal.actionUrl}
|
||||
onCancel={modalCancelHandler}
|
||||
|
|
|
@ -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,9 +156,8 @@ export default function DnsRecords(props) {
|
|||
|
||||
const fetchData = () => {
|
||||
let parsedQueryString = QueryString.parse(history.location.search, { ignoreQueryPrefix: true });
|
||||
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getDNSRecordsList(parsedQueryString.domain || '')
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -168,11 +167,12 @@ export default function DnsRecords(props) {
|
|||
totalAmount: result.data.totalAmount,
|
||||
domain: parsedQueryString.domain,
|
||||
toggledAll: false,
|
||||
selection: [],
|
||||
loading: 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();
|
||||
fetchData().then(() => {
|
||||
refreshMenuCounters();
|
||||
toggleAll(false);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
|
@ -302,12 +305,25 @@ export default function DnsRecords(props) {
|
|||
}
|
||||
|
||||
const modalConfirmHandler = () => {
|
||||
handleAction(modal.actionUrl)
|
||||
.then(() => {
|
||||
fetchData();
|
||||
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 = () => {
|
||||
|
@ -334,7 +350,7 @@ export default function DnsRecords(props) {
|
|||
</div>
|
||||
</div>
|
||||
</Toolbar>
|
||||
{state.loading
|
||||
{loading
|
||||
? <Spinner />
|
||||
: (
|
||||
<>
|
||||
|
|
|
@ -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%;
|
||||
|
|
|
@ -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,6 +165,8 @@ const Databases = props => {
|
|||
}
|
||||
|
||||
const fetchData = () => {
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getDatabaseList()
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -175,11 +177,12 @@ const Databases = props => {
|
|||
dbFav: result.data.dbFav,
|
||||
selection: [],
|
||||
toggledAll: false,
|
||||
totalAmount: result.data.totalAmount,
|
||||
loading: 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();
|
||||
fetchData().then(() => {
|
||||
refreshMenuCounters();
|
||||
toggleAll(false);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
|
@ -345,13 +350,25 @@ const Databases = props => {
|
|||
}
|
||||
|
||||
const modalConfirmHandler = () => {
|
||||
setState({ ...state, loading: true });
|
||||
handleAction(modal.actionUrl)
|
||||
.then(() => {
|
||||
fetchData();
|
||||
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 = () => {
|
||||
|
@ -381,7 +398,7 @@ const Databases = props => {
|
|||
</div>
|
||||
</Toolbar>
|
||||
<div className="mails-wrapper">
|
||||
{state.loading
|
||||
{loading
|
||||
? <Spinner />
|
||||
: (<>
|
||||
{databases()}
|
||||
|
|
|
@ -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,8 +174,8 @@ const DomainNameSystems = props => {
|
|||
}
|
||||
|
||||
const fetchData = () => {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getDnsList()
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -184,11 +184,12 @@ const DomainNameSystems = props => {
|
|||
dnsFav: result.data.dnsFav,
|
||||
selection: [],
|
||||
toggledAll: false,
|
||||
totalAmount: result.data.totalAmount,
|
||||
loading: 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();
|
||||
fetchData().then(() => {
|
||||
refreshMenuCounters();
|
||||
toggleAll(false);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
|
@ -363,12 +366,25 @@ const DomainNameSystems = props => {
|
|||
}
|
||||
|
||||
const modalConfirmHandler = () => {
|
||||
handleAction(modal.actionUrl)
|
||||
.then(() => {
|
||||
fetchData();
|
||||
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 = () => {
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,8 +149,8 @@ const BanLists = props => {
|
|||
}
|
||||
|
||||
const fetchData = () => {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getBanList()
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -157,11 +158,12 @@ const BanLists = props => {
|
|||
banIps: reformatData(result.data.data),
|
||||
totalAmount: result.data.total_amount,
|
||||
toggledAll: false,
|
||||
selection: [],
|
||||
loading: 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();
|
||||
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()}
|
||||
|
|
|
@ -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,8 +165,8 @@ const Firewalls = props => {
|
|||
}
|
||||
|
||||
const fetchData = () => {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getFirewallList()
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -176,11 +176,12 @@ const Firewalls = props => {
|
|||
selection: [],
|
||||
firewallExtension: result.data.firewallExtension,
|
||||
totalAmount: result.data.totalAmount,
|
||||
toggledAll: false,
|
||||
loading: false
|
||||
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();
|
||||
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()}
|
||||
</div>
|
||||
{loading
|
||||
? <Spinner />
|
||||
: (<>
|
||||
{firewalls()}
|
||||
<div className="total">{state.totalAmount}</div>
|
||||
</>)}
|
||||
</div>
|
||||
<Modal
|
||||
onSave={modalConfirmHandler}
|
||||
onCancel={modalCancelHandler}
|
||||
|
|
|
@ -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,8 +154,8 @@ const InternetProtocols = props => {
|
|||
}
|
||||
|
||||
const fetchData = () => {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getIpList()
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -163,11 +164,12 @@ const InternetProtocols = props => {
|
|||
ipFav: result.data.ipFav,
|
||||
selection: [],
|
||||
totalAmount: result.data.totalAmount,
|
||||
toggledAll: false,
|
||||
loading: false
|
||||
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();
|
||||
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()}
|
||||
</div>
|
||||
{loading
|
||||
? <Spinner />
|
||||
: (<>
|
||||
{internetProtocols()}
|
||||
<div className="total">{state.totalAmount}</div>
|
||||
</>)}
|
||||
</div>
|
||||
<Modal
|
||||
onSave={modalConfirmHandler}
|
||||
onCancel={modalCancelHandler}
|
||||
|
|
|
@ -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 });
|
||||
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getMailAccountList(props.domain)
|
||||
.then(result => {
|
||||
setState({
|
||||
...state,
|
||||
mailAccounts: reformatData(result.data.data),
|
||||
webMail: result.data.webMail,
|
||||
webMail: result.data.webmail,
|
||||
selection: [],
|
||||
toggledAll: false,
|
||||
mailAccountsFav: result.data.mailAccountsFav,
|
||||
totalAmount: result.data.totalAmount,
|
||||
loading: false
|
||||
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();
|
||||
fetchData().then(() => {
|
||||
refreshMenuCounters();
|
||||
toggleAll(false);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
|
@ -340,12 +344,25 @@ export default function MailAccounts(props) {
|
|||
}
|
||||
|
||||
const modalConfirmHandler = () => {
|
||||
handleAction(modal.actionUrl)
|
||||
.then(() => {
|
||||
fetchData();
|
||||
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 = () => {
|
||||
|
@ -374,7 +391,7 @@ export default function MailAccounts(props) {
|
|||
</div>
|
||||
</div>
|
||||
</Toolbar>
|
||||
{state.loading
|
||||
{loading
|
||||
? <Spinner />
|
||||
: (
|
||||
<>
|
||||
|
|
|
@ -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%;
|
||||
|
|
|
@ -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,8 +175,8 @@ const Mails = props => {
|
|||
}
|
||||
|
||||
const fetchData = () => {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getMailList()
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -186,11 +186,12 @@ const Mails = props => {
|
|||
mailFav: result.data.mailFav,
|
||||
selection: [],
|
||||
toggledAll: false,
|
||||
totalAmount: result.data.totalAmount,
|
||||
loading: 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();
|
||||
fetchData().then(() => {
|
||||
refreshMenuCounters();
|
||||
toggleAll(false);
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
|
@ -354,12 +357,25 @@ const Mails = props => {
|
|||
}
|
||||
|
||||
const modalConfirmHandler = () => {
|
||||
handleAction(modal.actionUrl)
|
||||
.then(() => {
|
||||
fetchData();
|
||||
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 = () => {
|
||||
|
@ -389,7 +405,7 @@ const Mails = props => {
|
|||
</div>
|
||||
</Toolbar>
|
||||
<div className="mails-wrapper">
|
||||
{state.loading
|
||||
{loading
|
||||
? <Spinner />
|
||||
: (<>
|
||||
{mails()}
|
||||
|
|
|
@ -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,10 +150,12 @@ 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 = () => {
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getPackageList()
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -161,11 +164,12 @@ const Packages = props => {
|
|||
packagesFav: result.data.packagesFav,
|
||||
totalAmount: result.data.totalAmount,
|
||||
selection: [],
|
||||
toggledAll: false,
|
||||
loading: false
|
||||
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();
|
||||
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()}
|
||||
|
|
|
@ -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%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 });
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getSearchResultsList(searchTerm)
|
||||
.then(result => {
|
||||
setState({
|
||||
...state,
|
||||
searchResults: result.data.data,
|
||||
totalAmount: result.data.total_amount,
|
||||
loading: false
|
||||
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();
|
||||
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()}
|
||||
</div>
|
||||
{loading
|
||||
? <Spinner />
|
||||
: (<>
|
||||
{searchResults()}
|
||||
<div className="total">{state.totalAmount}</div>
|
||||
</>)}
|
||||
</div>
|
||||
<Modal
|
||||
onSave={modalConfirmHandler}
|
||||
onCancel={modalCancelHandler}
|
||||
|
|
|
@ -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 });
|
||||
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getServersList()
|
||||
.then(result => {
|
||||
setState({
|
||||
...state,
|
||||
selection: [],
|
||||
toggledAll: false,
|
||||
servers: reformatData(result.data.data, result.data.sys),
|
||||
loading: 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();
|
||||
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>
|
||||
|
|
|
@ -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%;
|
||||
}
|
||||
}
|
|
@ -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,8 +61,8 @@ const Users = props => {
|
|||
}, [controlPanelFocusedElement, focusedElement, state.users]);
|
||||
|
||||
const fetchData = () => {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getUsersList()
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -70,11 +71,12 @@ const Users = props => {
|
|||
userFav: result.data.userFav,
|
||||
totalAmount: result.data.totalAmount,
|
||||
toggledAll: false,
|
||||
selection: [],
|
||||
loading: 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();
|
||||
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()}
|
||||
|
|
|
@ -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,8 +168,8 @@ const Web = props => {
|
|||
}
|
||||
|
||||
const fetchData = () => {
|
||||
setState({ ...state, loading: true });
|
||||
|
||||
setLoading(true);
|
||||
return new Promise((resolve, reject) => {
|
||||
getWebList()
|
||||
.then(result => {
|
||||
setState({
|
||||
|
@ -178,11 +178,12 @@ const Web = props => {
|
|||
webFav: result.data.webFav,
|
||||
totalAmount: result.data.totalAmount,
|
||||
toggledAll: false,
|
||||
selection: [],
|
||||
loading: 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 />
|
||||
: (
|
||||
<>
|
||||
|
|
|
@ -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: "",
|
||||
|
|
19
web/js/react/src/reducers/MenuCounters/menuCounterReducer.js
Normal file
19
web/js/react/src/reducers/MenuCounters/menuCounterReducer.js
Normal 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;
|
|
@ -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) => {
|
||||
|
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue