From e66ec829f79e8006fcb57f6308a7d8bd54bcf6b3 Mon Sep 17 00:00:00 2001 From: Alexander Date: Sun, 31 Oct 2021 23:27:00 +0200 Subject: [PATCH] Improved new react ui and added view for CSR generation. --- src/react/src/ControlPanelService/Backup.js | 2 +- src/react/src/ControlPanelService/Web.js | 37 +- .../src/actions/Session/sessionActions.js | 51 ++- .../actions/UserSession/userSessionActions.js | 8 + .../actions/UserSession/userSessionTypes.js | 1 + .../Backup/Exclusion/Edit/index.jsx | 29 +- .../AddItemLayout/Form/TextArea/TextArea.jsx | 8 +- .../Form/TextInput/TextInput.jsx | 3 +- .../components/CronJob/Edit/EditCronJob.jsx | 63 ++-- .../DNSRecord/Edit/EditDNSRecord.jsx | 48 +-- .../components/Database/Edit/EditDatabase.jsx | 51 +-- .../Edit/EditDomainNameSystem.jsx | 50 +-- .../components/Firewall/Edit/EditFirewall.jsx | 60 +-- .../Add/AddInternetProtocol.jsx | 5 +- .../Edit/EditInternetProtocol.jsx | 51 +-- src/react/src/components/Login/Login.scss | 1 - .../src/components/Mail/Edit/EditMail.jsx | 49 +-- .../MailAccount/Add/AddMailAccount.jsx | 3 + .../MailAccount/Edit/EditMailAccount.jsx | 27 +- .../MailInfoBlock/MailInfoBlock.jsx | 6 +- src/react/src/components/MainNav/MainNav.jsx | 16 +- .../src/components/MainNav/Panel/Panel.jsx | 19 +- .../src/components/MainNav/Stat-menu/Menu.jsx | 3 +- .../DropdownFilter/DropdownFilter.scss | 1 - src/react/src/components/Menu/Menu.jsx | 6 +- .../components/Package/Edit/EditPackage.jsx | 49 +-- .../components/Path/Dropdown/Dropdown.scss | 1 - .../src/components/Preview/Photo/Photo.scss | 1 - src/react/src/components/Preview/Preview.jsx | 4 +- .../components/Server/Edit/Bind9/Bind9.jsx | 38 +- .../Server/Edit/Dovecot/Dovecot.jsx | 32 +- .../src/components/Server/Edit/EditServer.jsx | 39 +- .../Server/Edit/EditServerDnsOption.jsx | 2 +- .../Server/Edit/EditVestaPlugins.jsx | 354 ++++++++---------- .../Server/Edit/Httpd/EditHttpd.jsx | 27 +- .../components/Server/Edit/Mysql/Mysql.jsx | 65 ++-- .../Server/Edit/Nginx/EditServerNginx.jsx | 55 ++- .../components/Server/Edit/PHP/EditPhp.jsx | 53 ++- .../Server/Edit/Postgresql/Postgresql.jsx | 38 +- .../Server/Edit/Service/Service.jsx | 33 +- src/react/src/components/Server/ServerSys.jsx | 4 +- src/react/src/components/User/Add/AddUser.jsx | 3 +- .../src/components/User/Edit/EditUser.jsx | 53 +-- src/react/src/components/User/User.jsx | 3 +- .../components/WebDomain/Add/AddWebDomain.jsx | 105 ++++-- .../Add/AdvancedOptions/AdvancedOptions.jsx | 54 +-- .../src/components/WebDomain/Edit/EditWeb.jsx | 117 +++--- .../WebDomain/Edit/SslSupport/SslSupport.scss | 1 + .../src/components/WebDomain/WebDomain.jsx | 47 ++- .../ControlPanelContent.jsx | 18 +- .../src/containers/FileManager/FileManager.js | 4 +- .../src/containers/GenerateCSR/index.jsx | 165 ++++++++ src/react/src/containers/Mails/Mails.jsx | 13 +- src/react/src/containers/Servers/Servers.jsx | 5 +- src/react/src/containers/Users/Users.jsx | 22 +- .../src/reducers/Session/sessionReducer.js | 5 - .../UserSession/userSessionReducer.js | 19 + src/react/src/reducers/rootReducer.js | 2 + 58 files changed, 1246 insertions(+), 783 deletions(-) create mode 100644 src/react/src/actions/UserSession/userSessionActions.js create mode 100644 src/react/src/actions/UserSession/userSessionTypes.js create mode 100644 src/react/src/containers/GenerateCSR/index.jsx create mode 100644 src/react/src/reducers/UserSession/userSessionReducer.js diff --git a/src/react/src/ControlPanelService/Backup.js b/src/react/src/ControlPanelService/Backup.js index 92ee7654f..b2f432b5f 100644 --- a/src/react/src/ControlPanelService/Backup.js +++ b/src/react/src/ControlPanelService/Backup.js @@ -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 = '/api/v1/schedule/restore/'; +const scheduleBackupUri = '/api/v1/schedule/backup/'; 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'; diff --git a/src/react/src/ControlPanelService/Web.js b/src/react/src/ControlPanelService/Web.js index 633881d5b..19361fd0e 100644 --- a/src/react/src/ControlPanelService/Web.js +++ b/src/react/src/ControlPanelService/Web.js @@ -6,6 +6,7 @@ const addWebUri = '/api/v1/add/web/index.php'; const webApiUri = '/api/v1/list/web/index.php'; const webStatsUri = '/api/v1/web-stats.php'; const domainInfoUri = '/api/v1/edit/web/index.php'; +const generateCSRUri = '/api/v1/generate/ssl/index.php'; const updateDomainUri = '/api/v1/edit/web/index.php'; export const getWebList = () => { @@ -42,6 +43,14 @@ export const addWeb = data => { return axios.post(BASE_URL + addWebUri, formDataObject); } +export const getWebDomainInfo = domain => { + return axios.get(BASE_URL + addWebUri, { + params: { + token: getAuthToken() + } + }); +} + export const getWebStats = () => { return axios.get(BASE_URL + webStatsUri); } @@ -68,4 +77,30 @@ export const updateWebDomain = (data, domain) => { token: getAuthToken() } }); -} \ No newline at end of file +} + +export const getCsrInitialData = domain => { + if (domain) { + return axios.get(BASE_URL + generateCSRUri, { + params: { + domain + } + }); + } else { + return axios.get(BASE_URL + generateCSRUri); + } +} + +export const generateCSR = (data) => { + let formDataObject = new FormData(); + + for (let key in data) { + formDataObject.append(key, data[key]); + } + + return axios.post(BASE_URL + generateCSRUri, formDataObject, { + params: { + token: getAuthToken() + } + }); +} diff --git a/src/react/src/actions/Session/sessionActions.js b/src/react/src/actions/Session/sessionActions.js index b1cd92651..c28a30e49 100644 --- a/src/react/src/actions/Session/sessionActions.js +++ b/src/react/src/actions/Session/sessionActions.js @@ -3,6 +3,7 @@ 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'; +import { SET_USER_SESSION } from '../UserSession/userSessionTypes'; const LOGOUT_RESPONSE = 'logged_out'; const LOGOUT_AS_RESPONSE = 'logged_out_as'; @@ -19,7 +20,6 @@ export const login = (user, password) => dispatch => { value: { token: token || '', panel, - session, i18n: i18n || {}, userName: user, error @@ -31,6 +31,10 @@ export const login = (user, password) => dispatch => { user: data, } }); + dispatch({ + type: SET_USER_SESSION, + value: session + }); resolve(token); }, (error) => { reject(error); @@ -48,7 +52,6 @@ export const reset = ({ user = '', code = '', password = '', password_confirm = value: { token, panel, - session, userName: user, error }, @@ -59,6 +62,10 @@ export const reset = ({ user = '', code = '', password = '', password_confirm = user: {}, } }); + dispatch({ + type: SET_USER_SESSION, + value: session + }); resolve(token); }, (error) => { reject(error); @@ -77,7 +84,6 @@ export const loginAs = username => dispatch => { value: { userName: user, i18n, - session, panel, token, error @@ -89,6 +95,10 @@ export const loginAs = username => dispatch => { user: data, } }); + dispatch({ + type: SET_USER_SESSION, + value: session + }); resolve(token); }, (error) => { @@ -123,6 +133,10 @@ export const logout = () => (dispatch, getState) => { user: {}, } }); + dispatch({ + type: SET_USER_SESSION, + value: {} + }); resolve(); } else if (logout_response === LOGOUT_AS_RESPONSE) { @@ -130,7 +144,6 @@ export const logout = () => (dispatch, getState) => { type: LOGGED_OUT_AS, value: { userName, - session, panel, token: '', i18n, @@ -143,6 +156,10 @@ export const logout = () => (dispatch, getState) => { user, } }); + dispatch({ + type: SET_USER_SESSION, + value: session + }); resolve(); } else { @@ -168,7 +185,6 @@ export const checkAuthHandler = () => (dispatch, getState) => { value: { userName: user, i18n, - session, panel, token, error @@ -180,6 +196,31 @@ export const checkAuthHandler = () => (dispatch, getState) => { user: data, } }); + dispatch({ + type: SET_USER_SESSION, + value: session + }); + + resolve(token); + }) + .catch(err => { + reject(); + console.error(err); + }); + }); +} + +export const refreshUserSession = () => (dispatch, getState) => { + return new Promise((resolve, reject) => { + checkAuth() + .then(res => { + const { session, token } = res.data; + + if (token) setAuthToken(token); + dispatch({ + type: SET_USER_SESSION, + value: session + }); resolve(token); }) diff --git a/src/react/src/actions/UserSession/userSessionActions.js b/src/react/src/actions/UserSession/userSessionActions.js new file mode 100644 index 000000000..a59b04773 --- /dev/null +++ b/src/react/src/actions/UserSession/userSessionActions.js @@ -0,0 +1,8 @@ +import { SET_USER_SESSION } from './userSessionTypes'; + +export const setUserSession = value => { + return { + type: SET_USER_SESSION, + value + }; +}; diff --git a/src/react/src/actions/UserSession/userSessionTypes.js b/src/react/src/actions/UserSession/userSessionTypes.js new file mode 100644 index 000000000..56d1b41f5 --- /dev/null +++ b/src/react/src/actions/UserSession/userSessionTypes.js @@ -0,0 +1 @@ +export const SET_USER_SESSION = 'SET_USER_SESSION'; \ No newline at end of file diff --git a/src/react/src/components/Backup/Exclusion/Edit/index.jsx b/src/react/src/components/Backup/Exclusion/Edit/index.jsx index 9b2d7e970..ffc3ad1f4 100644 --- a/src/react/src/components/Backup/Exclusion/Edit/index.jsx +++ b/src/react/src/components/Backup/Exclusion/Edit/index.jsx @@ -18,11 +18,11 @@ const EditBackupExclusions = () => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, - loading: false, - errorMessage: '', - okMessage: '' + loading: false }); useEffect(() => { @@ -30,19 +30,20 @@ const EditBackupExclusions = () => { dispatch(removeFocusedElement()); setState({ ...state, loading: true }); + fetchData(); + }, []); + const fetchData = () => { getBackupExclusionsInfo() .then(response => { setState({ ...state, data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], loading: false }); }) .catch(err => console.error(err)); - }, []); + } const submitFormHandler = event => { event.preventDefault(); @@ -61,17 +62,13 @@ const EditBackupExclusions = () => { updateBackupExclusions(updatedExclusions) .then(result => { if (result.status === 200) { - const { error_msg: errorMessage, ok_msg: okMessage } = result.data; + const { error_msg, ok_msg } = result.data; - if (errorMessage) { - setState({ ...state, errorMessage, okMessage: '', loading: false }); - } else if (okMessage) { - setState({ ...state, errorMessage: '', okMessage, loading: false }); - } else { - setState({ ...state, loading: false }); - } + setErrorMessage(error_msg || ''); + setOkMessage(ok_msg || ''); } }) + .then(() => fetchData()) .catch(err => console.error(err)); } } @@ -86,12 +83,12 @@ const EditBackupExclusions = () => {
{i18n['Editing Backup Exclusions']}
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/ControlPanel/AddItemLayout/Form/TextArea/TextArea.jsx b/src/react/src/components/ControlPanel/AddItemLayout/Form/TextArea/TextArea.jsx index f440497f1..39a0fefae 100644 --- a/src/react/src/components/ControlPanel/AddItemLayout/Form/TextArea/TextArea.jsx +++ b/src/react/src/components/ControlPanel/AddItemLayout/Form/TextArea/TextArea.jsx @@ -1,6 +1,6 @@ import React from 'react'; -const TextArea = ({ id, name, defaultValue = '', title, optionalTitle = '', rows = '3', disabled = false }) => { +const TextArea = ({ id, name, defaultValue = '', title, optionalTitle = '', rows = '3', disabled = false, ...rest }) => { return (
); } -export default TextArea; \ No newline at end of file +export default TextArea; diff --git a/src/react/src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput.jsx b/src/react/src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput.jsx index 843eb4ffc..21cd61350 100644 --- a/src/react/src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput.jsx +++ b/src/react/src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput.jsx @@ -25,7 +25,6 @@ const TextInput = ({ id, name, title, optionalTitle = '', type = 'text', onChang name={name} id={id} onChange={changeCheckbox} - // disabled={disabled} readOnly={disabled} value={inputValue} className="form-control" /> @@ -33,4 +32,4 @@ const TextInput = ({ id, name, title, optionalTitle = '', type = 'text', onChang ); } -export default TextInput; \ No newline at end of file +export default TextInput; diff --git a/src/react/src/components/CronJob/Edit/EditCronJob.jsx b/src/react/src/components/CronJob/Edit/EditCronJob.jsx index 4c081c26a..87ba1fed9 100644 --- a/src/react/src/components/CronJob/Edit/EditCronJob.jsx +++ b/src/react/src/components/CronJob/Edit/EditCronJob.jsx @@ -21,10 +21,10 @@ const EditMail = props => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, - errorMessage: '', - okMessage: '', loading: false, generatedCronJob: { h_min: '*', @@ -44,29 +44,33 @@ const EditMail = props => { if (job) { setState({ ...state, loading: true }); - - getCronJobInfo(job) - .then(response => { - setState({ - ...state, - generatedCronJob: { - ...state.generatedCronJob, - h_min: response.data.min, - h_hour: response.data.hour, - h_day: response.data.day, - h_wday: response.data.wday, - h_month: response.data.month - }, - data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], - loading: false - }); - }) - .catch(err => console.error(err)); + fetchData(job) } }, []); + const fetchData = job => { + getCronJobInfo(job) + .then(response => { + setState({ + ...state, + generatedCronJob: { + ...state.generatedCronJob, + h_min: response.data.min, + h_hour: response.data.hour, + h_day: response.data.day, + h_wday: response.data.wday, + h_month: response.data.month + }, + data: response.data, + loading: false + }); + }) + .catch(err => { + setState({ ...state, loading: false }); + console.error(err); + }); + } + const submitFormHandler = event => { event.preventDefault(); let updatedJob = {}; @@ -81,17 +85,20 @@ const EditMail = props => { updateCronJob(updatedJob, state.data.job) .then(result => { if (result.status === 200) { - const { error_msg: errorMessage, ok_msg: okMessage } = result.data; + const { error_msg, ok_msg } = result.data; - if (errorMessage) { - setState({ ...state, errorMessage, okMessage, loading: false }); + if (error_msg) { + setOkMessage(''); + setErrorMessage(error_msg); } else { dispatch(refreshCounters()).then(() => { - setState({ ...state, okMessage, errorMessage: '', loading: false }); + setOkMessage(ok_msg); + setErrorMessage(''); }); } } }) + .then(() => fetchData(state.data.job)) .catch(err => console.error(err)); } } @@ -125,12 +132,12 @@ const EditMail = props => {
{i18n['Editing Cron Job']}
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/DNSRecord/Edit/EditDNSRecord.jsx b/src/react/src/components/DNSRecord/Edit/EditDNSRecord.jsx index 114ba65d7..0df612db9 100644 --- a/src/react/src/components/DNSRecord/Edit/EditDNSRecord.jsx +++ b/src/react/src/components/DNSRecord/Edit/EditDNSRecord.jsx @@ -19,6 +19,8 @@ export default function EditDNSRecord(props) { const { i18n } = useSelector(state => state.session); const dispatch = useDispatch(); const history = useHistory(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, selectOptions: [ @@ -37,9 +39,7 @@ export default function EditDNSRecord(props) { 'TLSA', 'CAA' ], - loading: false, - errorMessage: '', - okMessage: '' + loading: false }); useEffect(() => { @@ -48,23 +48,24 @@ export default function EditDNSRecord(props) { dispatch(addActiveElement('/list/dns/')); dispatch(removeFocusedElement()); - if (domain) { + if (domain && record_id) { setState({ ...state, loading: true }); - - getDNSRecordInfo(domain, record_id) - .then(response => { - setState({ - ...state, - data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], - loading: false - }); - }) - .catch(err => console.error(err)); + fetchData(domain, record_id); } }, []); + const fetchData = (domain, record_id) => { + getDNSRecordInfo(domain, record_id) + .then(response => { + setState({ + ...state, + data: response.data, + loading: false + }); + }) + .catch(err => console.error(err)); + } + const submitFormHandler = event => { event.preventDefault(); let updatedRecord = {}; @@ -83,17 +84,20 @@ export default function EditDNSRecord(props) { updateDNS(updatedRecord, props.domain, props.record_id) .then(result => { if (result.status === 200) { - const { error_msg: errorMessage, ok_msg: okMessage } = result.data; + const { error_msg, ok_msg } = result.data; - if (errorMessage) { - setState({ ...state, errorMessage, okMessage, loading: false }); + if (error_msg) { + setOkMessage(''); + setErrorMessage(error_msg); } else { dispatch(refreshCounters()).then(() => { - setState({ ...state, okMessage, errorMessage: '', loading: false }); + setOkMessage(ok_msg); + setErrorMessage(''); }); } } }) + .then(() => fetchData(props.domain, props.record_id)) .catch(err => console.error(err)); } } @@ -108,12 +112,12 @@ export default function EditDNSRecord(props) {
{i18n['Editing DNS Record']}
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/Database/Edit/EditDatabase.jsx b/src/react/src/components/Database/Edit/EditDatabase.jsx index e1babafd5..1a8499574 100644 --- a/src/react/src/components/Database/Edit/EditDatabase.jsx +++ b/src/react/src/components/Database/Edit/EditDatabase.jsx @@ -22,12 +22,12 @@ const EditDatabase = props => { const { i18n, userName } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, loading: false, - databaseUserInputValue: '', - errorMessage: '', - okMessage: '' + databaseUserInputValue: '' }); useEffect(() => { @@ -39,22 +39,26 @@ const EditDatabase = props => { if (database) { setState({ ...state, loading: true }); - - getDatabaseInfo(database) - .then(response => { - 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 - }); - }) - .catch(err => console.error(err)); + fetchData(database); } }, []); + const fetchData = database => { + getDatabaseInfo(database) + .then(response => { + setState({ + ...state, + data: response.data, + databaseUserInputValue: response.data.dbuser.split('_').splice(1).join('_'), + loading: false + }); + }) + .catch(err => { + setState({ ...state, loading: false }); + console.error(err); + }); + } + const submitFormHandler = event => { event.preventDefault(); let updatedDatabase = {}; @@ -72,17 +76,20 @@ const EditDatabase = props => { updateDatabase(updatedDatabase, state.data.database) .then(result => { if (result.status === 200) { - const { error_msg: errorMessage, ok_msg: okMessage } = result.data; + const { error_msg, ok_msg } = result.data; - if (errorMessage) { - setState({ ...state, errorMessage, okMessage, loading: false }); + if (error_msg) { + setOkMessage(''); + setErrorMessage(error_msg); } else { dispatch(refreshCounters()).then(() => { - setState({ ...state, okMessage, errorMessage: '', loading: false }); + setOkMessage(ok_msg); + setErrorMessage(''); }); } } }) + .then(() => fetchData(state.data.database)) .catch(err => console.error(err)); } } @@ -101,12 +108,12 @@ const EditDatabase = props => {
{i18n['Editing Database']}
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/DomainNameSystem/Edit/EditDomainNameSystem.jsx b/src/react/src/components/DomainNameSystem/Edit/EditDomainNameSystem.jsx index 3a957a84c..1a4e79006 100644 --- a/src/react/src/components/DomainNameSystem/Edit/EditDomainNameSystem.jsx +++ b/src/react/src/components/DomainNameSystem/Edit/EditDomainNameSystem.jsx @@ -13,7 +13,6 @@ import QS from 'qs'; import './EditDomainNameSystem.scss'; import { Helmet } from 'react-helmet'; -import { andler } from 'src/actions/Session/sessionActions'; import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions'; import HtmlParser from 'react-html-parser'; @@ -22,11 +21,11 @@ const EditDomainNameSystem = props => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, - loading: false, - errorMessage: '', - okMessage: '' + loading: false }); useEffect(() => { @@ -38,21 +37,25 @@ const EditDomainNameSystem = props => { if (domain) { setState({ ...state, loading: true }); - - getDNSInfo(domain) - .then(response => { - setState({ - ...state, - data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], - loading: false - }); - }) - .catch(err => console.error(err)); + fetchData(domain); } }, []); + const fetchData = domain => { + getDNSInfo(domain) + .then(response => { + setState({ + ...state, + data: response.data, + loading: false + }); + }) + .catch(err => { + setState({ ...state, loading: false }); + console.error(err) + }); + } + const submitFormHandler = event => { event.preventDefault(); let updatedDomain = {}; @@ -69,17 +72,20 @@ const EditDomainNameSystem = props => { updateDNS(updatedDomain, state.data.domain) .then(result => { if (result.status === 200) { - const { error_msg: errorMessage, ok_msg: okMessage } = result.data; + const { error_msg, ok_msg } = result.data; - if (errorMessage) { - setState({ ...state, errorMessage, okMessage, loading: false }); + if (error_msg) { + setErrorMessage(error_msg); + setOkMessage(''); } else { dispatch(refreshCounters()).then(() => { - setState({ ...state, okMessage, errorMessage: '', loading: false }); + setErrorMessage(''); + setOkMessage(ok_msg); }); } } }) + .then(() => fetchData(state.data.domain)) .catch(err => console.error(err)); } } @@ -94,12 +100,12 @@ const EditDomainNameSystem = props => {
{i18n['Editing DNS Domain']}
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/Firewall/Edit/EditFirewall.jsx b/src/react/src/components/Firewall/Edit/EditFirewall.jsx index 207060aa3..1f64606a3 100644 --- a/src/react/src/components/Firewall/Edit/EditFirewall.jsx +++ b/src/react/src/components/Firewall/Edit/EditFirewall.jsx @@ -20,11 +20,11 @@ const EditFirewall = props => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, - loading: false, - errorMessage: '', - okMessage: '' + loading: false }); useEffect(() => { @@ -35,24 +35,24 @@ const EditFirewall = props => { dispatch(removeFocusedElement()); if (rule) { + setState({ ...state, loading: true }); fetchData(rule); } }, []); const fetchData = rule => { - setState({ ...state, loading: true }); - getFirewallInfo(rule) .then(response => { setState({ ...state, data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], loading: false }); }) - .catch(err => console.error(err)); + .catch(err => { + setState({ ...state, loading: false }); + console.error(err); + }); } const submitFormHandler = event => { @@ -69,13 +69,10 @@ const EditFirewall = props => { updateFirewall(updatedDomain, state.data.rule) .then(result => { if (result.status === 200) { - const { error_msg: errorMessage, ok_msg: okMessage } = result.data; + const { error_msg, ok_msg } = result.data; - if (errorMessage) { - setState({ ...state, errorMessage, okMessage, loading: false }); - } else { - setState({ ...state, okMessage, errorMessage: '', loading: false }); - } + setErrorMessage(error_msg || ''); + setOkMessage(ok_msg || ''); } }) .then(() => fetchData(state.data.rule)) @@ -93,12 +90,12 @@ const EditFirewall = props => {
{i18n['Editing Firewall Rule']}
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
@@ -108,19 +105,26 @@ const EditFirewall = props => { - +
+ + +
- +
+ + +
{ const token = localStorage.getItem("token"); - const { i18n } = useSelector(state => state.session); - const session = useSelector(state => state.session); + const { i18n, userName } = useSelector(state => state.session); const dispatch = useDispatch(); const history = useHistory(); const [state, setState] = useState({ @@ -105,7 +104,7 @@ const AddInternetProtocol = props => { {state.loading ? : (
submitFormHandler(event)}> - + diff --git a/src/react/src/components/InternetProtocol/Edit/EditInternetProtocol.jsx b/src/react/src/components/InternetProtocol/Edit/EditInternetProtocol.jsx index d65557cc7..1f0148397 100644 --- a/src/react/src/components/InternetProtocol/Edit/EditInternetProtocol.jsx +++ b/src/react/src/components/InternetProtocol/Edit/EditInternetProtocol.jsx @@ -23,12 +23,12 @@ const EditInternetProtocol = () => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, loading: false, - dedicated: false, - errorMessage: '', - okMessage: '' + dedicated: false }); useEffect(() => { @@ -40,22 +40,26 @@ const EditInternetProtocol = () => { if (ip) { setState({ ...state, loading: true }); - - getInternetProtocolInfo(ip) - .then(response => { - setState({ - ...state, - data: response.data, - dedicated: !response.data.dedicated, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], - loading: false - }); - }) - .catch(err => console.error(err)); + fetchData(ip); } }, []); + const fetchData = ip => { + getInternetProtocolInfo(ip) + .then(response => { + setState({ + ...state, + data: response.data, + dedicated: !response.data.dedicated, + loading: false + }); + }) + .catch(err => { + setState({ ...state, loading: false }); + console.error(err) + }); + } + const submitFormHandler = event => { event.preventDefault(); let updatedIP = {}; @@ -74,17 +78,20 @@ const EditInternetProtocol = () => { updateInternetProtocol(updatedIP, state.data.ip) .then(result => { if (result.status === 200) { - const { error_msg: errorMessage, ok_msg: okMessage } = result.data; + const { error_msg, ok_msg } = result.data; - if (errorMessage) { - setState({ ...state, errorMessage, okMessage, loading: false }); + if (error_msg) { + setErrorMessage(error_msg); + setOkMessage(''); } else { dispatch(refreshCounters()).then(() => { - setState({ ...state, okMessage, errorMessage: '', loading: false }); + setErrorMessage(''); + setOkMessage(ok_msg); }); } } }) + .then(() => fetchData(state.data.ip)) .catch(err => console.error(err)); } } @@ -103,12 +110,12 @@ const EditInternetProtocol = () => {
{i18n['Editing IP Address']}
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/Login/Login.scss b/src/react/src/components/Login/Login.scss index e51485ca7..2a67a6f1e 100644 --- a/src/react/src/components/Login/Login.scss +++ b/src/react/src/components/Login/Login.scss @@ -79,7 +79,6 @@ $textColor: #555; border: 1px solid $primary; padding: 1px 16px 3px; font-size: 13px;; - width: 100px; height: 35px; color: #fafafa; border-radius: 3px; diff --git a/src/react/src/components/Mail/Edit/EditMail.jsx b/src/react/src/components/Mail/Edit/EditMail.jsx index 9a3181cdd..13b801809 100644 --- a/src/react/src/components/Mail/Edit/EditMail.jsx +++ b/src/react/src/components/Mail/Edit/EditMail.jsx @@ -21,11 +21,11 @@ const EditMail = props => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, - loading: false, - errorMessage: '', - okMessage: '' + loading: false }); useEffect(() => { @@ -37,21 +37,25 @@ const EditMail = props => { if (domain) { setState({ ...state, loading: true }); - - getMailInfo(domain) - .then(response => { - setState({ - ...state, - data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], - loading: false - }); - }) - .catch(err => console.error(err)); + fetchData(domain); } }, []); + const fetchData = domain => { + getMailInfo(domain) + .then(response => { + setState({ + ...state, + data: response.data, + loading: false + }); + }) + .catch(err => { + setState({ ...state, loading: false }); + console.error(err); + }); + } + const submitFormHandler = event => { event.preventDefault(); let updatedDomain = {}; @@ -68,17 +72,20 @@ const EditMail = props => { updateMail(updatedDomain, state.data.domain) .then(result => { if (result.status === 200) { - const { error_msg: errorMessage, ok_msg: okMessage } = result.data; + const { error_msg, ok_msg } = result.data; - if (errorMessage) { - setState({ ...state, errorMessage, okMessage, loading: false }); + if (error_msg) { + setErrorMessage(error_msg); + setOkMessage(''); } else { dispatch(refreshCounters()).then(() => { - setState({ ...state, okMessage, errorMessage: '', loading: false }); + setErrorMessage(''); + setOkMessage(ok_msg); }); } } }) + .then(() => fetchData(state.data.domain)) .catch(err => console.error(err)); } } @@ -93,12 +100,12 @@ const EditMail = props => {
{i18n['Editing Mail Domain']}
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/MailAccount/Add/AddMailAccount.jsx b/src/react/src/components/MailAccount/Add/AddMailAccount.jsx index 1edadacae..af353d478 100644 --- a/src/react/src/components/MailAccount/Add/AddMailAccount.jsx +++ b/src/react/src/components/MailAccount/Add/AddMailAccount.jsx @@ -32,6 +32,7 @@ export default function AddMailAccount(props) { quotaValue: '', loading: false, password: '', + userName: '', okMessage: '', errorMessage: '', }); @@ -138,6 +139,7 @@ export default function AddMailAccount(props) { setState({ ...state, username: e.target.value })} name="v_account" id="account" /> @@ -148,6 +150,7 @@ export default function AddMailAccount(props) { diff --git a/src/react/src/components/MailAccount/Edit/EditMailAccount.jsx b/src/react/src/components/MailAccount/Edit/EditMailAccount.jsx index 8ba0e35c4..0457af439 100644 --- a/src/react/src/components/MailAccount/Edit/EditMailAccount.jsx +++ b/src/react/src/components/MailAccount/Edit/EditMailAccount.jsx @@ -24,13 +24,13 @@ export default function EditMailAccount(props) { const { i18n } = useSelector(state => state.session); const dispatch = useDispatch(); const history = useHistory(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, quotaValue: '', loading: false, - password: '', - okMessage: '', - errorMessage: '', + password: '' }); useEffect(() => { @@ -58,13 +58,15 @@ export default function EditMailAccount(props) { editMailAccount(newMailDomain, props.domain, props.account) .then(result => { if (result.status === 200) { - const { error_msg: errorMessage, ok_msg: okMessage } = result.data; + const { error_msg, ok_msg } = result.data; - if (errorMessage) { - setState({ ...state, errorMessage, okMessage, loading: false }); + if (error_msg) { + setErrorMessage(error_msg); + setOkMessage(''); } else { dispatch(refreshCounters()).then(() => { - setState({ ...state, okMessage, errorMessage: '', loading: false }); + setErrorMessage(''); + setOkMessage(ok_msg); }); } } @@ -81,8 +83,6 @@ export default function EditMailAccount(props) { setState({ ...state, data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], loading: false }); @@ -110,13 +110,13 @@ export default function EditMailAccount(props) {
{i18n['Editing Mail Account']}
- {state.errorMessage ? : ''} - {state.errorMessage} + {errorMessage ? : ''} + {errorMessage}
- {state.okMessage ? : ''} - {HtmlParser(state.okMessage)} + {okMessage ? : ''} + {HtmlParser(okMessage)}
@@ -193,6 +193,7 @@ export default function EditMailAccount(props) { diff --git a/src/react/src/components/MailAccount/MailInfoBlock/MailInfoBlock.jsx b/src/react/src/components/MailAccount/MailInfoBlock/MailInfoBlock.jsx index 57a6bebb1..dfdb2a0bf 100644 --- a/src/react/src/components/MailAccount/MailInfoBlock/MailInfoBlock.jsx +++ b/src/react/src/components/MailAccount/MailInfoBlock/MailInfoBlock.jsx @@ -1,13 +1,13 @@ import React, { useEffect, useState } from 'react'; import { useSelector } from 'react-redux'; +import { Link } from 'react-router-dom'; import { mailInfoBlockSelectOptions } from 'src/ControlPanelService/Mail'; import './MailInfoBlock.scss'; -export default function MailInfoBlock({ webMail, hostName, domain, password }) { +export default function MailInfoBlock({ webMail, hostName, domain, userName = '', password }) { const { i18n } = useSelector(state => state.session); const [selectedOption, setSelectedOption] = useState(''); - const { userName } = useSelector(state => state.session); const [state, setState] = useState({ imapHostName: hostName, smtpHostName: hostName, @@ -106,7 +106,7 @@ export default function MailInfoBlock({ webMail, hostName, domain, password }) {
{i18n['Webmail URL']}: - {webMail} + {webMail}
diff --git a/src/react/src/components/MainNav/MainNav.jsx b/src/react/src/components/MainNav/MainNav.jsx index 5c36f18f4..9d0e81171 100644 --- a/src/react/src/components/MainNav/MainNav.jsx +++ b/src/react/src/components/MainNav/MainNav.jsx @@ -18,7 +18,8 @@ const MainNav = () => { showTopNav: false }); - const { userName, session: { look } } = useSelector(state => state.session); + const { userName } = useSelector(state => state.session); + const { session: { look } } = useSelector(state => state.userSession); const { user } = useSelector(state => state.menuCounters); const { activeElement, focusedElement, adminMenuTabs, userMenuTabs } = useSelector(state => state.mainNavigation); const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent); @@ -29,11 +30,22 @@ const MainNav = () => { return history.push('/login'); } + if (look) { + const commonUserRoutes = ['package', 'ip', 'rrd', 'updates', 'firewall', 'server']; + const splitPath = history.location.pathname.split('/')[2]; + + if (history.location.pathname === '/add/user/') return history.push('/'); + + if (commonUserRoutes.includes(splitPath)) { + return history.push('/'); + } + } + const tabs = look ? userMenuTabs : adminMenuTabs; setState({ ...state, tabs }); setLoading(false); - }, [userName, user, history]); + }, [userName, user, history, look]); const controlFocusedTabWithCallback = useCallback(event => { let isSearchInputFocused = document.querySelector('input:focus') || document.querySelector('textarea:focus') || document.querySelector('textarea:focus'); diff --git a/src/react/src/components/MainNav/Panel/Panel.jsx b/src/react/src/components/MainNav/Panel/Panel.jsx index d838d2cec..a33a39d24 100644 --- a/src/react/src/components/MainNav/Panel/Panel.jsx +++ b/src/react/src/components/MainNav/Panel/Panel.jsx @@ -5,15 +5,14 @@ import { logout } from 'src/actions/Session/sessionActions'; import Notifications from './Notifications/Notifications'; import { useSelector, useDispatch } from "react-redux"; import Spinner from 'src/components/Spinner/Spinner'; -import { Link, useHistory } from "react-router-dom"; +import { Link } from "react-router-dom"; import './Panel.scss'; const Panel = props => { - const { i18n, userName, session: { look, user } } = useSelector(state => state.session); - const session = useSelector(state => state.session); + const { i18n, userName } = useSelector(state => state.session); + const { session: { look, user, FIREWALL_SYSTEM, FILEMANAGER_KEY, SOFTACULOUS } } = useSelector(state => state.userSession); const { activeElement, focusedElement } = useSelector(state => state.mainNavigation); const dispatch = useDispatch(); - const history = useHistory(); const [loading, setLoading] = useState(false); const [state, setState] = useState({ smallNavigationClass: 'small-navigation hidden' @@ -98,14 +97,14 @@ const Panel = props => {
handleState("/list/updates/", event)} onKeyPress={event => event.preventDefault()}>{i18n.Updates}
- {session.session.FIREWALL_SYSTEM &&
+ {FIREWALL_SYSTEM &&
handleState("/list/firewall/", event)} onKeyPress={event => event.preventDefault()}>{i18n.Firewall}
} )} - {session.session.FILEMANAGER_KEY &&
+ {FILEMANAGER_KEY &&
{i18n['File Manager']}
} - {session.session.SOFTACULOUS === "yes" &&
{i18n.Apps ?? 'Apps'} + {SOFTACULOUS === "yes" &&
{i18n.Apps ?? 'Apps'}
} {userName === 'admin' && (
@@ -116,14 +115,14 @@ const Panel = props => {
- + {look ?
{user} {look}
- : session.userName + : userName }
@@ -144,7 +143,7 @@ const Panel = props => {
-
{session.userName}
+
{userName}
diff --git a/src/react/src/components/MainNav/Stat-menu/Menu.jsx b/src/react/src/components/MainNav/Stat-menu/Menu.jsx index 62df71395..6720dfdb4 100644 --- a/src/react/src/components/MainNav/Stat-menu/Menu.jsx +++ b/src/react/src/components/MainNav/Stat-menu/Menu.jsx @@ -27,7 +27,8 @@ const style = ({ menuHeight, mobile }) => { const Menu = props => { const { activeElement, focusedElement } = useSelector(state => state.mainNavigation); - const { i18n, session: { look } } = useSelector(state => state.session); + const { i18n } = useSelector(state => state.session); + const { session: { look } } = useSelector(state => state.userSession); const { user } = useSelector(state => state.menuCounters); const dispatch = useDispatch(); diff --git a/src/react/src/components/MainNav/Toolbar/DropdownFilter/DropdownFilter.scss b/src/react/src/components/MainNav/Toolbar/DropdownFilter/DropdownFilter.scss index 8f62ead12..f37e767ad 100644 --- a/src/react/src/components/MainNav/Toolbar/DropdownFilter/DropdownFilter.scss +++ b/src/react/src/components/MainNav/Toolbar/DropdownFilter/DropdownFilter.scss @@ -68,7 +68,6 @@ span + span { text-align: center; - width: 100px; } } diff --git a/src/react/src/components/Menu/Menu.jsx b/src/react/src/components/Menu/Menu.jsx index 2f2365ba5..67b28abdc 100644 --- a/src/react/src/components/Menu/Menu.jsx +++ b/src/react/src/components/Menu/Menu.jsx @@ -118,9 +118,9 @@ const Menu = (props) => { } const hotKeys = (e) => { - if (props.modalVisible) { - return; - } + let isSearchInputFocused = document.querySelector('input:focus') || document.querySelector('textarea:focus'); + + if (props.modalVisible || isSearchInputFocused) return; if (e.shiftKey && e.keyCode === 117) { rename(); diff --git a/src/react/src/components/Package/Edit/EditPackage.jsx b/src/react/src/components/Package/Edit/EditPackage.jsx index 4f2eb4f33..967ee4f64 100644 --- a/src/react/src/components/Package/Edit/EditPackage.jsx +++ b/src/react/src/components/Package/Edit/EditPackage.jsx @@ -24,11 +24,11 @@ const EditPackage = props => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, - loading: false, - errorMessage: '', - okMessage: '' + loading: false }); useEffect(() => { @@ -39,21 +39,25 @@ const EditPackage = props => { if (queryParams.package) { setState({ ...state, loading: true }); - - getPackageInfo(queryParams.package) - .then(response => { - setState({ - ...state, - data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], - loading: false - }); - }) - .catch(err => console.error(err)); + fetchData(queryParams.package); } }, []); + const fetchData = pkg => { + getPackageInfo(pkg) + .then(response => { + setState({ + ...state, + data: response.data, + loading: false + }); + }) + .catch(err => { + setState({ ...state, loading: false }); + console.error(err); + }); + } + const submitFormHandler = event => { event.preventDefault(); let updatedPackage = {}; @@ -72,17 +76,20 @@ const EditPackage = props => { updatePackage(updatedPackage, state.data.package) .then(result => { if (result.status === 200) { - const { error_msg: errorMessage, ok_msg: okMessage } = result.data; + const { error_msg, ok_msg } = result.data; - if (errorMessage) { - setState({ ...state, errorMessage, okMessage, loading: false }); + if (error_msg) { + setErrorMessage(error_msg); + setOkMessage(''); } else { dispatch(refreshCounters()).then(() => { - setState({ ...state, okMessage, errorMessage: '', loading: false }); + setErrorMessage(''); + setOkMessage(ok_msg); }); } } }) + .then(() => fetchData(state.data.package)) .catch(err => console.error(err)); } } @@ -116,12 +123,12 @@ const EditPackage = props => {
{i18n['Editing Package']}
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/Path/Dropdown/Dropdown.scss b/src/react/src/components/Path/Dropdown/Dropdown.scss index d6f425cfe..44d338e28 100644 --- a/src/react/src/components/Path/Dropdown/Dropdown.scss +++ b/src/react/src/components/Path/Dropdown/Dropdown.scss @@ -41,7 +41,6 @@ span + span { text-align: center; - width: 100px; } } } diff --git a/src/react/src/components/Preview/Photo/Photo.scss b/src/react/src/components/Preview/Photo/Photo.scss index e72366af6..c2c1ad5a0 100644 --- a/src/react/src/components/Preview/Photo/Photo.scss +++ b/src/react/src/components/Preview/Photo/Photo.scss @@ -18,7 +18,6 @@ } .img { - height: 90vh; width: 90%; } } diff --git a/src/react/src/components/Preview/Preview.jsx b/src/react/src/components/Preview/Preview.jsx index e593c9827..72511b25c 100644 --- a/src/react/src/components/Preview/Preview.jsx +++ b/src/react/src/components/Preview/Preview.jsx @@ -6,11 +6,11 @@ import Photo from './Photo/Photo'; import Video from './Video/Video'; const Preview = (props) => { - const session = useSelector(state => state.session); + const {userName} = useSelector(state => state.session); const history = useHistory(); useEffect(() => { - if (!session.userName) history.push('/login'); + if (!userName) history.push('/login'); document.addEventListener("keydown", hotkeys); diff --git a/src/react/src/components/Server/Edit/Bind9/Bind9.jsx b/src/react/src/components/Server/Edit/Bind9/Bind9.jsx index d66160f1f..adfe16c78 100644 --- a/src/react/src/components/Server/Edit/Bind9/Bind9.jsx +++ b/src/react/src/components/Server/Edit/Bind9/Bind9.jsx @@ -19,11 +19,11 @@ const Bind9 = () => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, - loading: false, - errorMessage: '', - okMessage: '' + loading: false }); useEffect(() => { @@ -31,23 +31,23 @@ const Bind9 = () => { dispatch(removeFocusedElement()); setState({ ...state, loading: true }); + fetchData(); + }, []); + const fetchData = () => { getServiceInfo('bind9') .then(response => { if (response.data.config.includes('Error')) { history.push('/list/server'); } - setState({ - ...state, - data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], - loading: false - }); + setState({ ...state, data: response.data, loading: false }); }) - .catch(err => console.error(err)); - }, []); + .catch(err => { + setState({ ...state, loading: false }); + console.error(err); + }); + } const submitFormHandler = event => { event.preventDefault(); @@ -65,15 +65,11 @@ const Bind9 = () => { if (result.status === 200) { const { error_msg, ok_msg } = 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 }); - } else { - setState({ ...state, loading: false }); - } + setErrorMessage(error_msg || ''); + setOkMessage(ok_msg || ''); } }) + .then(() => fetchData()) .catch(err => console.error(err)); } } @@ -90,12 +86,12 @@ const Bind9 = () => {
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/Server/Edit/Dovecot/Dovecot.jsx b/src/react/src/components/Server/Edit/Dovecot/Dovecot.jsx index f3f5e7ca1..353c705e8 100644 --- a/src/react/src/components/Server/Edit/Dovecot/Dovecot.jsx +++ b/src/react/src/components/Server/Edit/Dovecot/Dovecot.jsx @@ -19,11 +19,11 @@ const Dovecot = () => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, - loading: false, - errorMessage: '', - okMessage: '' + loading: false }); useEffect(() => { @@ -31,7 +31,10 @@ const Dovecot = () => { dispatch(removeFocusedElement()); setState({ ...state, loading: true }); + fetchData(); + }, []); + const fetchData = () => { getServiceInfo('dovecot') .then(response => { if (!response.data.config) { @@ -41,13 +44,14 @@ const Dovecot = () => { setState({ ...state, data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], loading: false }); }) - .catch(err => console.error(err)); - }, []); + .catch(err => { + setState({ ...state, loading: false }); + console.error(err); + }); + } const submitFormHandler = event => { event.preventDefault(); @@ -65,15 +69,11 @@ const Dovecot = () => { if (result.status === 200) { const { error_msg, ok_msg } = 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 }); - } else { - setState({ ...state, loading: false }); - } + setErrorMessage(error_msg || ''); + setOkMessage(ok_msg || ''); } }) + .then(() => fetchData()) .catch(err => console.error(err)); } } @@ -90,12 +90,12 @@ const Dovecot = () => {
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/Server/Edit/EditServer.jsx b/src/react/src/components/Server/Edit/EditServer.jsx index e82e6ce74..38fa2ab88 100644 --- a/src/react/src/components/Server/Edit/EditServer.jsx +++ b/src/react/src/components/Server/Edit/EditServer.jsx @@ -20,12 +20,16 @@ import { useDispatch, useSelector } from 'react-redux'; import './EditServer.scss'; import { Helmet } from 'react-helmet'; import HtmlParser from 'react-html-parser'; +import { refreshUserSession } from 'src/actions/Session/sessionActions'; const EditServer = props => { const token = localStorage.getItem("token"); const { i18n } = useSelector(state => state.session); + const { session } = useSelector(state => state.userSession); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, loading: false, @@ -35,9 +39,7 @@ const EditServer = props => { backupOption: false, sslOption: false, pluginsOption: false, - dbOption: false, - errorMessage: '', - okMessage: '' + dbOption: false }); useEffect(() => { @@ -45,20 +47,23 @@ const EditServer = props => { dispatch(removeFocusedElement()); setState({ ...state, loading: true }); + fetchData(); + }, []); + const fetchData = () => { getServerAdditionalInfo() .then(response => { setState({ ...state, data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], loading: false }); }) - .catch(err => console.error(err)); - - }, []); + .catch(err => { + setState({ ...state, loading: false }); + console.error(err); + }); + } const submitFormHandler = event => { event.preventDefault(); @@ -71,6 +76,10 @@ const EditServer = props => { updatedServer['save'] = 'save'; updatedServer['token'] = token; + if (updatedServer['v_softaculous'] === 'no' && !session['SOFTACULOUS']) { + delete updatedServer['v_softaculous']; + } + if (Object.keys(updatedServer).length !== 0 && updatedServer.constructor === Object) { setState({ ...state, loading: true }); @@ -78,9 +87,17 @@ const EditServer = props => { .then(result => { if (result.status === 200) { const { error_msg, ok_msg } = result.data; - setState({ ...state, errorMessage: error_msg || '', okMessage: ok_msg || '', loading: false }); + + if (error_msg) { + setErrorMessage(error_msg); + setOkMessage(''); + } else { + setErrorMessage(''); + setOkMessage(ok_msg); + } } }) + .then(() => dispatch(refreshUserSession()).then(() => fetchData())) .catch(err => console.error(err)); } } @@ -102,12 +119,12 @@ const EditServer = props => {
{i18n['Configuring Server']}
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/Server/Edit/EditServerDnsOption.jsx b/src/react/src/components/Server/Edit/EditServerDnsOption.jsx index d32d85a0d..e45213264 100644 --- a/src/react/src/components/Server/Edit/EditServerDnsOption.jsx +++ b/src/react/src/components/Server/Edit/EditServerDnsOption.jsx @@ -9,7 +9,7 @@ const EditServerDnsOption = ({ dnsSystem, selected, dnsCluster, visible }) => { const { i18n } = useSelector(state => state.session); const printHosts = () => { - return dnsCluster.map((cluster, index) => ( + return Object.keys(dnsCluster).map((cluster, index) => ( { const { i18n } = useSelector(state => state.session); - const [sftpOptions, setSftpOptions] = useState([]); - const [fmOptions, setFmOptions] = useState([]); - const [sftpDescription, setSftpDescription] = useState(false); - const [fmDescription, setFmDescription] = useState(false); - const [softaculousDescription, setSoftaculousDescription] = useState(false); + const { session } = useSelector(state => state.userSession); + const [sftpValue, setSftpValue] = useState(data.lead || session['SFTPJAIL_KEY'] ? 'yes' : 'no'); + const [fmValue, setFmValue] = useState(data.fm_lead || session['FILEMANAGER_KEY'] ? 'yes' : 'no'); + const [softaculousValue, setSoftaculousValue] = useState(session['SOFTACULOUS'] === 'yes' ? 'yes' : 'no'); - useEffect(() => { - let sftpOptionsArray = []; - let fmOptionsArray = []; + const renderSoftaculous = () => { + if (softaculousValue === 'yes') { + if (session['SOFTACULOUS'] === 'yes') { + return (
+
+ {i18n['* plugin installation will run in background']} + + Softaculous is a great Auto Installer having 426 great scripts, 1115 PHP Classes + and we are still adding more. Softaculous is ideal for Web Hosting companies and + it could give a significant boost to your sales. These scripts cover most of the + uses a customer could ever have. We have covered a wide array of Categories so that + everyone could find the required script one would need to power their Web Site. + +
- if (data.sftpjail_key) { - sftpOptionsArray.push(i18n['Disable and Cancel Licence']); - } - - sftpOptionsArray.push(i18n['yes']); - - if (data.fm_key) { - fmOptionsArray.push(i18n['Disable and Cancel Licence']); - } - - fmOptionsArray.push(i18n['yes']); - - setSftpOptions(sftpOptionsArray); - setFmOptions(fmOptionsArray); - - if (data.lead === 'sftp' || data.sftpjail_key !== 'no') { - setSftpDescription(true); - } - - if (data.lead === 'filemanager' || data.fm_key !== 'no') { - setFmDescription(true); - } - - if (data.lead === 'softaculous' || data.softaculous !== 'no') { - setSoftaculousDescription(true); - } - }, []); - - const onChangeSftpChroot = value => { - if (value !== i18n['yes']) { - setSftpDescription(false); - } else { - setSftpDescription(true); + +
); + } } } - const onChangeFm = value => { - if (value !== i18n['yes']) { - setFmDescription(false); - } else { - setFmDescription(true); + const renderSftp = () => { + if (sftpValue === 'yes') { + if (!data.sftp_license_key && session['SFTPJAIL_KEY']) { + return (
+
{i18n['Restrict users so that they cannot use SSH and access only their home directory.']}
+
+ {i18n['Licence Key']}: + +
+
) + } else { + return (
+ <> + {i18n['Restrict users so that they cannot use SSH and access only their home directory.']} + {i18n['This is a commercial module, you would need to purchace license key to enable it.']} + +
+ {i18n['Enter License Key']}: + +
+ + + + 2Checkout.com Inc. (Ohio, USA) is a payment facilitator for goods and services provided by vestacp.com. +
) + } } } - const onChangeSoftaculous = value => { - if (value !== i18n['yes']) { - setSoftaculousDescription(true); - } else { - setSoftaculousDescription(false); + const renderFm = () => { + if (fmValue === 'yes') { + if (!data.fm_license_key && session['FILEMANAGER_KEY']) { + return (
+
{i18n['Browse, copy, edit, view, and retrieve all of your web domain files using fully featured File Manager.']}
+
+ {i18n['Licence Key']}: + +
+
); + } else { + return (
+ <> + {i18n['Browse, copy, edit, view, and retrieve all of your web domain files using fully featured File Manager.']} + {i18n['This is a commercial module, you would need to purchace license key to enable it.']} + +
+ {i18n['Enter License Key']}: + +
+ + + + 2Checkout.com Inc. (Ohio, USA) is a payment facilitator for goods and services provided by vestacp.com. +
) + } } } @@ -78,21 +132,27 @@ const EditVestaPluginsOption = ({ data, visible }) => { id="version" disabled /> - +
+ + +

- +
+ + +
{ id="backup_manager" disabled /> - +
+ + +
- - - 2Checkout.com Inc. (Ohio, USA) is a payment facilitator for goods and services provided by vestacp.com. -
- ) - } + {renderSftp()}
- +
+ + +
- - - 2Checkout.com Inc. (Ohio, USA) is a payment facilitator for goods and services provided by vestacp.com. - - ) - } + {renderFm()}
- +
+ + +
- { - softaculousDescription && ( -
-
- {i18n['* plugin installation will run in background']} - - Softaculous is a great Auto Installer having 426 great scripts, 1115 PHP Classes - and we are still adding more. Softaculous is ideal for Web Hosting companies and - it could give a significant boost to your sales. These scripts cover most of the - uses a customer could ever have. We have covered a wide array of Categories so that - everyone could find the required script one would need to power their Web Site. - -
- - -
- ) - } + {renderSoftaculous()} ); } diff --git a/src/react/src/components/Server/Edit/Httpd/EditHttpd.jsx b/src/react/src/components/Server/Edit/Httpd/EditHttpd.jsx index 494cd3dd8..c23aec7f4 100644 --- a/src/react/src/components/Server/Edit/Httpd/EditHttpd.jsx +++ b/src/react/src/components/Server/Edit/Httpd/EditHttpd.jsx @@ -19,6 +19,8 @@ const EditHttpd = props => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, loading: false, @@ -31,19 +33,23 @@ const EditHttpd = props => { dispatch(removeFocusedElement()); setState({ ...state, loading: true }); + fetchData(); + }, []); + const fetchData = () => { getServiceInfo('httpd') .then(response => { setState({ ...state, data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], loading: false }); }) - .catch(err => console.error(err)); - }, []); + .catch(err => { + setState({ ...state, loading: false }); + console.error(err); + }); + } const submitFormHandler = event => { event.preventDefault(); @@ -62,14 +68,15 @@ const EditHttpd = props => { const { error_msg, ok_msg } = 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 }); + setErrorMessage(error_msg); + setOkMessage(''); } else { - setState({ ...state, loading: false }); + setErrorMessage(''); + setOkMessage(ok_msg); } } }) + .then(() => fetchData()) .catch(err => console.error(err)); } } @@ -85,12 +92,12 @@ const EditHttpd = props => {
{i18n['Configure']} php.ini
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
diff --git a/src/react/src/components/Server/Edit/Mysql/Mysql.jsx b/src/react/src/components/Server/Edit/Mysql/Mysql.jsx index 64dc47e51..df9840b8b 100644 --- a/src/react/src/components/Server/Edit/Mysql/Mysql.jsx +++ b/src/react/src/components/Server/Edit/Mysql/Mysql.jsx @@ -20,13 +20,14 @@ const Mysql = ({ serviceName = '' }) => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); + const [restart, setRestart] = useState(true); const [state, setState] = useState({ data: {}, loading: false, basicOptions: true, - advancedOptions: false, - errorMessage: '', - okMessage: '' + advancedOptions: false }); useEffect(() => { @@ -38,23 +39,23 @@ const Mysql = ({ serviceName = '' }) => { } setState({ ...state, loading: true }); + fetchData(); + }, []); + const fetchData = () => { getServiceInfo('mysql') .then(response => { if (response.data.config.includes('Error')) { history.push('/list/server'); } - setState({ - ...state, - data: response.data, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], - loading: false - }); + setState({ ...state, data: response.data, loading: false }); }) - .catch(err => console.error(err)); - }, []); + .catch(err => { + setState({ ...state, loading: false }); + console.error(err); + }); + } const submitFormHandler = event => { event.preventDefault(); @@ -67,20 +68,19 @@ const Mysql = ({ serviceName = '' }) => { if (Object.keys(updatedService).length !== 0 && updatedService.constructor === Object) { setState({ ...state, loading: true }); + updatedService['v_config'] = state.data.config; + updatedService['v_restart'] = restart ? 'yes' : 'no'; + updateService(updatedService, `/${serviceName}`) .then(result => { if (result.status === 200) { const { error_msg, ok_msg } = 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 }); - } else { - setState({ ...state, loading: false }); - } + setErrorMessage(error_msg || ''); + setOkMessage(ok_msg || ''); } }) + .then(() => fetchData()) .catch(err => console.error(err)); } } @@ -93,6 +93,14 @@ const Mysql = ({ serviceName = '' }) => { }); } + const onUpdateConfig = ({ id, value }) => { + if (!value) return; + + var regexp = new RegExp(`(${id})(.+)(${state.data[id]})`, 'gm'); + const updatedConfig = state.data.config.replace(regexp, `$1$2${value}`); + setState({ ...state, data: { ...state.data, config: updatedConfig, [id]: value } }); + } + return (
@@ -103,12 +111,12 @@ const Mysql = ({ serviceName = '' }) => {
{i18n['Configuring Server']} / {state.data.service_name}
- {state.data.errorMessage ? : ''} {state.errorMessage} + {errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
@@ -134,30 +142,35 @@ const Mysql = ({ serviceName = '' }) => { id="max_connections" title="max_connections" name="v_max_connections" + onChange={event => onUpdateConfig(event.target)} value={state.data.max_connections} /> onUpdateConfig(event.target)} value={state.data.max_user_connections} /> onUpdateConfig(event.target)} value={state.data.wait_timeout} /> onUpdateConfig(event.target)} value={state.data.interactive_timeout} /> onUpdateConfig(event.target)} value={state.data.max_allowed_packet} /> ) @@ -181,6 +194,7 @@ const Mysql = ({ serviceName = '' }) => {
-
-
- - -
-
+ { + panel[userName]['DNS_DOMAINS'] !== '0' && ( + checkboxHandler('dnsSupport', checked)} + name="v_dns" + id="dns-support" + title={i18n['DNS Support'] ?? 'DNS Support'} + defaultChecked={state.dnsSupport} /> + ) + } + + { + panel[userName]['MAIL_DOMAINS'] !== '0' && ( + checkboxHandler('mailSupport', checked)} + name="v_mail" + id="mail-support" + title={i18n['Mail Support'] ?? 'Mail Support'} + defaultChecked={state.mailSupport} /> + ) + } + + { + session.PROXY_SYSTEM && ( + <> + checkboxHandler('proxySupport', checked)} + name="v_proxy" + id="proxy" + title={i18n['Proxy Support'] ?? 'Proxy Support'} + defaultChecked={state.proxySupport} /> + + { + state.proxySupport && (
+ -
- +
{
-
-
- setState({ ...state, additionalFtp: !state.additionalFtp })} /> - -
-
+ setState({ ...state, additionalFtp: checked })} + name="v_ftp" + id="add-ftp" + checked={state.additionalFtp} + title={i18n['Additional FTP Account']} /> - {renderAdditionalFtp()} + setState({ ...state, additionalFtp: false })} />
); } -export default AdvancedOptions; \ No newline at end of file +export default AdvancedOptions; diff --git a/src/react/src/components/WebDomain/Edit/EditWeb.jsx b/src/react/src/components/WebDomain/Edit/EditWeb.jsx index d119d8c00..ab7e724c7 100644 --- a/src/react/src/components/WebDomain/Edit/EditWeb.jsx +++ b/src/react/src/components/WebDomain/Edit/EditWeb.jsx @@ -26,6 +26,8 @@ const EditWeb = props => { const { i18n } = useSelector(state => state.session); const history = useHistory(); const dispatch = useDispatch(); + const [errorMessage, setErrorMessage] = useState(''); + const [okMessage, setOkMessage] = useState(''); const [state, setState] = useState({ data: {}, domain: '', @@ -33,10 +35,9 @@ const EditWeb = props => { sslSupport: false, letsEncrypt: false, additionalFtp: false, + proxySupport: false, statAuth: false, - loading: false, - errorMessage: '', - okMessage: '' + loading: false }); useEffect(() => { @@ -48,27 +49,29 @@ const EditWeb = props => { if (domain) { setState({ ...state, loading: true }); - - getDomainInfo(domain) - .then(response => { - setState({ - ...state, - domain, - webStat: response.data.v_stats ? response.data.v_stats : 'none', - sslSupport: response.data.ssl === 'yes', - letsEncrypt: response.data.letsencrypt === 'yes', - data: response.data, - additionalFtp: !!response.data.ftp_user, - statAuth: response.data.stats_user, - errorMessage: response.data['error_msg'], - okMessage: response.data['ok_msg'], - loading: false - }); - }) - .catch(err => console.error(err)); + fetchData(domain); } }, []); + const fetchData = domain => { + getDomainInfo(domain) + .then(response => { + setState({ + ...state, + domain, + webStat: response.data.v_stats ? response.data.v_stats : 'none', + sslSupport: response.data.ssl === 'yes', + letsEncrypt: response.data.letsencrypt === 'yes', + proxySupport: !!response.data.proxy, + data: response.data, + additionalFtp: !!response.data.ftp_user, + statAuth: response.data.stats_user, + loading: false + }); + }) + .catch(err => console.error(err)); + } + const submitFormHandler = event => { event.preventDefault(); let updatedDomain = {}; @@ -79,19 +82,27 @@ const EditWeb = props => { updatedDomain['v_domain'] = state.domain; + if (updatedDomain['v_ssl'] === 'on') { + updatedDomain['v_ssl'] = 'yes'; + } + if (Object.keys(updatedDomain).length !== 0 && updatedDomain.constructor === Object) { setState({ ...state, loading: true }); updateWebDomain(updatedDomain, state.domain) .then(result => { if (result.status === 200) { - const { error_msg: errorMessage, ok_msg: okMessage } = result.data; + const { error_msg, ok_msg } = result.data; - if (errorMessage) { - setState({ ...state, errorMessage, okMessage, loading: false }); + if (error_msg) { + setErrorMessage(error_msg); + setOkMessage(''); + setState({ ...state, loading: false }); } else { dispatch(refreshCounters()).then(() => { - setState({ ...state, okMessage, errorMessage: '', loading: false }); + setErrorMessage(''); + setOkMessage(ok_msg); + fetchData(state.domain); }); } } @@ -114,6 +125,10 @@ const EditWeb = props => { setState({ ...state, sslSupport: checked }); } + const onChangeProxySupport = checked => { + setState({ ...state, proxySupport: checked }); + } + const onChangeWebStats = webStat => { setState({ ...state, webStat }); } @@ -134,9 +149,9 @@ const EditWeb = props => {
{i18n['Editing Domain']}
-
{state.data.errorMessage ? : ''} {state.errorMessage}
+
{errorMessage ? : ''} {errorMessage}
- {state.okMessage ? : ''} {HtmlParser(state.okMessage)} + {okMessage ? : ''} {HtmlParser(okMessage)}
@@ -169,8 +184,7 @@ const EditWeb = props => { title={i18n['Web Template']} /> { - state.data.web_backend - && ( + state.data.WEB_BACKEND && ( { } { - state.data.proxy_system - && ( - + state.data.proxy_system && ( + <> + + + { + state.proxySupport && (
+ + +