UI 1.0.0-6 release.

This commit is contained in:
Alexander 2021-12-30 21:53:38 +00:00
parent 22f3dd11e2
commit 0420ecc0e6
58 changed files with 374 additions and 151 deletions

View file

@ -2,5 +2,6 @@
"compilerOptions": { "compilerOptions": {
"baseUrl": "." "baseUrl": "."
}, },
"include": ["src"] "include": ["src"],
"exclude": ["node_modules", "build"]
} }

View file

@ -11526,6 +11526,15 @@
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz", "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
}, },
"react-perfect-scrollbar": {
"version": "1.5.8",
"resolved": "https://registry.npmjs.org/react-perfect-scrollbar/-/react-perfect-scrollbar-1.5.8.tgz",
"integrity": "sha512-bQ46m70gp/HJtiBOF3gRzBISSZn8FFGNxznTdmTG8AAwpxG1bJCyn7shrgjEvGSQ5FJEafVEiosY+ccER11OSA==",
"requires": {
"perfect-scrollbar": "^1.5.0",
"prop-types": "^15.6.1"
}
},
"react-redux": { "react-redux": {
"version": "7.2.1", "version": "7.2.1",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.1.tgz", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.1.tgz",

View file

@ -25,6 +25,7 @@
"react-dom": "^16.10.2", "react-dom": "^16.10.2",
"react-helmet": "^6.1.0", "react-helmet": "^6.1.0",
"react-html-parser": "^2.0.2", "react-html-parser": "^2.0.2",
"react-perfect-scrollbar": "^1.5.8",
"react-redux": "^7.2.1", "react-redux": "^7.2.1",
"react-router-dom": "^5.1.2", "react-router-dom": "^5.1.2",
"react-scripts": "^3.4.1", "react-scripts": "^3.4.1",

View file

@ -1,12 +1,13 @@
import { REFRESH_COUNTERS } from './menuCounterTypes'; import { REFRESH_COUNTERS } from './menuCounterTypes';
import { checkAuth } from 'src/services/session'; import { checkAuth } from 'src/services/session';
import { setAuthToken } from 'src/utils/token'; import { setAuthToken } from 'src/utils/token';
import { REFRESH_PANEL } from '../Panel/panelTypes';
export const refreshCounters = () => (dispatch, getState) => { export const refreshCounters = () => (dispatch, getState) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
checkAuth() checkAuth()
.then(res => { .then(res => {
const { data, token } = res.data; const { data, token, panel } = res.data;
if (token) setAuthToken(token); if (token) setAuthToken(token);
@ -17,6 +18,13 @@ export const refreshCounters = () => (dispatch, getState) => {
} }
}); });
dispatch({
type: REFRESH_PANEL,
value: {
panel
}
});
resolve(token); resolve(token);
}) })
.catch(err => { .catch(err => {

View file

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

View file

@ -4,6 +4,7 @@ import { resetPassword } from 'src/ControlPanelService/ResetPassword';
import { resetAuthToken, setAuthToken } from 'src/utils/token'; import { resetAuthToken, setAuthToken } from 'src/utils/token';
import { REFRESH_COUNTERS } from '../MenuCounters/menuCounterTypes'; import { REFRESH_COUNTERS } from '../MenuCounters/menuCounterTypes';
import { SET_USER_SESSION } from '../UserSession/userSessionTypes'; import { SET_USER_SESSION } from '../UserSession/userSessionTypes';
import { REFRESH_PANEL } from '../Panel/panelTypes';
const LOGOUT_RESPONSE = 'logged_out'; const LOGOUT_RESPONSE = 'logged_out';
const LOGOUT_AS_RESPONSE = 'logged_out_as'; const LOGOUT_AS_RESPONSE = 'logged_out_as';
@ -19,12 +20,17 @@ export const login = (user, password) => dispatch => {
type: LOGIN, type: LOGIN,
value: { value: {
token: token || '', token: token || '',
panel,
i18n: i18n || {}, i18n: i18n || {},
userName: user, userName: user,
error error
}, },
}); });
dispatch({
type: REFRESH_PANEL,
value: {
panel
}
});
dispatch({ dispatch({
type: REFRESH_COUNTERS, type: REFRESH_COUNTERS,
value: { value: {
@ -51,11 +57,16 @@ export const reset = ({ user = '', code = '', password = '', password_confirm =
type: RESET_PASSWORD, type: RESET_PASSWORD,
value: { value: {
token, token,
panel,
userName: user, userName: user,
error error
}, },
}); });
dispatch({
type: REFRESH_PANEL,
value: {
panel
}
});
dispatch({ dispatch({
type: REFRESH_COUNTERS, type: REFRESH_COUNTERS,
value: { value: {
@ -84,11 +95,16 @@ export const loginAs = username => dispatch => {
value: { value: {
userName: user, userName: user,
i18n, i18n,
panel,
token, token,
error error
} }
}); });
dispatch({
type: REFRESH_PANEL,
value: {
panel
}
});
dispatch({ dispatch({
type: REFRESH_COUNTERS, type: REFRESH_COUNTERS,
value: { value: {
@ -121,12 +137,17 @@ export const logout = () => (dispatch, getState) => {
value: { value: {
userName: '', userName: '',
token: '', token: '',
panel: {},
session: {}, session: {},
i18n: [], i18n: [],
error, error,
}, },
}); });
dispatch({
type: REFRESH_PANEL,
value: {
panel: {}
}
});
dispatch({ dispatch({
type: REFRESH_COUNTERS, type: REFRESH_COUNTERS,
value: { value: {
@ -144,12 +165,17 @@ export const logout = () => (dispatch, getState) => {
type: LOGGED_OUT_AS, type: LOGGED_OUT_AS,
value: { value: {
userName, userName,
panel,
token: '', token: '',
i18n, i18n,
error, error,
}, },
}); });
dispatch({
type: REFRESH_PANEL,
value: {
panel
}
});
dispatch({ dispatch({
type: REFRESH_COUNTERS, type: REFRESH_COUNTERS,
value: { value: {
@ -185,11 +211,16 @@ export const checkAuthHandler = () => (dispatch, getState) => {
value: { value: {
userName: user, userName: user,
i18n, i18n,
panel,
token, token,
error error
} }
}); });
dispatch({
type: REFRESH_PANEL,
value: {
panel
}
});
dispatch({ dispatch({
type: REFRESH_COUNTERS, type: REFRESH_COUNTERS,
value: { value: {

View file

@ -18,7 +18,6 @@ import './BackupRestoreSettings.scss';
export default function BackupRestoreSettings(props) { export default function BackupRestoreSettings(props) {
const { i18n } = useSelector(state => state.session); const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent); const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation); const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch(); const dispatch = useDispatch();

View file

@ -23,7 +23,7 @@ $errorColor: #BE5ABF;
div.error, div.error,
div.success { div.success {
width: max-content !important; width: fit-content !important;
span { span {
font-weight: bold; font-weight: bold;
@ -58,6 +58,7 @@ $errorColor: #BE5ABF;
width: auto !important; width: auto !important;
padding: 10px 0; padding: 10px 0;
margin-left: 0; margin-left: 0;
margin-right: 10px;
} }
} }
} }
@ -211,7 +212,7 @@ $errorColor: #BE5ABF;
label.label-wrapper { label.label-wrapper {
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
width: max-content; width: fit-content;
span { span {
font-weight: normal; font-weight: normal;

View file

@ -30,6 +30,7 @@ const Password = ({ defaultValue, onChange = () => { }, id, name, title, showGen
} }
setState({ ...state, generatedPassword: result }); setState({ ...state, generatedPassword: result });
onChange(result);
} }
const passwordInputHandler = value => { const passwordInputHandler = value => {

View file

@ -1,6 +1,6 @@
.content .edit-template.add-firewall { .content .edit-template.add-firewall {
.toolbar .search-toolbar-name { .toolbar .search-toolbar-name {
width: max-content; width: fit-content;
} }
label.label-wrapper[for=ip] span { label.label-wrapper[for=ip] span {

View file

@ -50,7 +50,7 @@ const InternetProtocol = props => {
</Container> </Container>
<Container className="c-3 w-35"> <Container className="c-3 w-35">
<div>{i18n.Owner}: <span className="stat">{data.OWNER}</span></div> <div>{i18n.Owner}: <span className="stat">{data.OWNER}</span></div>
<div>{i18n.Users}: <span className="stat">{data.U_SYS_USERS.replaceAll(',', ', ')}</span></div> <div>{i18n.Users}: <span className="stat">{data.U_SYS_USERS.replace(/,/g, ', ')}</span></div>
</Container> </Container>
</div> </div>
</Container> </Container>

View file

@ -48,14 +48,18 @@ export default function AddMailAccount(props) {
event.preventDefault(); event.preventDefault();
let newMailDomain = {}; let newMailDomain = {};
for (var [name, value] of (new FormData(event.target)).entries()) { for (var [name, value] of (new FormData(event.target)).entries()) {
newMailDomain[name] = value; newMailDomain[name] = value;
} }
newMailDomain['ok_acc'] = 'add'; newMailDomain['ok_acc'] = 'add';
newMailDomain['token'] = token; newMailDomain['token'] = token;
newMailDomain['v_domain'] = props.domain; newMailDomain['v_domain'] = props.domain;
newMailDomain['Password'] = newMailDomain['v_password']; newMailDomain['v_password'] = state.password;
if (!newMailDomain['v_quota']) newMailDomain['v_quota'] = '';
if (!newMailDomain['v_aliases']) newMailDomain['v_aliases'] = '';
if (!newMailDomain['v_fwd']) newMailDomain['v_fwd'] = '';
if (Object.keys(newMailDomain).length !== 0 && newMailDomain.constructor === Object) { if (Object.keys(newMailDomain).length !== 0 && newMailDomain.constructor === Object) {
setState({ ...state, loading: true }); setState({ ...state, loading: true });
@ -195,8 +199,8 @@ export default function AddMailAccount(props) {
<TextInput <TextInput
title={i18n['Send login credentials to email address']} title={i18n['Send login credentials to email address']}
name="v_credentials" name="v_send_email"
id="credentials" /> id="send_email" />
</div> </div>
<div className="buttons-wrapper"> <div className="buttons-wrapper">

View file

@ -1,6 +1,6 @@
.content .edit-template.add-mail-account { .content .edit-template.add-mail-account {
.search-toolbar-name { .search-toolbar-name {
width: max-content; width: fit-content;
} }
form { form {

View file

@ -63,10 +63,12 @@ export default function EditMailAccount(props) {
if (error_msg) { if (error_msg) {
setErrorMessage(error_msg); setErrorMessage(error_msg);
setOkMessage(''); setOkMessage('');
setState({ ...state, loading: false });
} else { } else {
dispatch(refreshCounters()).then(() => { dispatch(refreshCounters()).then(() => {
setErrorMessage(''); setErrorMessage('');
setOkMessage(ok_msg); setOkMessage(ok_msg);
setState({ ...state, loading: false });
}); });
} }
} }
@ -200,7 +202,7 @@ export default function EditMailAccount(props) {
</div> </div>
<div className="buttons-wrapper"> <div className="buttons-wrapper">
<button type="submit" className="add">{i18n.Add}</button> <button type="submit" className="add">{i18n.Save}</button>
<button type="button" className="back" onClick={goBack}>{i18n.Back}</button> <button type="button" className="back" onClick={goBack}>{i18n.Back}</button>
</div> </div>
</form> </form>

View file

@ -46,6 +46,24 @@ export default function MailInfoBlock({ webMail, hostName, domain, userName = ''
); );
} }
const getCredentials = () => {
let result = '';
result += `${i18n['Username']}:${userName}@${domain}\n`;
result += `${i18n['Password']}:${password}\n`;
result += `${i18n['IMAP hostname']}:${state.imapHostName}\n`;
result += `${i18n['IMAP port']}:${state.imapPort}\n`;
result += `${i18n['IMAP security']}:${state.imapEncryption}\n`;
result += `${i18n['IMAP auth method']}:${i18n['Normal password']}\n`;
result += `${i18n['SMTP hostname']}:${state.smtpHostName}\n`;
result += `${i18n['SMTP port']}:${state.smtpPort}\n`;
result += `${i18n['SMTP security']}:${state.smtpEncryption}\n`;
result += `${i18n['SMTP auth method']}:${i18n['Normal password']}\n`;
result += `${i18n['Webmail URL']}:${`http://${window.location.hostname}${webMail}`}\n`;
return result;
}
return ( return (
<div className="mail-info-block"> <div className="mail-info-block">
<div class="form-group select-group"> <div class="form-group select-group">
@ -109,15 +127,7 @@ export default function MailInfoBlock({ webMail, hostName, domain, userName = ''
<span><Link to={{ pathname: `http://${window.location.hostname}${webMail}` }} target="_blank">{webMail}</Link></span> <span><Link to={{ pathname: `http://${window.location.hostname}${webMail}` }} target="_blank">{webMail}</Link></span>
</div> </div>
<input type="hidden" name={i18n['Username']} value={`@${domain}`} /> <input type="hidden" name="v_credentials" value={getCredentials()} />
<input type="hidden" name={i18n['IMAP hostname']} value={state.imapHostName} />
<input type="hidden" name={i18n['SMTP hostname']} value={state.smtpHostName} />
<input type="hidden" name={i18n['IMAP port']} value={state.imapPort} />
<input type="hidden" name={i18n['SMTP port']} value={state.smtpPort} />
<input type="hidden" name={i18n['IMAP security']} value={state.imapEncryption} />
<input type="hidden" name={i18n['SMTP security']} value={state.smtpEncryption} />
<input type="hidden" name={i18n['IMAP auth method']} value={i18n['Normal password']} />
<input type="hidden" name={i18n['SMTP auth method']} value={i18n['Normal password']} />
</div> </div>
</div> </div>
</div> </div>

View file

@ -45,7 +45,7 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 0 10px !important; padding: 0 10px !important;
width: max-content; width: fit-content;
height: 100%; height: 100%;
text-decoration: none; text-decoration: none;
color: $black; color: $black;

View file

@ -14,7 +14,8 @@ const Notifications = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
useEffect(() => { useEffect(() => {
if (!notifications) { if (!notifications.length) {
console.log(notifications);
fetchData(); fetchData();
} }
}, [notifications]); }, [notifications]);
@ -47,7 +48,7 @@ const Notifications = () => {
} }
const renderOptions = () => { const renderOptions = () => {
if (notifications && notifications.length) { if (notifications.length) {
return notifications.map(item => { return notifications.map(item => {
return ( return (
<> <>
@ -74,7 +75,7 @@ const Notifications = () => {
<button type="button" className="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <button type="button" className="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<div className="bell"> <div className="bell">
{ {
notifications && notifications.length notifications.length
? <BellUnread /> ? <BellUnread />
: <Bell /> : <Bell />
} }
@ -87,4 +88,4 @@ const Notifications = () => {
); );
}; };
export default Notifications; export default Notifications;

View file

@ -9,7 +9,8 @@ import { Link } from "react-router-dom";
import './Panel.scss'; import './Panel.scss';
const Panel = props => { const Panel = props => {
const { i18n, userName, panel } = useSelector(state => state.session); const { i18n, userName } = useSelector(state => state.session);
const { panel } = useSelector(state => state.panel);
const { session } = useSelector(state => state.userSession); const { session } = useSelector(state => state.userSession);
const { activeElement, focusedElement } = useSelector(state => state.mainNavigation); const { activeElement, focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -63,6 +64,40 @@ const Panel = props => {
}); });
} }
const renderNotifications = () => {
if (panel[userName]) {
if (panel[userName]['NOTIFICATIONS'] === 'yes') {
return <Notifications />;
}
}
}
const renderSmallNavigation = () => {
if (document.documentElement.clientWidth < 900) {
return (<div className="top-panel small-device">
<div className="container left-menu">
<div className="logo">
<Link to="/list/user/" onClick={() => dispatch(addActiveElement('/list/user/'))}>
<div>
<img src="/images/white_logo.png" alt="Logo" />
</div>
</Link>
</div>
</div>
<div className="container hamburger" onClick={toggleNavigation}>
<span className="bar"></span>
<span className="bar"></span>
<span className="bar"></span>
</div>
<div className="container profile-menu">
{renderNotifications()}
<div><Link to={`/edit/user?user=${userName}`}>{userName}</Link></div>
<div><button onClick={signOut}>{i18n['Log out']}</button></div>
</div>
</div>);
}
}
return ( return (
<div className="panel-wrapper"> <div className="panel-wrapper">
{loading && <Spinner />} {loading && <Spinner />}
@ -113,7 +148,7 @@ const Panel = props => {
)} )}
</div> </div>
<div className="container profile-menu"> <div className="container profile-menu">
{panel[userName]['NOTIFICATIONS'] === 'yes' && <Notifications />} {renderNotifications()}
<div className="edit-user"> <div className="edit-user">
<Link to={`/edit/user?user=${userName}`}> <Link to={`/edit/user?user=${userName}`}>
{session.look {session.look
@ -130,27 +165,7 @@ const Panel = props => {
</div> </div>
</div> </div>
<div className="top-panel small-device"> {renderSmallNavigation()}
<div className="container left-menu">
<div className="logo">
<Link to="/list/user/" onClick={() => dispatch(addActiveElement('/list/user/'))}>
<div>
<img src="/images/white_logo.png" alt="Logo" />
</div>
</Link>
</div>
</div>
<div className="container hamburger" onClick={toggleNavigation}>
<span className="bar"></span>
<span className="bar"></span>
<span className="bar"></span>
</div>
<div className="container profile-menu">
{panel[userName]['NOTIFICATIONS'] === 'yes' && <Notifications />}
<div><Link to={`/edit/user?user=${userName}`}>{userName}</Link></div>
<div><button onClick={signOut}>{i18n['Log out']}</button></div>
</div>
</div>
</div> </div>
); );
} }

View file

@ -46,7 +46,7 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 0 10px !important; padding: 0 10px !important;
width: max-content; width: fit-content;
height: 100%; height: 100%;
text-decoration: none; text-decoration: none;
color: white; color: white;
@ -91,7 +91,8 @@
padding: 0; padding: 0;
justify-content: space-between; justify-content: space-between;
div { div.top-link,
div.nav-link {
flex: 1 1 auto; flex: 1 1 auto;
height: 100%; height: 100%;
transform: translateX(-5px); transform: translateX(-5px);
@ -150,8 +151,8 @@
svg { svg {
border-radius: 30px; border-radius: 30px;
width: 100%; width: 40px;
height: 100%; height: 30px;
padding: 3px; padding: 3px;
&:hover { &:hover {
@ -199,7 +200,7 @@
justify-content: start; justify-content: start;
> div { > div {
width: max-content; width: fit-content;
flex: unset; flex: unset;
padding: 0 1rem; padding: 0 1rem;
} }
@ -212,11 +213,10 @@
} }
.profile-menu { .profile-menu {
justify-content: space-between;
align-items: center; align-items: center;
> .edit-user { > .edit-user {
width: max-content; width: fit-content;
} }
.long-username { .long-username {
@ -236,7 +236,7 @@
} }
} }
@media screen and (min-width: $desktopMax) { @media screen and (max-width: 1350px) {
.top-panel { .top-panel {
padding: 0 10%; padding: 0 10%;
} }
@ -248,13 +248,7 @@
} }
} }
@media screen and (max-width: 1200px) { @media (max-width: 900px) {
.top-panel {
padding: 0 10%;
}
}
@media (max-width: 1065px) {
.top-panel { .top-panel {
display: none; display: none;
} }

View file

@ -4,6 +4,7 @@ import { useSelector, useDispatch } from "react-redux";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import './Menu.scss'; import './Menu.scss';
import Spinner from 'src/components/Spinner/Spinner';
const className = height => { const className = height => {
if (height === 35) { if (height === 35) {
@ -27,7 +28,8 @@ const style = ({ menuHeight, mobile }) => {
const Menu = props => { const Menu = props => {
const { activeElement, focusedElement } = useSelector(state => state.mainNavigation); const { activeElement, focusedElement } = useSelector(state => state.mainNavigation);
const { i18n, panel, userName } = useSelector(state => state.session); const { i18n, userName } = useSelector(state => state.session);
const { panel } = useSelector(state => state.panel);
const { session } = useSelector(state => state.userSession); const { session } = useSelector(state => state.userSession);
const { user } = useSelector(state => state.menuCounters); const { user } = useSelector(state => state.menuCounters);
const dispatch = useDispatch(); const dispatch = useDispatch();
@ -50,6 +52,8 @@ const Menu = props => {
return `stat ${activeName === activeElement && 'l-active'} ${activeName === focusedElement && 'focus'}`; return `stat ${activeName === activeElement && 'l-active'} ${activeName === focusedElement && 'focus'}`;
} }
if (!panel[userName]) return <Spinner />;
return ( return (
<div className="menu-wrapper"> <div className="menu-wrapper">
<div className={className(props.menuHeight)} style={{ height: style(props) }}> <div className={className(props.menuHeight)} style={{ height: style(props) }}>
@ -62,11 +66,21 @@ const Menu = props => {
? (<> ? (<>
<div> <div>
<span>{i18n.Disk}:</span> <span>{i18n.Disk}:</span>
<span><span className="value">{user.U_DISK} <span className="unit">{panel[session.look]['U_DISK_MEASURE']}</span></span></span> <span>
<span className="value">
{panel[session.look]['U_DISK']}
<span className="unit">{panel[session.look]['U_DISK_MEASURE']}</span>
</span>
</span>
</div> </div>
<div> <div>
<span>{i18n.Bandwidth}:</span> <span>{i18n.Bandwidth}:</span>
<span><span className="value">{user.U_BANDWIDTH} <span className="unit">{panel[session.look]['U_BANDWIDTH_MEASURE']}</span></span></span> <span>
<span className="value">
{panel[session.look]['U_BANDWIDTH']}
<span className="unit">{panel[session.look]['U_BANDWIDTH_MEASURE']}</span>
</span>
</span>
</div> </div>
</>) </>)
: (<> : (<>

View file

@ -99,10 +99,6 @@
} }
} }
.stat.last {
flex: 1;
}
.l-active { .l-active {
border-bottom: 3px solid $primary; border-bottom: 3px solid $primary;

View file

@ -23,18 +23,23 @@
flex-wrap: unset; flex-wrap: unset;
width: 100%; width: 100%;
align-items: center; align-items: center;
justify-content: flex-end;
} }
a.button-extra, a.button-extra,
button.button-extra { button.button-extra {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 100%;
justify-content: flex-start;
padding: 5px 10px;
background: none; background: none;
border: none; border: none;
padding: 0 0.75rem;
text-decoration: none; text-decoration: none;
color: rgb(129, 125, 125); color: rgb(129, 125, 125);
font-size: 14px; font-size: 14px;
display: flex; display: flex;
justify-content: center;
align-items: center; align-items: center;
margin-right: 10px; margin-right: 10px;
border-radius: 3px; border-radius: 3px;
@ -152,11 +157,28 @@
} }
} }
@media (max-width: 1250px) {
.toolbar {
.r-menu {
a.button-extra,
button.button-extra {
max-width: 30%;
}
}
}
}
@media (max-width: 900px) { @media (max-width: 900px) {
.toolbar { .toolbar {
.r-menu { .r-menu {
overflow: scroll; overflow: scroll;
a.button-extra,
button.button-extra {
overflow: unset;
max-width: 100%;
}
> div { > div {
margin-left: 3rem; margin-left: 3rem;
position: relative; position: relative;
@ -164,6 +186,7 @@
flex-wrap: unset; flex-wrap: unset;
width: 100%; width: 100%;
align-items: center; align-items: center;
justify-content: flex-start;
} }
.select-wrapper + div { .select-wrapper + div {

View file

@ -3,7 +3,7 @@
label.label-wrapper { label.label-wrapper {
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
width: max-content; width: fit-content;
span { span {
font-weight: normal; font-weight: normal;

View file

@ -9,6 +9,7 @@ import { useSelector } from 'react-redux';
const Package = props => { const Package = props => {
const { data } = props; const { data } = props;
const { i18n } = useSelector(state => state.session); const { i18n } = useSelector(state => state.session);
const { session } = useSelector(state => state.userSession);
const printNameServers = servers => { const printNameServers = servers => {
let serversArray = servers.split(','); let serversArray = servers.split(',');
@ -50,7 +51,7 @@ const Package = props => {
<div className="stats"> <div className="stats">
<Container className="c-1 w-30"> <Container className="c-1 w-30">
<div>{i18n['Web Template']}: <span><span className="stat">{data.WEB_TEMPLATE}</span></span></div> <div>{i18n['Web Template']}: <span><span className="stat">{data.WEB_TEMPLATE}</span></span></div>
<div>{i18n['Proxy Template']}: <span><span className="stat">{data.PROXY_TEMPLATE}</span></span></div> {session.PROXY_SYSTEM && <div>{i18n['Proxy Template']}: <span><span className="stat">{data.PROXY_TEMPLATE}</span></span></div>}
<div>{i18n['DNS Template']}: <span><span className="stat">{data.DNS_TEMPLATE}</span></span></div> <div>{i18n['DNS Template']}: <span><span className="stat">{data.DNS_TEMPLATE}</span></span></div>
<div>{i18n['SSH Access']}: <span><span className="stat">{data.SHELL}</span></span></div> <div>{i18n['SSH Access']}: <span><span className="stat">{data.SHELL}</span></span></div>
<div>{i18n['Web Domains']}: <span><span className="stat">{data.WEB_DOMAINS}</span></span></div> <div>{i18n['Web Domains']}: <span><span className="stat">{data.WEB_DOMAINS}</span></span></div>

View file

@ -1,7 +1,7 @@
.content .edit-template.edit-bind9 { .content .edit-template.edit-bind9 {
.toolbar { .toolbar {
.search-toolbar-name { .search-toolbar-name {
width: max-content; width: fit-content;
} }
} }

View file

@ -1,7 +1,7 @@
.content .edit-template.edit-bind9 { .content .edit-template.edit-bind9 {
.toolbar { .toolbar {
.search-toolbar-name { .search-toolbar-name {
width: max-content; width: fit-content;
} }
} }

View file

@ -6,6 +6,7 @@ import { Link } from 'react-router-dom';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
const EditDatabaseOption = ({ data, visible }) => { const EditDatabaseOption = ({ data, visible }) => {
const { DB_PMA_URL, DB_PGA_URL } = useSelector(state => state.userSession.session);
const { i18n } = useSelector(state => state.session); const { i18n } = useSelector(state => state.session);
const printPhpMyAdminHosts = () => { const printPhpMyAdminHosts = () => {
@ -85,7 +86,7 @@ const EditDatabaseOption = ({ data, visible }) => {
<> <>
<TextInput <TextInput
title={i18n['phpMyAdmin URL']} title={i18n['phpMyAdmin URL']}
value={data.mail_url} value={DB_PMA_URL}
name="v_mysql_url" name="v_mysql_url"
id="mysql_url" /> id="mysql_url" />
@ -108,7 +109,7 @@ const EditDatabaseOption = ({ data, visible }) => {
<> <>
<TextInput <TextInput
title={i18n['phpPgAdmin URL']} title={i18n['phpPgAdmin URL']}
value={data.pgsql_url} value={DB_PGA_URL}
name="v_pgsql_url" name="v_pgsql_url"
id="pgsql_url" /> id="pgsql_url" />

View file

@ -7,6 +7,7 @@ import { Link } from 'react-router-dom';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
const EditMailOption = ({ data, visible }) => { const EditMailOption = ({ data, visible }) => {
const { MAIL_URL } = useSelector(state => state.userSession.session);
const { i18n } = useSelector(state => state.session); const { i18n } = useSelector(state => state.session);
const [mailCertificateSystem, setMailCertificateSystem] = useState(false); const [mailCertificateSystem, setMailCertificateSystem] = useState(false);
@ -58,7 +59,7 @@ const EditMailOption = ({ data, visible }) => {
<TextInput <TextInput
title={i18n['Webmail URL']} title={i18n['Webmail URL']}
name="v_mail_url" name="v_mail_url"
value={data.mail_url} value={MAIL_URL}
id="mail-url" /> id="mail-url" />
<br /><br /> <br /><br />

View file

@ -167,12 +167,6 @@ const EditServer = props => {
name="v_language" name="v_language"
id="language" /> id="language" />
{/* <TextInput
value={state.data.port}
title={i18n['Default Port'] ?? 'Default Port'}
name="port"
id="port" /> */}
<div className="modules"> <div className="modules">
<button type="button" onClick={() => toggleOption('webOption')}> <button type="button" onClick={() => toggleOption('webOption')}>
{i18n['WEB']} {i18n['WEB']}

View file

@ -111,7 +111,7 @@
padding: 7px 15px; padding: 7px 15px;
text-transform: capitalize; text-transform: capitalize;
text-decoration: none; text-decoration: none;
width: max-content; width: fit-content;
margin-right: 10px; margin-right: 10px;
&:hover { &:hover {

View file

@ -4,7 +4,7 @@ $secondaryLight: #f8b014;
.content .edit-template.edit-httpd { .content .edit-template.edit-httpd {
.toolbar { .toolbar {
.search-toolbar-name { .search-toolbar-name {
width: max-content; width: fit-content;
a { a {
color: $secondary; color: $secondary;
@ -17,7 +17,7 @@ $secondaryLight: #f8b014;
} }
.link { .link {
width: max-content; width: fit-content;
margin-left: 15px; margin-left: 15px;
a { a {

View file

@ -1,7 +1,7 @@
.content .edit-template.edit-mysql { .content .edit-template.edit-mysql {
.toolbar { .toolbar {
.search-toolbar-name { .search-toolbar-name {
width: max-content; width: fit-content;
} }
} }

View file

@ -3,11 +3,11 @@ $secondaryLight: #f8b014;
.content .edit-template.edit-nginx { .content .edit-template.edit-nginx {
.toolbar { .toolbar {
.search-toolbar-name { .search-toolbar-name {
width: max-content; width: fit-content;
} }
.link { .link {
width: max-content; width: fit-content;
margin-left: 15px; margin-left: 15px;
a { a {

View file

@ -5,13 +5,13 @@ $textColor: #555;
.content .edit-template.edit-php { .content .edit-template.edit-php {
.toolbar { .toolbar {
.search-toolbar-name { .search-toolbar-name {
width: max-content; width: fit-content;
color: $textColor; color: $textColor;
} }
.search-toolbar-name, .search-toolbar-name,
.link { .link {
width: max-content; width: fit-content;
a { a {
text-decoration: none; text-decoration: none;

View file

@ -1,7 +1,7 @@
.content .edit-template.edit-pgsql { .content .edit-template.edit-pgsql {
.toolbar { .toolbar {
.search-toolbar-name { .search-toolbar-name {
width: max-content; width: fit-content;
} }
} }

View file

@ -1,7 +1,7 @@
.content .edit-template.edit-service { .content .edit-template.edit-service {
.toolbar { .toolbar {
.search-toolbar-name { .search-toolbar-name {
width: max-content; width: fit-content;
} }
} }

View file

@ -4,6 +4,7 @@ import { logout } from 'src/actions/Session/sessionActions';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { Link, useHistory } from 'react-router-dom'; import { Link, useHistory } from 'react-router-dom';
import Spinner from '../Spinner/Spinner'; import Spinner from '../Spinner/Spinner';
import PerfectScrollbar from 'react-perfect-scrollbar';
import './TopPanel.scss'; import './TopPanel.scss';
@ -82,9 +83,10 @@ const TopPanel = ({ menuItems = [], extraMenuItems = [] }) => {
</Link> </Link>
</div> </div>
{renderMenuItems()} <PerfectScrollbar>
{renderMenuItems()}
{renderExtraMenuItems()} {renderExtraMenuItems()}
</PerfectScrollbar>
</div> </div>
<div className="container profile-menu"> <div className="container profile-menu">

View file

@ -16,6 +16,24 @@
} }
.left-menu { .left-menu {
justify-content: unset;
.logo {
width: fit-content;
flex: unset;
}
.scrollbar-container {
&:hover {
background: none;
}
.nav-link {
flex: unset;
padding: 0 5px;
}
}
a, button { a, button {
padding: 0 !important; padding: 0 !important;
outline: none; outline: none;

View file

@ -29,7 +29,7 @@
span.stat.email{ span.stat.email{
display: block; display: block;
width: max-content; width: fit-content;
text-overflow: ellipsis; text-overflow: ellipsis;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
@ -208,7 +208,7 @@ span.stat.email{
@media (max-width: 850px) { @media (max-width: 850px) {
> div { > div {
width: max-content; width: fit-content;
a, button { a, button {
width: 100%; width: 100%;

View file

@ -20,7 +20,8 @@ import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import HtmlParser from 'react-html-parser'; import HtmlParser from 'react-html-parser';
const AddWebDomain = props => { const AddWebDomain = props => {
const { i18n, panel, userName } = useSelector(state => state.session); const { i18n, userName } = useSelector(state => state.session);
const { panel } = useSelector(state => state.panel);
const { session } = useSelector(state => state.userSession); const { session } = useSelector(state => state.userSession);
const dispatch = useDispatch(); const dispatch = useDispatch();
const token = localStorage.getItem("token"); const token = localStorage.getItem("token");

View file

@ -1,6 +1,5 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import TextArea from 'src/components/ControlPanel/AddItemLayout/Form/TextArea/TextArea'; import TextArea from 'src/components/ControlPanel/AddItemLayout/Form/TextArea/TextArea';
import './SslSupport.scss'; import './SslSupport.scss';
@ -30,7 +29,6 @@ const SslSupport = props => {
id="ssl-certificate" id="ssl-certificate"
name="v_ssl_crt" name="v_ssl_crt"
title={i18n['SSL Certificate']} title={i18n['SSL Certificate']}
value={props.sslCertificate}
disabled={letsEncrypt} disabled={letsEncrypt}
optionalTitle={<>/ <button type="button" onClick={() => props.setModalVisible(true)} className="generate-csr">{i18n['Generate CSR']}</button></>} /> optionalTitle={<>/ <button type="button" onClick={() => props.setModalVisible(true)} className="generate-csr">{i18n['Generate CSR']}</button></>} />

View file

@ -13,7 +13,7 @@
} }
&:nth-child(2) { &:nth-child(2) {
width: max-content; width: fit-content;
} }
} }
} }

View file

@ -72,7 +72,7 @@ export default function WebDomain(props) {
<Container className="r-col w-85"> <Container className="r-col w-85">
<div className="name"> <div className="name">
<div>{data.NAME}</div> <div>{data.NAME}</div>
<div><span className="dns-name-span">{data.ALIAS.replaceAll(',', ', ')}</span></div> <div><span className="dns-name-span">{data.ALIAS.replace(/,/g, ', ')}</span></div>
</div> </div>
<div>{data.IP}</div> <div>{data.IP}</div>
<div className="stats"> <div className="stats">

View file

@ -19,12 +19,16 @@
.name { .name {
display: flex; display: flex;
align-items: center;
> div:nth-child(1) { > div:nth-child(1) {
margin-right: 2rem; margin-right: 2rem;
} }
> div + div {
line-height: 10px;
margin-top: .75rem;
}
.dns-name-span { .dns-name-span {
font-style: italic; font-style: italic;
color: #858585; color: #858585;

View file

@ -106,7 +106,7 @@ const App = () => {
exact exact
component={Preview} /> component={Preview} />
<AuthenticatedRoute <AuthenticatedRoute
path="/list/server/:service" path="/list/server/service/"
authenticated={session.userName} authenticated={session.userName}
component={ServiceInfo} /> component={ServiceInfo} />
<AuthenticatedRoute <AuthenticatedRoute

View file

@ -380,7 +380,7 @@ export default function MailAccounts(props) {
<LeftButton name={i18n['Add Mail Account']} href={`/add/mail/?domain=${props.domain}`} showLeftMenu={true} /> <LeftButton name={i18n['Add Mail Account']} href={`/add/mail/?domain=${props.domain}`} showLeftMenu={true} />
<div className="r-menu"> <div className="r-menu">
<div className="input-group input-group-sm"> <div className="input-group input-group-sm">
<a href={state.webMail} className="button-extra" type="submit">{i18n['open webmail']}</a> {state.webMail && <a href={state.webMail} className="button-extra" type="submit">{i18n['open webmail']}</a>}
<Checkbox toggleAll={toggleAll} toggled={state.toggledAll} /> <Checkbox toggleAll={toggleAll} toggled={state.toggledAll} />
<Select list='mailList' bulkAction={bulk} /> <Select list='mailList' bulkAction={bulk} />
<DropdownFilter changeSorting={changeSorting} sorting={state.sorting} order={state.order} list="mailAccountList" /> <DropdownFilter changeSorting={changeSorting} sorting={state.sorting} order={state.order} list="mailAccountList" />

View file

@ -17,7 +17,7 @@
div.list-item { div.list-item {
.r-col { .r-col {
.stat.email { .stat.email {
width: max-content; width: fit-content;
text-transform: none; text-transform: none;
} }
} }

View file

@ -426,4 +426,4 @@ const Mails = props => {
); );
} }
export default Mails; export default Mails;

View file

@ -319,7 +319,7 @@ const Servers = props => {
<LeftButton href="/edit/server/" list="server" name={i18n.configure} showLeftMenu={true} /> <LeftButton href="/edit/server/" list="server" name={i18n.configure} showLeftMenu={true} />
<div className="r-menu"> <div className="r-menu">
<div className="input-group input-group-sm"> <div className="input-group input-group-sm">
<Link to="/list/server/cpu" className="button-extra">{i18n['show: CPU / MEM / NET / DISK']}</Link> <Link to="/list/server/service/?srv=cpu" className="button-extra">{i18n['show: CPU / MEM / NET / DISK']}</Link>
<Checkbox toggleAll={toggleAll} toggled={state.toggledAll} /> <Checkbox toggleAll={toggleAll} toggled={state.toggledAll} />
<Select list='serverList' bulkAction={bulk} /> <Select list='serverList' bulkAction={bulk} />
<SearchInput handleSearchTerm={term => props.changeSearchTerm(term)} /> <SearchInput handleSearchTerm={term => props.changeSearchTerm(term)} />

View file

@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
import { addActiveElement } from 'src/actions/MainNavigation/mainNavigationActions'; import { addActiveElement } from 'src/actions/MainNavigation/mainNavigationActions';
import TopPanel from 'src/components/TopPanel/TopPanel'; import TopPanel from 'src/components/TopPanel/TopPanel';
import { useParams, useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { getServiceLogs } from 'src/ControlPanelService/Server'; import { getServiceLogs } from 'src/ControlPanelService/Server';
@ -11,13 +11,12 @@ import { Helmet } from 'react-helmet';
import ReactHtmlParser from 'react-html-parser'; import ReactHtmlParser from 'react-html-parser';
import './styles.scss'; import './styles.scss';
import QueryString from 'qs';
const ServiceInfo = () => { const ServiceInfo = () => {
const { i18n, userName } = useSelector(state => state.session); const { i18n, userName } = useSelector(state => state.session);
const dispatch = useDispatch(); const dispatch = useDispatch();
const { activeElement } = useSelector(state => state.mainNavigation);
const history = useHistory(); const history = useHistory();
const { service } = useParams();
const [state, setState] = useState({ const [state, setState] = useState({
data: "", data: "",
loading: false loading: false
@ -30,14 +29,28 @@ const ServiceInfo = () => {
}, [userName]); }, [userName]);
useEffect(() => { useEffect(() => {
fetchData(); let queryParams = QueryString.parse(history.location.search, { ignoreQueryPrefix: true });
dispatch(addActiveElement(`/list/server/${service}`));
}, [activeElement]);
const fetchData = () => { if (!queryParams.srv) {
fetchData('cpu');
dispatch(addActiveElement('/list/server/service/?srv=cpu'));
return;
}
if (!menuItems.find(item => item.service === queryParams.srv)) {
dispatch(addActiveElement('/list/server/service/?srv=cpu'));
history.push('/list/server/service/?srv=cpu');
return;
}
fetchData(queryParams.srv);
dispatch(addActiveElement(`/list/server/service/?srv=${queryParams.srv}`));
}, [history.location.search]);
const fetchData = serviceName => {
setState({ ...state, loading: true }); setState({ ...state, loading: true });
getServiceLogs(service) getServiceLogs(serviceName)
.then(result => { .then(result => {
setState({ ...state, data: result.data.service_log, loading: false }); setState({ ...state, data: result.data.service_log, loading: false });
}) })
@ -49,35 +62,43 @@ const ServiceInfo = () => {
const menuItems = [ const menuItems = [
{ {
route: '/list/server/cpu', route: '/list/server/service/?srv=cpu',
service: 'cpu',
name: i18n['CPU'] name: i18n['CPU']
}, },
{ {
route: '/list/server/mem', route: '/list/server/service/?srv=mem',
service: 'mem',
name: i18n['MEMORY'] name: i18n['MEMORY']
}, },
{ {
route: '/list/server/disk', route: '/list/server/service/?srv=disk',
service: 'disk',
name: i18n['DISK'] name: i18n['DISK']
}, },
{ {
route: '/list/server/net', route: '/list/server/service/?srv=net',
service: 'net',
name: i18n['NETWORK'] name: i18n['NETWORK']
}, },
{ {
route: '/list/server/web', route: '/list/server/service/?srv=web',
service: 'web',
name: i18n['WEB'] name: i18n['WEB']
}, },
{ {
route: '/list/server/dns', route: '/list/server/service/?srv=dns',
service: 'dns',
name: i18n['DNS'] name: i18n['DNS']
}, },
{ {
route: '/list/server/mail', route: '/list/server/service/?srv=mail',
service: 'mail',
name: i18n['MAIL'] name: i18n['MAIL']
}, },
{ {
route: '/list/server/db', route: '/list/server/service/?srv=db',
service: 'db',
name: i18n['DB'] name: i18n['DB']
} }
]; ];
@ -93,7 +114,7 @@ const ServiceInfo = () => {
state.loading state.loading
? <Spinner /> ? <Spinner />
: (<pre> : (<pre>
{state.data.length && state.data.map(line => (<>{ReactHtmlParser(line)}<br /></>))} {state.data && ReactHtmlParser(state.data)}
</pre>) </pre>)
} }
</div> </div>

View file

@ -1,7 +1,36 @@
.service-info { .App .service-info {
@media screen and (max-width: 1066px) {
.top-panel {
display: flex;
}
}
@media screen and (min-width: 1200px) {
.top-panel {
padding: 0 13%;
}
}
.content { .content {
font-size: 14px; font-size: 14px;
color: #555; color: #555;
padding-top: 4rem; padding-top: 4rem;
@media screen and (min-width: 1067px) {
padding-top: 5rem !important;
margin-top: 0px !important;
}
@media screen and (max-width: 1066px) {
padding-top: 5rem !important;
margin-top: 0px !important;
}
table {
td,th {
padding: 5px 10px;
border: 1px solid black;
}
}
} }
} }

View file

@ -17,12 +17,16 @@ import { useDispatch, useSelector } from 'react-redux';
import { Helmet } from 'react-helmet'; import { Helmet } from 'react-helmet';
import './Web.scss'; import './Web.scss';
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions'; import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
import { useHistory } from 'react-router-dom';
const Web = props => { const Web = props => {
const { i18n } = useSelector(state => state.session); const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent); const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation); const { focusedElement } = useSelector(state => state.mainNavigation);
const { panel } = useSelector(state => state.panel);
const { userName } = useSelector(state => state.session);
const dispatch = useDispatch(); const dispatch = useDispatch();
const history = useHistory();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [modal, setModal] = useState({ const [modal, setModal] = useState({
text: '', text: '',
@ -40,6 +44,10 @@ const Web = props => {
}); });
useEffect(() => { useEffect(() => {
if (panel[userName]['WEB_DOMAINS'] === '0') {
return history.push('/');
}
dispatch(addActiveElement('/list/web/')); dispatch(addActiveElement('/list/web/'));
dispatch(removeFocusedElement()); dispatch(removeFocusedElement());
dispatch(removeControlPanelContentFocusedElement()); dispatch(removeControlPanelContentFocusedElement());

View file

@ -94,7 +94,7 @@ export default function WebLogs() {
</Helmet> </Helmet>
<TopPanel menuItems={menuItems} extraMenuItems={extraMenuItems} /> <TopPanel menuItems={menuItems} extraMenuItems={extraMenuItems} />
<div className="content"> <div className="content">
<h6>{state.prefix}</h6> <h6><b>{state.prefix}</b></h6>
<br /> <br />
{ {
state.loading state.loading

View file

@ -1,12 +1,30 @@
.web-logs { .App .web-logs {
.top-panel {
.left-menu {
.logo {
justify-content: start;
margin: 0;
a {
padding: 0 !important;
}
}
}
}
.content { .content {
font-size: 14px; font-size: 14px;
color: #555; color: #555;
padding-top: 4rem; padding-top: 4rem;
}
.nav-link:nth-child(3), @media screen and (min-width: 1067px) {
.nav-link:nth-child(4) { padding-top: 5rem !important;
width: 9rem; margin-top: 0px !important;
}
@media screen and (max-width: 1066px) {
padding-top: 5rem !important;
margin-top: 0px !important;
}
} }
} }

View file

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

View file

@ -0,0 +1,19 @@
import { REFRESH_PANEL } from '../../actions/Panel/panelTypes';
const INITIAL_STATE = {
panel: {}
};
const panelReducer = (state = INITIAL_STATE, action) => {
switch (action.type) {
case REFRESH_PANEL:
return {
...state,
panel: action.value.panel
};
default: return state;
}
};
export default panelReducer;

View file

@ -4,8 +4,7 @@ const INITIAL_STATE = {
token: '', token: '',
error: '', error: '',
i18n: {}, i18n: {},
userName: '', userName: ''
panel: {}
}; };
const sessionReducer = (state = INITIAL_STATE, action) => { const sessionReducer = (state = INITIAL_STATE, action) => {
@ -16,7 +15,6 @@ const sessionReducer = (state = INITIAL_STATE, action) => {
token: action.value.token, token: action.value.token,
userName: action.value.userName, userName: action.value.userName,
i18n: action.value.i18n || {}, i18n: action.value.i18n || {},
panel: action.value.panel,
error: action.value.error error: action.value.error
}; };
@ -26,7 +24,6 @@ const sessionReducer = (state = INITIAL_STATE, action) => {
token: action.value.token, token: action.value.token,
userName: action.value.userName, userName: action.value.userName,
i18n: action.value.i18n || {}, i18n: action.value.i18n || {},
panel: action.value.panel,
error: action.value.error error: action.value.error
}; };
@ -36,7 +33,6 @@ const sessionReducer = (state = INITIAL_STATE, action) => {
token: action.value.token, token: action.value.token,
userName: action.value.userName, userName: action.value.userName,
i18n: action.value.i18n || {}, i18n: action.value.i18n || {},
panel: action.value.panel,
error: action.value.error error: action.value.error
}; };
@ -45,7 +41,6 @@ const sessionReducer = (state = INITIAL_STATE, action) => {
token: action.value.token, token: action.value.token,
userName: action.value.userName, userName: action.value.userName,
i18n: action.value.i18n || {}, i18n: action.value.i18n || {},
panel: action.value.panel,
error: action.value.error error: action.value.error
}; };

View file

@ -5,6 +5,7 @@ import notificationReducer from './Notification/notificationReducer';
import menuCounterReducer from './MenuCounters/menuCounterReducer'; import menuCounterReducer from './MenuCounters/menuCounterReducer';
import userSessionReducer from './UserSession/userSessionReducer'; import userSessionReducer from './UserSession/userSessionReducer';
import sessionReducer from './Session/sessionReducer'; import sessionReducer from './Session/sessionReducer';
import panelReducer from './Panel/panel';
export default combineReducers({ export default combineReducers({
mainNavigation: mainNavigationReducer, mainNavigation: mainNavigationReducer,
@ -13,4 +14,5 @@ export default combineReducers({
menuCounters: menuCounterReducer, menuCounters: menuCounterReducer,
userSession: userSessionReducer, userSession: userSessionReducer,
session: sessionReducer, session: sessionReducer,
panel: panelReducer,
}); });