diff --git a/src/react/jsconfig.json b/src/react/jsconfig.json
index 30b25afe5..97f4bc227 100644
--- a/src/react/jsconfig.json
+++ b/src/react/jsconfig.json
@@ -2,5 +2,6 @@
"compilerOptions": {
"baseUrl": "."
},
- "include": ["src"]
+ "include": ["src"],
+ "exclude": ["node_modules", "build"]
}
diff --git a/src/react/package-lock.json b/src/react/package-lock.json
index 2409be918..749fd541c 100644
--- a/src/react/package-lock.json
+++ b/src/react/package-lock.json
@@ -11526,6 +11526,15 @@
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"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": {
"version": "7.2.1",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.1.tgz",
diff --git a/src/react/package.json b/src/react/package.json
index f371616ad..e992f9e70 100644
--- a/src/react/package.json
+++ b/src/react/package.json
@@ -25,6 +25,7 @@
"react-dom": "^16.10.2",
"react-helmet": "^6.1.0",
"react-html-parser": "^2.0.2",
+ "react-perfect-scrollbar": "^1.5.8",
"react-redux": "^7.2.1",
"react-router-dom": "^5.1.2",
"react-scripts": "^3.4.1",
diff --git a/src/react/src/actions/MenuCounters/menuCounterActions.js b/src/react/src/actions/MenuCounters/menuCounterActions.js
index 8dc5fcf5b..5d4255dc0 100644
--- a/src/react/src/actions/MenuCounters/menuCounterActions.js
+++ b/src/react/src/actions/MenuCounters/menuCounterActions.js
@@ -1,12 +1,13 @@
import { REFRESH_COUNTERS } from './menuCounterTypes';
import { checkAuth } from 'src/services/session';
import { setAuthToken } from 'src/utils/token';
+import { REFRESH_PANEL } from '../Panel/panelTypes';
export const refreshCounters = () => (dispatch, getState) => {
return new Promise((resolve, reject) => {
checkAuth()
.then(res => {
- const { data, token } = res.data;
+ const { data, token, panel } = res.data;
if (token) setAuthToken(token);
@@ -17,6 +18,13 @@ export const refreshCounters = () => (dispatch, getState) => {
}
});
+ dispatch({
+ type: REFRESH_PANEL,
+ value: {
+ panel
+ }
+ });
+
resolve(token);
})
.catch(err => {
diff --git a/src/react/src/actions/Panel/panelTypes.js b/src/react/src/actions/Panel/panelTypes.js
new file mode 100644
index 000000000..3c5615340
--- /dev/null
+++ b/src/react/src/actions/Panel/panelTypes.js
@@ -0,0 +1 @@
+export const REFRESH_PANEL = 'REFRESH_PANEL';
diff --git a/src/react/src/actions/Session/sessionActions.js b/src/react/src/actions/Session/sessionActions.js
index c28a30e49..5f1823c57 100644
--- a/src/react/src/actions/Session/sessionActions.js
+++ b/src/react/src/actions/Session/sessionActions.js
@@ -4,6 +4,7 @@ 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';
+import { REFRESH_PANEL } from '../Panel/panelTypes';
const LOGOUT_RESPONSE = 'logged_out';
const LOGOUT_AS_RESPONSE = 'logged_out_as';
@@ -19,12 +20,17 @@ export const login = (user, password) => dispatch => {
type: LOGIN,
value: {
token: token || '',
- panel,
i18n: i18n || {},
userName: user,
error
},
});
+ dispatch({
+ type: REFRESH_PANEL,
+ value: {
+ panel
+ }
+ });
dispatch({
type: REFRESH_COUNTERS,
value: {
@@ -51,11 +57,16 @@ export const reset = ({ user = '', code = '', password = '', password_confirm =
type: RESET_PASSWORD,
value: {
token,
- panel,
userName: user,
error
},
});
+ dispatch({
+ type: REFRESH_PANEL,
+ value: {
+ panel
+ }
+ });
dispatch({
type: REFRESH_COUNTERS,
value: {
@@ -84,11 +95,16 @@ export const loginAs = username => dispatch => {
value: {
userName: user,
i18n,
- panel,
token,
error
}
});
+ dispatch({
+ type: REFRESH_PANEL,
+ value: {
+ panel
+ }
+ });
dispatch({
type: REFRESH_COUNTERS,
value: {
@@ -121,12 +137,17 @@ export const logout = () => (dispatch, getState) => {
value: {
userName: '',
token: '',
- panel: {},
session: {},
i18n: [],
error,
},
});
+ dispatch({
+ type: REFRESH_PANEL,
+ value: {
+ panel: {}
+ }
+ });
dispatch({
type: REFRESH_COUNTERS,
value: {
@@ -144,12 +165,17 @@ export const logout = () => (dispatch, getState) => {
type: LOGGED_OUT_AS,
value: {
userName,
- panel,
token: '',
i18n,
error,
},
});
+ dispatch({
+ type: REFRESH_PANEL,
+ value: {
+ panel
+ }
+ });
dispatch({
type: REFRESH_COUNTERS,
value: {
@@ -185,11 +211,16 @@ export const checkAuthHandler = () => (dispatch, getState) => {
value: {
userName: user,
i18n,
- panel,
token,
error
}
});
+ dispatch({
+ type: REFRESH_PANEL,
+ value: {
+ panel
+ }
+ });
dispatch({
type: REFRESH_COUNTERS,
value: {
diff --git a/src/react/src/components/Backup/RestoreSettings/BackupRestoreSettings.jsx b/src/react/src/components/Backup/RestoreSettings/BackupRestoreSettings.jsx
index 7043d56f7..ffb3e808a 100644
--- a/src/react/src/components/Backup/RestoreSettings/BackupRestoreSettings.jsx
+++ b/src/react/src/components/Backup/RestoreSettings/BackupRestoreSettings.jsx
@@ -18,7 +18,6 @@ import './BackupRestoreSettings.scss';
export default function BackupRestoreSettings(props) {
const { i18n } = useSelector(state => state.session);
- const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
diff --git a/src/react/src/components/ControlPanel/AddItemLayout/AddItemLayout.scss b/src/react/src/components/ControlPanel/AddItemLayout/AddItemLayout.scss
index 403f0b28c..12b4c548d 100644
--- a/src/react/src/components/ControlPanel/AddItemLayout/AddItemLayout.scss
+++ b/src/react/src/components/ControlPanel/AddItemLayout/AddItemLayout.scss
@@ -23,7 +23,7 @@ $errorColor: #BE5ABF;
div.error,
div.success {
- width: max-content !important;
+ width: fit-content !important;
span {
font-weight: bold;
@@ -58,6 +58,7 @@ $errorColor: #BE5ABF;
width: auto !important;
padding: 10px 0;
margin-left: 0;
+ margin-right: 10px;
}
}
}
@@ -211,7 +212,7 @@ $errorColor: #BE5ABF;
label.label-wrapper {
display: flex;
align-items: flex-end;
- width: max-content;
+ width: fit-content;
span {
font-weight: normal;
diff --git a/src/react/src/components/ControlPanel/AddItemLayout/Form/Password/Password.jsx b/src/react/src/components/ControlPanel/AddItemLayout/Form/Password/Password.jsx
index 839e4f8ad..9c89a98f1 100644
--- a/src/react/src/components/ControlPanel/AddItemLayout/Form/Password/Password.jsx
+++ b/src/react/src/components/ControlPanel/AddItemLayout/Form/Password/Password.jsx
@@ -30,6 +30,7 @@ const Password = ({ defaultValue, onChange = () => { }, id, name, title, showGen
}
setState({ ...state, generatedPassword: result });
+ onChange(result);
}
const passwordInputHandler = value => {
diff --git a/src/react/src/components/Firewall/Add/AddFirewall.scss b/src/react/src/components/Firewall/Add/AddFirewall.scss
index 05d56dc08..aff53e9fd 100644
--- a/src/react/src/components/Firewall/Add/AddFirewall.scss
+++ b/src/react/src/components/Firewall/Add/AddFirewall.scss
@@ -1,6 +1,6 @@
.content .edit-template.add-firewall {
.toolbar .search-toolbar-name {
- width: max-content;
+ width: fit-content;
}
label.label-wrapper[for=ip] span {
diff --git a/src/react/src/components/InternetProtocol/InternetProtocol.jsx b/src/react/src/components/InternetProtocol/InternetProtocol.jsx
index 6b4e88dce..fbdda12e6 100644
--- a/src/react/src/components/InternetProtocol/InternetProtocol.jsx
+++ b/src/react/src/components/InternetProtocol/InternetProtocol.jsx
@@ -50,7 +50,7 @@ const InternetProtocol = props => {
{i18n.Owner}: {data.OWNER}
- {i18n.Users}: {data.U_SYS_USERS.replaceAll(',', ', ')}
+ {i18n.Users}: {data.U_SYS_USERS.replace(/,/g, ', ')}
diff --git a/src/react/src/components/MailAccount/Add/AddMailAccount.jsx b/src/react/src/components/MailAccount/Add/AddMailAccount.jsx
index 1413eb595..8e68af96f 100644
--- a/src/react/src/components/MailAccount/Add/AddMailAccount.jsx
+++ b/src/react/src/components/MailAccount/Add/AddMailAccount.jsx
@@ -48,14 +48,18 @@ export default function AddMailAccount(props) {
event.preventDefault();
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['ok_acc'] = 'add';
newMailDomain['token'] = token;
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) {
setState({ ...state, loading: true });
@@ -195,8 +199,8 @@ export default function AddMailAccount(props) {
+ name="v_send_email"
+ id="send_email" />
diff --git a/src/react/src/components/MailAccount/Add/AddMailAccount.scss b/src/react/src/components/MailAccount/Add/AddMailAccount.scss
index 5d4e5a606..f09dd23d7 100644
--- a/src/react/src/components/MailAccount/Add/AddMailAccount.scss
+++ b/src/react/src/components/MailAccount/Add/AddMailAccount.scss
@@ -1,6 +1,6 @@
.content .edit-template.add-mail-account {
.search-toolbar-name {
- width: max-content;
+ width: fit-content;
}
form {
diff --git a/src/react/src/components/MailAccount/Edit/EditMailAccount.jsx b/src/react/src/components/MailAccount/Edit/EditMailAccount.jsx
index 0457af439..d0d8ca4c1 100644
--- a/src/react/src/components/MailAccount/Edit/EditMailAccount.jsx
+++ b/src/react/src/components/MailAccount/Edit/EditMailAccount.jsx
@@ -63,10 +63,12 @@ export default function EditMailAccount(props) {
if (error_msg) {
setErrorMessage(error_msg);
setOkMessage('');
+ setState({ ...state, loading: false });
} else {
dispatch(refreshCounters()).then(() => {
setErrorMessage('');
setOkMessage(ok_msg);
+ setState({ ...state, loading: false });
});
}
}
@@ -200,7 +202,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 9a233a435..efd02a7b3 100644
--- a/src/react/src/components/MailAccount/MailInfoBlock/MailInfoBlock.jsx
+++ b/src/react/src/components/MailAccount/MailInfoBlock/MailInfoBlock.jsx
@@ -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 (
@@ -109,15 +127,7 @@ export default function MailInfoBlock({ webMail, hostName, domain, userName = ''
{webMail}
-
-
-
-
-
-
-
-
-
+
diff --git a/src/react/src/components/MainNav/Mobile/MobileTopNav.scss b/src/react/src/components/MainNav/Mobile/MobileTopNav.scss
index 33d40a183..a84541eb8 100644
--- a/src/react/src/components/MainNav/Mobile/MobileTopNav.scss
+++ b/src/react/src/components/MainNav/Mobile/MobileTopNav.scss
@@ -45,7 +45,7 @@
justify-content: center;
align-items: center;
padding: 0 10px !important;
- width: max-content;
+ width: fit-content;
height: 100%;
text-decoration: none;
color: $black;
diff --git a/src/react/src/components/MainNav/Panel/Notifications/Notifications.jsx b/src/react/src/components/MainNav/Panel/Notifications/Notifications.jsx
index c5517f945..09644996f 100644
--- a/src/react/src/components/MainNav/Panel/Notifications/Notifications.jsx
+++ b/src/react/src/components/MainNav/Panel/Notifications/Notifications.jsx
@@ -14,7 +14,8 @@ const Notifications = () => {
const [loading, setLoading] = useState(false);
useEffect(() => {
- if (!notifications) {
+ if (!notifications.length) {
+ console.log(notifications);
fetchData();
}
}, [notifications]);
@@ -47,7 +48,7 @@ const Notifications = () => {
}
const renderOptions = () => {
- if (notifications && notifications.length) {
+ if (notifications.length) {
return notifications.map(item => {
return (
<>
@@ -74,7 +75,7 @@ const Notifications = () => {