dispatch(addActiveElement('/list/user/'))}>
-
+
+

+
-
-
-
-
-
-
-
-
-
+ {userName === 'admin' && (<>
+
+ handleState("/list/package/", event)} onKeyPress={event => event.preventDefault()}>{i18n.Packages}
+
+
+ handleState("/list/ip/", event)} onKeyPress={event => event.preventDefault()}>{i18n.IP}
+
+
+ handleState("/list/rrd/", event)} onKeyPress={event => event.preventDefault()}>{i18n.Graphs}
+
+ >)}
-
+ handleState("/list/stats/", event)} onKeyPress={event => event.preventDefault()}>{i18n.Statistics}
-
+ handleState("/list/log/", event)} onKeyPress={event => event.preventDefault()}>{i18n.Log}
-
-
-
- {session.session.FIREWALL_SYSTEM &&
-
+ {userName === 'admin' && (<>
+
+ handleState("/list/updates/", event)} onKeyPress={event => event.preventDefault()}>{i18n.Updates}
+
+ {session.session.FIREWALL_SYSTEM &&
+ handleState("/list/firewall/", event)} onKeyPress={event => event.preventDefault()}>{i18n.Firewall}
+
}
+ >)}
+ {session.session.FILEMANAGER_KEY &&
+ {i18n['File Manager']}
}
- {session.session.FILEMANAGER_KEY &&
-
{i18n['File Manager']}
+ {session.session.SOFTACULOUS === "yes" &&
}
- {session.session.SOFTACULOUS === "yes" &&
}
-
-
+ {userName === 'admin' && (
+
+ handleState("/list/server/", event)} onKeyPress={event => event.preventDefault()}>{i18n.Server}
+
+ )}
-
{session.userName}
+
+
+ {look
+ ?
+ {user}
+
+ {look}
+
+ : session.userName
+ }
+
+
diff --git a/web/js/react/src/components/MainNav/Panel/Panel.scss b/web/js/react/src/components/MainNav/Panel/Panel.scss
index f90b80fbb..d66fe02e3 100644
--- a/web/js/react/src/components/MainNav/Panel/Panel.scss
+++ b/web/js/react/src/components/MainNav/Panel/Panel.scss
@@ -1,3 +1,14 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
.top-panel.small-device {
display: none;
}
@@ -10,7 +21,7 @@
width: 100%;
text-align: center;
color: white;
- background: #111;
+ background: #222e44;
height: 34px;
align-items: center;
padding: 0 13%;
@@ -22,13 +33,10 @@
width: 80%;
height: 100%;
- .logo .logo-img {
- background-image: url("/images/sprite.png?1446554103");
- background-position: -117px -57px;
- background-repeat: no-repeat;
- height: 22px;
- width: 70px;
- margin-left: -2px;
+ .logo div {
+ img {
+ width: 82%;
+ }
&:hover {
background-color: transparent;
@@ -65,7 +73,7 @@
background: white;
a, button {
- color: #f79b44;
+ color: $secondary;
font-weight: bold;
&:hover {
@@ -73,13 +81,13 @@
}
&:active {
- background: #ff6701;
+ background: $secondaryActive;
color: white;
}
}
&:hover {
- background: #f79b44;
+ background: $secondaryLight;
}
}
}
@@ -91,9 +99,11 @@
div {
width: 7rem;
height: 100%;
+ transform: translateX(-5px);
+ padding-right: 5px;
&:hover {
- background: #f79b44;
+ background: $secondaryLight;
}
}
@@ -113,8 +123,7 @@
.top-link.focus {
a, button {
- color: #5edad0;
- text-decoration: underline;
+ color: $secondaryActive;
}
}
}
@@ -129,20 +138,21 @@
div.bell {
width: auto;
- color: #C0E60E;
+ color: $secondary;
+ padding: 3px 0;
svg {
border-radius: 30px;
- width: 25px;
- height: 25px;
- padding: 5px;
+ width: 100%;
+ height: 100%;
+ padding: 3px;
&:hover {
- background: rgba(255, 255, 255, 0.4);
+ background: #79522294;
}
- &:hover {
- background: #c0e6198a;
+ &:active {
+ background: #866032;
}
}
}
@@ -152,11 +162,11 @@
font-weight: 700;
&:hover {
- color: #ffd62e;
+ color: $secondaryLight;
}
&:active {
- color: #f79b44;
+ color: $secondaryActive;
}
}
@@ -167,11 +177,40 @@
font-weight: 100;
&:hover {
- color: #C0E60E;
+ color: $secondaryLight;
}
&:active {
- color: #ffd62e;
+ color: $secondaryActive;
+ }
+ }
+ }
+}
+
+.top-panel.long-profile {
+ .left-menu {
+ width: 75%;
+ }
+
+ .profile-menu {
+ width: 25%;
+
+ > div + div {
+ width: max-content;
+ }
+
+ .long-username {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: auto;
+
+ > span:nth-child(1) {
+ margin-right: 5px;
+ }
+
+ > span:nth-child(3) {
+ margin-left: 5px;
}
}
}
diff --git a/web/js/react/src/components/MainNav/Stat-menu/Menu.jsx b/web/js/react/src/components/MainNav/Stat-menu/Menu.jsx
index 07675b88f..7b54618d1 100644
--- a/web/js/react/src/components/MainNav/Stat-menu/Menu.jsx
+++ b/web/js/react/src/components/MainNav/Stat-menu/Menu.jsx
@@ -1,7 +1,7 @@
import React, { useEffect } from 'react';
import { addActiveElement } from '../../../actions/MainNavigation/mainNavigationActions';
import { useSelector, useDispatch } from "react-redux";
-import { useHistory } from "react-router-dom";
+import { Link } from "react-router-dom";
import './Menu.scss';
@@ -26,12 +26,9 @@ const style = ({ menuHeight, mobile }) => {
}
const Menu = props => {
- const session = useSelector(state => state.session);
const { activeElement, focusedElement } = useSelector(state => state.mainNavigation);
- const { user } = useSelector(state => state.session);
- const { i18n } = window.GLOBAL.App;
+ const { user, i18n, session: { look } } = useSelector(state => state.session);
const dispatch = useDispatch();
- const history = useHistory();
useEffect(() => {
if (user.LANGUAGE) {
@@ -40,8 +37,10 @@ const Menu = props => {
}, [user]);
const handleState = (tab, event) => {
- event.preventDefault();
- history.push(tab);
+ if (`${window.location.pathname}${window.location.search}` === tab) {
+ return event.preventDefault();
+ }
+
dispatch(addActiveElement(tab));
}
@@ -49,77 +48,100 @@ const Menu = props => {
return `stat ${activeName === activeElement && 'l-active'} ${activeName === focusedElement && 'focus'}`;
}
+ const sizeFormatter = (bytes, decimals) => {
+ if (!bytes) return null;
+
+ if (bytes === "0") {
+ return
0 b;
+ }
+
+ let k = 1024,
+ dm = decimals <= 0 ? 0 : decimals || 2,
+ sizes = ['b', 'kb', 'Mb', 'GB'],
+ i = Math.floor(Math.log(bytes) / Math.log(k));
+ return (
{parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} {sizes[i]});
+ }
+
return (
-
+
-
+
-
+
-
+
-
+
-
+
-
+
);
}
-export default Menu;
\ No newline at end of file
+export default Menu;
diff --git a/web/js/react/src/components/MainNav/Stat-menu/Menu.scss b/web/js/react/src/components/MainNav/Stat-menu/Menu.scss
index 67def7320..b6e8010cc 100644
--- a/web/js/react/src/components/MainNav/Stat-menu/Menu.scss
+++ b/web/js/react/src/components/MainNav/Stat-menu/Menu.scss
@@ -1,3 +1,14 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
.menu-wrapper {
position: fixed;
width: 100%;
@@ -71,10 +82,10 @@
&:hover {
cursor: pointer;
- border-bottom: 3px solid #ff6701;
+ border-bottom: 3px solid $secondaryLight;
h3 {
- color: #ff6701;
+ color: $secondary;
}
.stats {
@@ -83,10 +94,10 @@
}
&:active {
- border-color: #f72b44;
+ border-color: $secondaryActive;
h3 {
- color: #f72b44;
+ color: $secondary;
}
}
@@ -102,20 +113,20 @@
}
.l-active {
- border-bottom: 3px solid #ff6701;
+ border-bottom: 3px solid $primary;
h3 {
- color: #ff6701;
+ color: $primary;
font-size: 18px;
margin-bottom: 25px;
}
}
.stat.focus {
- border-bottom: 3px solid #5edad0 !important;
+ border-bottom: 3px solid $secondaryLight !important;
a, h3 {
- color: #36B3A9 !important;
+ color: $secondaryLight !important;
}
}
}
@@ -203,7 +214,7 @@
}
.stat.l-active {
- background: #ff67010d;
+ background: #fdac020d;
}
}
}
diff --git a/web/js/react/src/components/MainNav/Toolbar/Checkbox/Checkbox.jsx b/web/js/react/src/components/MainNav/Toolbar/Checkbox/Checkbox.jsx
index e1277dd1f..2323277d4 100644
--- a/web/js/react/src/components/MainNav/Toolbar/Checkbox/Checkbox.jsx
+++ b/web/js/react/src/components/MainNav/Toolbar/Checkbox/Checkbox.jsx
@@ -1,4 +1,5 @@
import React from 'react';
+import { useSelector } from 'react-redux';
import './Checkbox.scss';
function toggleAll(props, e) {
@@ -6,13 +7,15 @@ function toggleAll(props, e) {
}
const Checkbox = (props) => {
+ const { i18n } = useSelector(state => state.session);
+
return (
);
diff --git a/web/js/react/src/components/MainNav/Toolbar/DropdownFilter/DropdownFilter.jsx b/web/js/react/src/components/MainNav/Toolbar/DropdownFilter/DropdownFilter.jsx
index f4659d164..27b8fa800 100644
--- a/web/js/react/src/components/MainNav/Toolbar/DropdownFilter/DropdownFilter.jsx
+++ b/web/js/react/src/components/MainNav/Toolbar/DropdownFilter/DropdownFilter.jsx
@@ -1,9 +1,11 @@
-import React, { Component } from 'react';
+import React, { useState } from 'react';
+import { useSelector } from 'react-redux';
import './DropdownFilter.scss';
-const { i18n } = window.GLOBAL.App;
-class DropdownFilter extends Component {
- state = {
+const DropdownFilter = props => {
+ const { i18n } = useSelector(state => state.session);
+
+ const state = {
usersList: [i18n.Date, i18n.Username, i18n.Disk, i18n.Bandwidth, i18n.Starred],
webList: [i18n.Date, i18n.Domain, i18n['IP Addresses'], i18n.Disk, i18n.Bandwidth, i18n.Starred],
dnsList: [i18n.Date, i18n.Expire, i18n.Domain, i18n['IP Addresses'], i18n.Records, i18n.Starred],
@@ -15,57 +17,55 @@ class DropdownFilter extends Component {
internetProtocolsList: [i18n.Date, i18n.IP, i18n.Netmask, i18n.Interface, i18n.Domain, i18n.Owner, i18n.Starred],
firewallList: [i18n.Action, i18n.Protocol, i18n.Port, i18n['IP Addresses'], i18n.Comment, i18n.Starred],
searchList: [i18n.Date, i18n.Name, i18n.Starred]
+ };
+
+ const changeSorting = (type, order) => {
+ props.changeSorting(type, order);
}
- changeSorting = (type, order) => {
- this.props.changeSorting(type, order);
- }
-
- filterClassName = (sorting, order) => {
- if (this.props.sorting === sorting && this.props.order === order) {
+ const filterClassName = (sorting, order) => {
+ if (props.sorting === sorting && props.order === order) {
return "dropdown-item active";
}
return "dropdown-item";
}
- renderFilters = () => {
- const { list } = this.props;
- let activeListFilter = this.state[list];
+ const renderFilters = () => {
+ const { list } = props;
+ let activeListFilter = state[list];
return activeListFilter.map((item, index) => {
return (
- this.changeSorting(item, "descending")}>{item}↓
- this.changeSorting(item, "ascending")}>↑
+ changeSorting(item, "descending")}>{item}↓
+ changeSorting(item, "ascending")}>↑
);
});
}
- button = () => {
- if (this.props.order === "descending") {
+ const button = () => {
+ if (props.order === "descending") {
return
↓;
} else {
return
↑;
}
}
- render() {
- return (
-
-
-
-
- {this.renderFilters()}
-
-
-
- );
- }
+ return (
+
+
+
+
+ );
}
export default DropdownFilter;
\ No newline at end of file
diff --git a/web/js/react/src/components/MainNav/Toolbar/LeftButton/LeftButton.scss b/web/js/react/src/components/MainNav/Toolbar/LeftButton/LeftButton.scss
index 2f9d67ede..1e37bbfdc 100644
--- a/web/js/react/src/components/MainNav/Toolbar/LeftButton/LeftButton.scss
+++ b/web/js/react/src/components/MainNav/Toolbar/LeftButton/LeftButton.scss
@@ -1,3 +1,14 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
.l-menu {
transform: translate(35px, 50%);
@@ -5,7 +16,7 @@
display: flex;
justify-content: center;
align-items: center;
- background: #aacb0c;
+ background: $primary;
border-radius: 100%;
color: white;
width: 45px;
@@ -15,10 +26,30 @@
text-decoration: none;
&:hover {
- background: #c1e411;
+ background: $primaryLight;
span.add {
display: block;
+ color: $hoverButtonText;
+ background: $primaryLight;
+ }
+
+ svg {
+ color: $hoverButtonText;
+ }
+ }
+
+ &:active {
+ background: $primary;
+
+ span.add {
+ display: block;
+ color: $activeButtonText;
+ background: $primary;
+ }
+
+ svg {
+ color: $activeButtonText;
}
}
@@ -26,7 +57,7 @@
width: max-content;
display: none;
padding: 4px 10px 4px 25px;
- background: #aacb0c;
+ background: $primary;
border-radius: 15px;
color: white;
font-size: 15px;
@@ -52,7 +83,7 @@
.l-menu {
&.server-icon {
a, span.add {
- background: #55c9c0;
+ background: $primary;
}
}
diff --git a/web/js/react/src/components/MainNav/Toolbar/Select/Select.jsx b/web/js/react/src/components/MainNav/Toolbar/Select/Select.jsx
index 1c79cab31..90790f705 100644
--- a/web/js/react/src/components/MainNav/Toolbar/Select/Select.jsx
+++ b/web/js/react/src/components/MainNav/Toolbar/Select/Select.jsx
@@ -1,13 +1,14 @@
-import React, { Component } from 'react';
+import React, { useEffect, useState } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { values } from '../../../../ControlPanelService/Select';
+import { useSelector } from 'react-redux';
import './Select.scss';
-const { i18n } = window.GLOBAL.App;
-const listValues = values(i18n);
+const Select = props => {
+ const { i18n } = useSelector(state => state.session);
+ const listValues = values(i18n);
-class Select extends Component {
- state = {
+ const [state, setState] = useState({
usersList: listValues.usersList,
webList: listValues.webList,
dnsList: listValues.dnsList,
@@ -24,56 +25,54 @@ class Select extends Component {
backupDetailList: listValues.backupDetailList,
banList: listValues.banList,
selected: '',
- };
+ });
- defaultValue = () => {
- if (this.props.list === 'statisticsList') {
+ useEffect(() => {
+ const { list } = props;
+ setState({ ...state, list });
+ }, []);
+
+ const defaultValue = () => {
+ if (props.list === 'statisticsList') {
return i18n['show per user'];
}
return i18n['apply to selected'];
}
- componentDidMount() {
- const { list } = this.props;
-
- this.setState({ list });
- }
-
- renderOptions = () => {
- const { list } = this.props;
- let activeList = this.state[list];
+ const renderOptions = () => {
+ const { list } = props;
+ let activeList = state[list];
if (list === 'statisticsList') {
- return this.props.users.map((item, index) => { return
});
+ return props.users.map((item, index) => { return
});
} else {
return activeList.map((item, index) => { return
});
}
}
- handleSelect = event => {
- this.setState({ selected: event.target.value });
+ const handleSelect = event => {
+ setState({ ...state, selected: event.target.value });
}
- bulkAction = () => {
- this.props.bulkAction(this.state.selected);
+ const bulkAction = () => {
+ props.bulkAction(state.selected);
+ setState({ ...state, selected: '' });
}
- render() {
- return (
-
-
-
-
-
+ return (
+
+
+
+
- );
- }
+
+ );
}
-export default Select;
\ No newline at end of file
+export default Select;
diff --git a/web/js/react/src/components/Menu/Menu.jsx b/web/js/react/src/components/Menu/Menu.jsx
index 89e0174c1..2f2365ba5 100644
--- a/web/js/react/src/components/Menu/Menu.jsx
+++ b/web/js/react/src/components/Menu/Menu.jsx
@@ -1,27 +1,29 @@
-import React, { Component } from 'react';
+import React, { createRef, useEffect } from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import './Menu.scss';
+import { useSelector } from 'react-redux';
+import { Link } from 'react-router-dom';
-class Menu extends Component {
+const Menu = (props) => {
+ const { i18n } = useSelector(state => state.session);
+ const inputFile = createRef();
- componentDidMount = () => {
- document.addEventListener("keydown", this.hotKeys);
+ useEffect(() => {
+ document.addEventListener("keydown", hotKeys);
+
+ return () => document.removeEventListener("keydown", hotKeys);
+ }, []);
+
+ const newFile = () => {
+ props.openModal("Add file");
}
- componentWillUnmount = () => {
- document.removeEventListener("keydown", this.hotKeys);
+ const newDirectory = () => {
+ props.openModal("Add directory");
}
- newFile = () => {
- this.props.openModal("Add file");
- }
-
- newDirectory = () => {
- this.props.openModal("Add directory");
- }
-
- delete = () => {
- const { selection, openModal, cursor } = this.props;
+ const deleteFile = () => {
+ const { selection, openModal, cursor } = props;
if (selection.length === 0) {
if (cursor === 0) {
openModal("Nothing selected");
@@ -33,24 +35,24 @@ class Menu extends Component {
}
}
- rename = () => {
- if (this.props.cursor === 0) {
- this.props.openModal("Nothing selected");
+ const rename = () => {
+ if (props.cursor === 0) {
+ props.openModal("Nothing selected");
} else {
- this.props.openModal("Rename");
+ props.openModal("Rename");
}
}
- permissions = () => {
- if (this.props.cursor === 0) {
- this.props.openModal("Nothing selected");
+ const permissions = () => {
+ if (props.cursor === 0) {
+ props.openModal("Nothing selected");
} else {
- this.props.openModal("Permissions");
+ props.openModal("Permissions");
}
}
- move = () => {
- const { selection, openModal, cursor } = this.props;
+ const move = () => {
+ const { selection, openModal, cursor } = props;
if (selection.length === 0) {
if (cursor === 0) {
openModal("Nothing selected");
@@ -62,8 +64,8 @@ class Menu extends Component {
}
}
- archive = () => {
- const { selection, openModal, cursor } = this.props;
+ const archive = () => {
+ const { selection, openModal, cursor } = props;
if (selection.length === 0) {
if (cursor === 0) {
@@ -76,16 +78,16 @@ class Menu extends Component {
}
}
- extract = () => {
- if (this.props.cursor === 0) {
- this.props.openModal("Nothing selected");
+ const extract = () => {
+ if (props.cursor === 0) {
+ props.openModal("Nothing selected");
} else {
- this.props.openModal("Extract");
+ props.openModal("Extract");
}
}
- copy = () => {
- const { selection, openModal, cursor } = this.props;
+ const copy = () => {
+ const { selection, openModal, cursor } = props;
if (selection.length === 0) {
if (cursor === 0) {
openModal("Nothing selected");
@@ -97,87 +99,84 @@ class Menu extends Component {
}
}
- upload = (e) => {
+ const upload = (e) => {
if (e.target.files.length === 0) {
return;
}
- this.props.upload(e.target.files);
+ props.upload(e.target.files);
}
- download = () => {
- if (this.props.cursor === 0) {
- this.props.openModal("Nothing selected");
- } else if (this.props.itemType === "d") {
- this.props.openModal("Nothing selected", null, true);
+ const download = () => {
+ if (props.cursor === 0) {
+ props.openModal("Nothing selected");
+ } else if (props.itemType === "d") {
+ props.openModal("Nothing selected", null, true);
} else {
- this.props.download();
+ props.download();
}
}
- hotKeys = (e) => {
- if (this.props.modalVisible) {
+ const hotKeys = (e) => {
+ if (props.modalVisible) {
return;
}
if (e.shiftKey && e.keyCode === 117) {
- this.rename();
+ rename();
}
switch (e.keyCode) {
- case 46: return this.delete();
- case 65: return this.archive();
- case 68: return this.download();
- case 77: return this.move();
- case 78: return this.newFile();
- case 85: return this.inputFile.click();
- case 113: return this.rename();
- case 115: return this.permissions();
- case 116: return this.copy();
- case 118: return this.newDirectory();
- case 119: return this.delete();
+ case 46: return deleteFile();
+ case 65: return archive();
+ case 68: return download();
+ case 77: return move();
+ case 78: return newFile();
+ case 85: return inputFile.click();
+ case 113: return rename();
+ case 115: return permissions();
+ case 116: return copy();
+ case 118: return newDirectory();
+ case 119: return deleteFile();
default: break;
}
}
- render() {
- let matchArchive = this.props.name.match(/.zip|.tgz|.tar.gz|.gzip|.tbz|.tar.bz|.gz|.zip|.tar|.rar/g);
- const { i18n } = window.GLOBAL.App;
+ let matchArchive = props.name.match(/.zip|.tgz|.tar.gz|.gzip|.tbz|.tar.bz|.gz|.zip|.tar|.rar/g);
- return (
-
-
-
- this.inputFile = inputFile} />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {matchArchive ? null : }
- {matchArchive ? null : }
- {matchArchive ? : null}
- {matchArchive ? : null}
-
-
-
+ return (
+
+
+
+

+
- );
- }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {matchArchive ? null : }
+ {matchArchive ? null : }
+ {matchArchive ? : null}
+ {matchArchive ? : null}
+
+
+
+
+ );
}
-export default Menu;
\ No newline at end of file
+export default Menu;
diff --git a/web/js/react/src/components/Menu/Menu.scss b/web/js/react/src/components/Menu/Menu.scss
index 0291028c6..2eb9abb7f 100644
--- a/web/js/react/src/components/Menu/Menu.scss
+++ b/web/js/react/src/components/Menu/Menu.scss
@@ -1,21 +1,33 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
.menu {
display: flex;
background: #f8f9fa;
height: 40px;
.logo {
+ width: 7rem;
padding-left: 5px;
display: flex;
justify-content: center;
align-items: center;
img {
- width: 80%;
+ width: 82%;
}
}
.btn-group {
- padding: 0;
+ padding: 0 0 0 10px;
margin: 0;
font-size: 17px;
border-radius: 0;
@@ -34,11 +46,11 @@
margin-left: 2px;
color: white;
border-radius: 4px;
- background: #AACC0D;
+ background: $primary;
&:hover {
- color: white;
- background: rgb(184, 221, 17);
+ color: $primary;
+ background: $primaryLight;
}
}
@@ -54,7 +66,7 @@
text-align: center;
&:hover {
- color: rgb(1, 148, 148);
+ color: $primary;
}
&:focus {
@@ -92,11 +104,11 @@
.small {
&:hover {
.file, .folder-close, .download, .copy {
- color: #aacc0d;
+ color: $primary;
}
.italic, .user, .paste {
- color: #44a8b3;
+ color: $primary;
}
.trash {
@@ -104,7 +116,7 @@
}
.book {
- color: rgb(216, 186, 77);
+ color: $primary;
}
}
}
diff --git a/web/js/react/src/components/Modal/AddDirectory.jsx b/web/js/react/src/components/Modal/AddDirectory.jsx
index 7bc069ba0..d94b483b5 100644
--- a/web/js/react/src/components/Modal/AddDirectory.jsx
+++ b/web/js/react/src/components/Modal/AddDirectory.jsx
@@ -1,8 +1,10 @@
import React from 'react';
+import { useSelector } from 'react-redux';
-const { i18n } = window.GLOBAL.App;
const AddDirectory = (props) => {
+ const { i18n } = useSelector(state => state.session);
+
return (
diff --git a/web/js/react/src/components/Modal/AddFile.jsx b/web/js/react/src/components/Modal/AddFile.jsx
index 76af4985b..cbd96bd89 100644
--- a/web/js/react/src/components/Modal/AddFile.jsx
+++ b/web/js/react/src/components/Modal/AddFile.jsx
@@ -1,8 +1,9 @@
import React from 'react';
-
-const { i18n } = window.GLOBAL.App;
+import { useSelector } from 'react-redux';
const AddFile = (props) => {
+ const { i18n } = useSelector(state => state.session);
+
return (
diff --git a/web/js/react/src/components/Modal/Archive.jsx b/web/js/react/src/components/Modal/Archive.jsx
index 449d06e29..1979f5eb9 100644
--- a/web/js/react/src/components/Modal/Archive.jsx
+++ b/web/js/react/src/components/Modal/Archive.jsx
@@ -1,8 +1,9 @@
import React from 'react';
-
-const { i18n } = window.GLOBAL.App;
+import { useSelector } from 'react-redux';
const Archive = (props) => {
+ const { i18n } = useSelector(state => state.session);
+
return (
diff --git a/web/js/react/src/components/Modal/Copy.jsx b/web/js/react/src/components/Modal/Copy.jsx
index 298a00c2c..7b1a70351 100644
--- a/web/js/react/src/components/Modal/Copy.jsx
+++ b/web/js/react/src/components/Modal/Copy.jsx
@@ -1,21 +1,22 @@
import React from 'react';
+import { useSelector } from 'react-redux';
const Copy = (props) => {
- const { Constants } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
return (
{props.items > 0 ?
-
{Constants.FM_COPY_BULK} ({props.items}) {Constants.FM_INTO_KEYWORD}:
:
- {Constants.FM_COPY} "{props.fName}" {Constants.FM_INTO_KEYWORD}:
}
+ {i18n['Copy files']} ({props.items}) {i18n['into']}:
:
+ {i18n['Copy']} "{props.fName}" {i18n['into']}:
}
-
-
+
+
);
diff --git a/web/js/react/src/components/Modal/Delete.jsx b/web/js/react/src/components/Modal/Delete.jsx
index 181ef9600..b85e26b79 100644
--- a/web/js/react/src/components/Modal/Delete.jsx
+++ b/web/js/react/src/components/Modal/Delete.jsx
@@ -1,18 +1,19 @@
import React from 'react';
+import { useSelector } from 'react-redux';
const Delete = (props) => {
- const { Constants } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
return (
{props.items > 0 ?
-
{Constants.FM_CONFIRM_DELETE_BULK} ({props.items}) ?
:
- {Constants.FM_CONFIRM_DELETE} "{props.fName}"?
}
+ {i18n['Delete items']} ({props.items}) ?
:
+ {i18n['Are you sure you want to delete']} "{props.fName}"?
}
-
-
+
+
);
diff --git a/web/js/react/src/components/Modal/Extract.jsx b/web/js/react/src/components/Modal/Extract.jsx
index 3698fdce0..0513775e5 100644
--- a/web/js/react/src/components/Modal/Extract.jsx
+++ b/web/js/react/src/components/Modal/Extract.jsx
@@ -1,19 +1,20 @@
import React from 'react';
+import { useSelector } from 'react-redux';
const Extract = (props) => {
- const { Constants } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
return (
-
{Constants.FM_EXTRACT} "{props.fName}"{Constants.FM_INTO_KEYWORD}
+ {i18n['Extract']} "{props.fName}"{i18n['into']}
-
-
+
+
);
diff --git a/web/js/react/src/components/Modal/Modal.scss b/web/js/react/src/components/Modal/Modal.scss
index e36ceac03..7e6d9a51e 100644
--- a/web/js/react/src/components/Modal/Modal.scss
+++ b/web/js/react/src/components/Modal/Modal.scss
@@ -1,3 +1,14 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$danger: #b00e5b;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
$black: #000;
.modal {
@@ -16,9 +27,9 @@ $black: #000;
.modal-content {
box-shadow: 0 2px 11px 0 rgba(0, 0, 0, 0.5);
- background: #333;
+ background: #222e44;
+ border: 1px solid #111824;
margin: auto;
- border: 1px solid #888;
width: 25%;
height: auto;
color: white;
@@ -42,7 +53,7 @@ $black: #000;
word-break: break-word;
h3 {
- color: #EBE697;
+ color: $secondaryLight;
}
.replace {
@@ -52,7 +63,7 @@ $black: #000;
}
.quot {
- color: rgb(182, 120, 28);
+ color: $secondaryActive;
}
}
@@ -82,25 +93,31 @@ $black: #000;
}
button.btn-danger:hover {
- background: #00cccb;
- border-color: #00cccb;
+ background: $danger;
+ border-color: $danger;
}
button + button {
padding: 6px 30px;
- background: #CACE33;
- border-color: #CACE33;
+ background: $secondary;
+ border-color: $secondary;
&:hover {
- background: #00cccb;
- border-color: #00cccb;
- color: white;
+ background: $primaryLight;
+ border-color: $primaryLight;
+ color: $hoverButtonText;
+ }
+
+ &:hover {
+ background: $primaryActive;
+ border-color: $primaryActive;
+ color: $activeButtonText;
}
}
}
.header .quot {
- color: rgb(182, 120, 28);
+ color: $secondaryActive;
}
.close {
diff --git a/web/js/react/src/components/Modal/Move.jsx b/web/js/react/src/components/Modal/Move.jsx
index 9589c4532..a879eee75 100644
--- a/web/js/react/src/components/Modal/Move.jsx
+++ b/web/js/react/src/components/Modal/Move.jsx
@@ -1,21 +1,22 @@
import React from 'react';
+import { useSelector } from 'react-redux';
const Move = (props) => {
- const { Constants } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
return (
{props.items > 0 ?
-
{Constants.FM_MOVE_BULK} ({props.items}) {Constants.FM_INTO_KEYWORD}:
:
- {Constants.FM_MOVE} "{props.fName}" {Constants.FM_INTO_KEYWORD}:
}
+ {i18n['Move files']} ({props.items}) {i18n['into']}:
:
+ {i18n['Move']} "{props.fName}" {i18n['into']}:
}
-
-
+
+
);
diff --git a/web/js/react/src/components/Modal/NothingSelected.jsx b/web/js/react/src/components/Modal/NothingSelected.jsx
index 2876719a3..2a55cfae7 100644
--- a/web/js/react/src/components/Modal/NothingSelected.jsx
+++ b/web/js/react/src/components/Modal/NothingSelected.jsx
@@ -1,15 +1,16 @@
import React from 'react';
+import { useSelector } from 'react-redux';
const NothingSelected = (props) => {
- const { Constants } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
return (
- {props.notAvailable ?
{Constants.FM_DirDownloadNotAvailable}
: {Constants.FM_NO_FILE_SELECTED}
}
+ {props.notAvailable ? {i18n['Directory download not available in current version']}
: {i18n['No file selected']}
}
-
+
);
diff --git a/web/js/react/src/components/Modal/Permissions.jsx b/web/js/react/src/components/Modal/Permissions.jsx
index ad064ad93..719877beb 100644
--- a/web/js/react/src/components/Modal/Permissions.jsx
+++ b/web/js/react/src/components/Modal/Permissions.jsx
@@ -1,5 +1,6 @@
import React, { Component } from 'react';
import classNames from 'classname';
+import { connect } from 'react-redux';
const defaultPermissions = {
owner: {
@@ -101,7 +102,7 @@ class Permissions extends Component {
}
render() {
- const { Constants } = window.GLOBAL.App;
+ const { i18n } = this.props.session;
const { inputInvalid } = this.state;
const { close, save, fName } = this.props;
const inputClasses = classNames({
@@ -112,33 +113,39 @@ class Permissions extends Component {
return (
-
{Constants.FM_CHMOD} "{fName}"
+ {i18n['Change Rights']} "{fName}"
this.inputRef = ref} onChange={this.handleInputChange} maxLength="3" />
-
-
+
+
);
}
}
-export default Permissions;
\ No newline at end of file
+function mapStateToProps(state) {
+ return {
+ session: state.session
+ }
+}
+
+export default connect(mapStateToProps)(Permissions);
diff --git a/web/js/react/src/components/Modal/Rename.jsx b/web/js/react/src/components/Modal/Rename.jsx
index 01b1158b7..1f6a92b7e 100644
--- a/web/js/react/src/components/Modal/Rename.jsx
+++ b/web/js/react/src/components/Modal/Rename.jsx
@@ -1,19 +1,20 @@
import React from 'react';
+import { useSelector } from 'react-redux';
const Rename = (props) => {
- const { Constants } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
return (
-
{Constants.FM_RENAME} "{props.fName}"
+ {i18n['Rename']} "{props.fName}"
-
-
+
+
);
diff --git a/web/js/react/src/components/Package/Add/AddPackage.jsx b/web/js/react/src/components/Package/Add/AddPackage.jsx
index a8595ed69..2bf8a501b 100644
--- a/web/js/react/src/components/Package/Add/AddPackage.jsx
+++ b/web/js/react/src/components/Package/Add/AddPackage.jsx
@@ -11,14 +11,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Toolbar from '../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
import Spinner from '../../Spinner/Spinner';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './AddPackage.scss';
import { Helmet } from 'react-helmet';
const AddPackage = props => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const dispatch = useDispatch();
const history = useHistory();
const [state, setState] = useState({
diff --git a/web/js/react/src/components/Package/Edit/EditPackage.jsx b/web/js/react/src/components/Package/Edit/EditPackage.jsx
index 81fec2b19..885253606 100644
--- a/web/js/react/src/components/Package/Edit/EditPackage.jsx
+++ b/web/js/react/src/components/Package/Edit/EditPackage.jsx
@@ -11,7 +11,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Spinner from '../../../components/Spinner/Spinner';
import Toolbar from '../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import QS from 'qs';
import './EditPackage.scss';
@@ -19,7 +19,7 @@ import { Helmet } from 'react-helmet';
const EditPackage = props => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
diff --git a/web/js/react/src/components/Package/Package.jsx b/web/js/react/src/components/Package/Package.jsx
index 6041a7bf6..c8ea987ab 100644
--- a/web/js/react/src/components/Package/Package.jsx
+++ b/web/js/react/src/components/Package/Package.jsx
@@ -4,10 +4,11 @@ import Container from '../ControlPanel/Container/Container';
import ListItem from '../ControlPanel/ListItem/ListItem';
import './Package.scss';
import { Link } from 'react-router-dom';
+import { useSelector } from 'react-redux';
const Package = props => {
const { data } = props;
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const printNameServers = servers => {
@@ -31,7 +32,7 @@ const Package = props => {
}
const handleDelete = () => {
- props.handleModal(data.delete_conf, `/delete/package?package=${data.NAME}&token=${token}`);
+ props.handleModal(data.delete_conf, `/api/v1/delete/package?package=${data.NAME}`);
}
return (
diff --git a/web/js/react/src/components/Path/Dropdown/Dropdown.jsx b/web/js/react/src/components/Path/Dropdown/Dropdown.jsx
index ab74e371f..495d9f1f9 100644
--- a/web/js/react/src/components/Path/Dropdown/Dropdown.jsx
+++ b/web/js/react/src/components/Path/Dropdown/Dropdown.jsx
@@ -1,47 +1,48 @@
import React from 'react';
+import { useSelector } from 'react-redux';
import './Dropdown.scss';
-const { i18n } = window.GLOBAL.App;
-
-function changeSorting(field, order, props) {
- if (!props.isActive) {
- return;
- } else {
- props.changeSorting(field, order);
- }
-}
-
-function sort(sorting) {
- if (sorting === "Type") {
- return i18n.type;
- } else if (sorting === "Size") {
- return i18n.size;
- } else if (sorting === "Date") {
- return i18n.date;
- } else if (sorting === "Name") {
- return i18n.name;
- }
-}
-
-function button(sorting, order) {
- if (order === "descending") {
- return (
-
- );
- } else {
- return (
-
- );
- }
-}
-
const Dropdown = (props) => {
+ const { i18n } = useSelector(state => state.session);
+
+ const changeSorting = (field, order, props) => {
+ if (!props.isActive) {
+ return;
+ } else {
+ props.changeSorting(field, order);
+ }
+ }
+
+ const sort = (sorting) => {
+ if (sorting === "Type") {
+ return i18n.type;
+ } else if (sorting === "Size") {
+ return i18n.size;
+ } else if (sorting === "Date") {
+ return i18n.date;
+ } else if (sorting === "Name") {
+ return i18n.name;
+ }
+ }
+
+ const button = (sorting, order) => {
+ if (order === "descending") {
+ return (
+
+ );
+ } else {
+ return (
+
+ );
+ }
+ }
+
return (
{button(props.sorting, props.order)}
diff --git a/web/js/react/src/components/Path/Path.jsx b/web/js/react/src/components/Path/Path.jsx
index 80ca95de4..5945c66e3 100644
--- a/web/js/react/src/components/Path/Path.jsx
+++ b/web/js/react/src/components/Path/Path.jsx
@@ -1,14 +1,17 @@
import React from 'react';
+import { useSelector } from 'react-redux';
import Dropdown from './Dropdown/Dropdown';
import './Path.scss';
const Path = ({ path, isActive, className, openDirectory, changeSorting, sorting, order }) => {
+ const session = useSelector(state => state.session);
+
const clickablePath = () => {
let splitPath = path.split('/');
splitPath.splice(0, 3);
- if (path !== window.GLOBAL.ROOT_DIR) {
+ if (path !== session.user.HOME) {
return (
splitPath.map((item, index) =>
openDirectoryHandler(index)}> / {item})
);
@@ -33,7 +36,7 @@ const Path = ({ path, isActive, className, openDirectory, changeSorting, sorting
- openDirectory(window.GLOBAL.ROOT_DIR)}>{window.GLOBAL.ROOT_DIR}
+ openDirectory(session.user.HOME)}>{session.user.HOME}
{clickablePath()}
diff --git a/web/js/react/src/components/Path/Path.scss b/web/js/react/src/components/Path/Path.scss
index b6befee9d..a70cbe27b 100644
--- a/web/js/react/src/components/Path/Path.scss
+++ b/web/js/react/src/components/Path/Path.scss
@@ -1,4 +1,15 @@
$white: #fff;
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$danger: #b00e5b;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
.path {
display: flex;
@@ -6,71 +17,57 @@ $white: #fff;
font-size: 15px;
padding: 1px 0 0 5px;
height: 40px;
- background: #7b7b7b;
- color: $white;
- box-shadow: 0 2px 10px -4px gray;
+ background: #222e44;
+ color: #999;
+ box-shadow: 0 2px 10px -4px #222e44;
.btn-group {
width: 75px;
margin-left: 15px;
background: none;
box-shadow: none;
- background: #7b7b7b;
.btn-secondary:not(:disabled):not(.disabled).active, .btn-secondary:not(:disabled):not(.disabled):active, .show>.btn-secondary.dropdown-toggle {
- border-color: #7b7b7b;
- background-color: #7b7b7b;
+ background: #222e44;
+ border: #222e44;
}
button {
padding-left: 0;
padding-right: 5px;
- color: white;
- background: #7b7b7b;
+ color: #999;
+ background: #222e44;
+ border: #222e44;
transition: none;
span {
- color: #fff;
+ color: #999;
padding: 0 0 0 5px;
}
&:active, &:focus {
- background-color: #7b7b7b;
- border-color: #7b7b7b;
+ background: #222e44;
+ border: #222e44;
}
}
.btn.active.focus, .btn.active:focus, .btn.focus, .btn:active.focus, .btn:active:focus, .btn:focus {
box-shadow: none;
outline: none;
- background-color: #7b7b7b;
- border-color: #7b7b7b;
+ background: #222e44;
+ border: #222e44;
}
.btn-secondary {
display: flex;
justify-content: center;
align-items: center;
-
- &:hover {
- color: rgb(1, 148, 148);
- background: #7b7b7b;
- border-color: #7b7b7b;
-
- span {
- color: rgb(1, 148, 148);
- }
- }
}
}
.clickable {
padding-top: 8px;
cursor: pointer;
-
- &:hover {
- color: goldenrod;
- }
}
}
@@ -80,9 +77,9 @@ $white: #fff;
font-size: 15px;
padding: 1px 0 0 5px;
height: 40px;
- background: #333;
+ background: #d7dcef;
color: $white;
- box-shadow: 0 2px 6px -2px gray;
+ box-shadow: 0 2px 6px -2px #d7dcef;
.clickable-wrapper {
display: flex;
@@ -94,18 +91,18 @@ $white: #fff;
width: 75px;
background: none;
box-shadow: none;
- background: #333;
.btn-secondary:not(:disabled):not(.disabled).active, .btn-secondary:not(:disabled):not(.disabled):active, .show>.btn-secondary.dropdown-toggle {
- border-color: #333;
- background-color: #333;
+ border-color: #d7dcef;
+ background: #d7dcef;
}
button {
padding-left: 0;
padding-right: 5px;
color: white;
- background: #333;
+ border-color: #d7dcef;
+ background: #d7dcef;
transition: none;
span {
@@ -114,41 +111,51 @@ $white: #fff;
}
&:active, &:focus {
- background-color: #333;
- border-color: #333;
+ border-color: #d7dcef;
+ background: #d7dcef;
}
}
.btn.active.focus, .btn.active:focus, .btn.focus, .btn:active.focus, .btn:active:focus, .btn:focus {
box-shadow: none;
outline: none;
- background-color: #333;
- border-color: #333;
+ border-color: #d7dcef;
+ background: #d7dcef;
}
.btn-secondary {
display: flex;
justify-content: center;
align-items: center;
-
+ color: $primary;
+
+ span {
+ color: $primary;
+ }
+
&:hover {
- color: rgb(1, 148, 148);
- background: #333;
- border-color: #333;
+ color: #1c3876;
+ border-color: #d7dcef;
+ background: #d7dcef;
span {
- color: rgb(1, 148, 148);
+ color: #1c3876;
}
}
}
}
.clickable {
+ color: $primary;
padding-top: 8px;
cursor: pointer;
&:hover {
- color: goldenrod;
+ color: #1c3876;
+ }
+
+ &:active {
+ color: $primary;
}
}
}
diff --git a/web/js/react/src/components/Preview/Editor/Editor.jsx b/web/js/react/src/components/Preview/Editor/Editor.jsx
index 7dcc57d62..165397a60 100644
--- a/web/js/react/src/components/Preview/Editor/Editor.jsx
+++ b/web/js/react/src/components/Preview/Editor/Editor.jsx
@@ -11,9 +11,10 @@ import axios from 'axios';
import Spinner from '../../Spinner/Spinner';
import { useHistory } from 'react-router-dom';
import { toast, ToastContainer } from 'react-toastify';
+import { useSelector } from 'react-redux';
const Editor = ({ close, name }) => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const [state, setState] = useState({
code: '',
@@ -29,7 +30,7 @@ const Editor = ({ close, name }) => {
checkFileType(path)
.then(res => {
if (res.data.result) {
- axios.get(`${window.location.origin}/edit/file/?path=${encodePath(path)}`)
+ axios.get(`${window.location.origin}/api/v1/edit/file/?path=${encodePath(path)}`)
.then(result => {
if (result.data.error) {
return showToast(res.data.error);
@@ -71,7 +72,7 @@ const Editor = ({ close, name }) => {
formData.append('contents', state.code);
setState({ ...state, loading: true });
- axios.post(`${window.location.origin}/edit/file/?path=${path}%2F${name}`, formData)
+ axios.post(`${window.location.origin}/api/v1/edit/file/?path=${path}%2F${name}`, formData)
.then(res => {
if (res.data.error) {
showToast(res.data.error);
diff --git a/web/js/react/src/components/Preview/Photo/Photo.jsx b/web/js/react/src/components/Preview/Photo/Photo.jsx
index 77f130ddb..e16568cd3 100644
--- a/web/js/react/src/components/Preview/Photo/Photo.jsx
+++ b/web/js/react/src/components/Preview/Photo/Photo.jsx
@@ -37,7 +37,7 @@ class Photo extends Component {
return gallery.map((item, i) => {
const imageClasses = classNames({ 'control-photo': true, 'active': i === this.state.activeSlide });
const result = (
-
}/${item}&raw=true`})
+
);
return result;
});
@@ -48,7 +48,7 @@ class Photo extends Component {
return gallery.map((item, i) => (
-
}/${item}&raw=true`})
+
));
diff --git a/web/js/react/src/components/Preview/Preview.jsx b/web/js/react/src/components/Preview/Preview.jsx
index e03881701..e593c9827 100644
--- a/web/js/react/src/components/Preview/Preview.jsx
+++ b/web/js/react/src/components/Preview/Preview.jsx
@@ -1,13 +1,17 @@
import React, { useEffect } from 'react';
+import { useSelector } from 'react-redux';
import { useHistory } from 'react-router';
import Editor from './Editor/Editor';
import Photo from './Photo/Photo';
import Video from './Video/Video';
const Preview = (props) => {
+ const session = useSelector(state => state.session);
const history = useHistory();
useEffect(() => {
+ if (!session.userName) history.push('/login');
+
document.addEventListener("keydown", hotkeys);
return () => {
diff --git a/web/js/react/src/components/RRD/RRD.jsx b/web/js/react/src/components/RRD/RRD.jsx
index 76ae702a3..268943b2e 100644
--- a/web/js/react/src/components/RRD/RRD.jsx
+++ b/web/js/react/src/components/RRD/RRD.jsx
@@ -4,10 +4,11 @@ import { faFileDownload } from '@fortawesome/free-solid-svg-icons';
import Container from '../ControlPanel/Container/Container';
import { generateImagePath } from '../../ControlPanelService/RRD';
import './RRD.scss';
+import { useSelector } from 'react-redux';
const RRD = props => {
const { data } = props;
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const printDate = date => {
let newDate = new Date(date);
diff --git a/web/js/react/src/components/Searchitem/SearchItem.jsx b/web/js/react/src/components/Searchitem/SearchItem.jsx
index d3d38addf..88376d089 100644
--- a/web/js/react/src/components/Searchitem/SearchItem.jsx
+++ b/web/js/react/src/components/Searchitem/SearchItem.jsx
@@ -1,50 +1,49 @@
-import React, { Component } from 'react';
+import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import ListItem from '../ControlPanel/ListItem/ListItem';
import Container from '../ControlPanel/Container/Container';
+import { useSelector } from 'react-redux';
import './SearchItem.scss';
+import { Link } from 'react-router-dom';
-class SearchItem extends Component {
- render() {
- const { data } = this.props;
- const { i18n } = window.GLOBAL.App;
+const SearchItem = ({ data, handleModal }) => {
+ const { i18n } = useSelector(state => state.session);
- return (
-
-
- {data.RESULT}
-
-
- {i18n[data.object]}
-
-
- {i18n.Owner}: {data.USER}
-
-
- {i18n.Status}: {data.status}
-
-
-
-
-
-
-
-
-
-
-
+ return (
+
+
+ {data.RESULT}
+
+
+ {i18n[data.object]}
+
+
+ {i18n.Owner}: {data.USER}
+
+
+ {i18n.Status}: {data.status}
+
-
- );
- }
+
+
+
{i18n.edit}
+
+
+
+
+
+
+
+
+ );
}
-export default SearchItem;
\ No newline at end of file
+export default SearchItem;
diff --git a/web/js/react/src/components/Server/Edit/Bind9/Bind9.jsx b/web/js/react/src/components/Server/Edit/Bind9/Bind9.jsx
index 053919dc9..dc71a3a6c 100644
--- a/web/js/react/src/components/Server/Edit/Bind9/Bind9.jsx
+++ b/web/js/react/src/components/Server/Edit/Bind9/Bind9.jsx
@@ -8,14 +8,14 @@ import { getServiceInfo, updateService } from 'src/ControlPanelService/Server';
import Spinner from '../../../../components/Spinner/Spinner';
import Toolbar from '../../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './Bind9.scss';
import { Helmet } from 'react-helmet';
const Bind9 = () => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
diff --git a/web/js/react/src/components/Server/Edit/Dovecot/Dovecot.jsx b/web/js/react/src/components/Server/Edit/Dovecot/Dovecot.jsx
index 5e9b47765..2656c7099 100644
--- a/web/js/react/src/components/Server/Edit/Dovecot/Dovecot.jsx
+++ b/web/js/react/src/components/Server/Edit/Dovecot/Dovecot.jsx
@@ -8,14 +8,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Spinner from '../../../../components/Spinner/Spinner';
import Toolbar from '../../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './Dovecot.scss';
import { Helmet } from 'react-helmet';
const Dovecot = () => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
diff --git a/web/js/react/src/components/Server/Edit/EditBackupOption.jsx b/web/js/react/src/components/Server/Edit/EditBackupOption.jsx
index dd0e4d220..799b1ace9 100644
--- a/web/js/react/src/components/Server/Edit/EditBackupOption.jsx
+++ b/web/js/react/src/components/Server/Edit/EditBackupOption.jsx
@@ -3,9 +3,10 @@ import React, { useState } from 'react';
import SelectInput from 'src/components/ControlPanel/AddItemLayout/Form/SelectInput/SelectInput';
import TextInput from 'src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { useSelector } from 'react-redux';
const EditBackupOption = ({ data, visible }) => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const [remoteBackup, setRemoteBackup] = useState(false);
return (
diff --git a/web/js/react/src/components/Server/Edit/EditDatabaseOption.jsx b/web/js/react/src/components/Server/Edit/EditDatabaseOption.jsx
index 8ae114fb3..85cfd80a0 100644
--- a/web/js/react/src/components/Server/Edit/EditDatabaseOption.jsx
+++ b/web/js/react/src/components/Server/Edit/EditDatabaseOption.jsx
@@ -4,9 +4,10 @@ import SelectInput from 'src/components/ControlPanel/AddItemLayout/Form/SelectIn
import TextInput from 'src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput';
import Checkbox from 'src/components/ControlPanel/AddItemLayout/Form/Checkbox/Checkbox';
import { Link } from 'react-router-dom';
+import { useSelector } from 'react-redux';
const EditDatabaseOption = ({ data, visible }) => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const printPhpMyAdminHosts = () => {
if (data.mysql_hosts.length) {
diff --git a/web/js/react/src/components/Server/Edit/EditMailOption.jsx b/web/js/react/src/components/Server/Edit/EditMailOption.jsx
index 807cee612..e398a5958 100644
--- a/web/js/react/src/components/Server/Edit/EditMailOption.jsx
+++ b/web/js/react/src/components/Server/Edit/EditMailOption.jsx
@@ -4,9 +4,10 @@ import SelectInput from 'src/components/ControlPanel/AddItemLayout/Form/SelectIn
import TextInput from 'src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput';
import Checkbox from 'src/components/ControlPanel/AddItemLayout/Form/Checkbox/Checkbox';
import { Link } from 'react-router-dom';
+import { useSelector } from 'react-redux';
const EditMailOption = ({ data, visible }) => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const [mailCertificateSystem, setMailCertificateSystem] = useState(false);
useEffect(() => {
diff --git a/web/js/react/src/components/Server/Edit/EditServer.jsx b/web/js/react/src/components/Server/Edit/EditServer.jsx
index f77c7ebba..2aa3074f4 100644
--- a/web/js/react/src/components/Server/Edit/EditServer.jsx
+++ b/web/js/react/src/components/Server/Edit/EditServer.jsx
@@ -15,14 +15,14 @@ import Toolbar from '../../MainNav/Toolbar/Toolbar';
import EditBackupOption from './EditBackupOption';
import EditMailOption from './EditMailOption';
import { useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './EditServer.scss';
import { Helmet } from 'react-helmet';
const EditServer = props => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
@@ -119,18 +119,30 @@ const EditServer = props => {
name="v_hostname"
id="hostname" />
-
+ {
+ state.data.timezones && (
+
+
+
+
+ )
+ }
diff --git a/web/js/react/src/components/Server/Edit/EditServer.scss b/web/js/react/src/components/Server/Edit/EditServer.scss
index 90a8cc628..5d13178eb 100644
--- a/web/js/react/src/components/Server/Edit/EditServer.scss
+++ b/web/js/react/src/components/Server/Edit/EditServer.scss
@@ -1,3 +1,15 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$danger: #b00e5b;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
.edit-server {
.modules {
display: flex;
@@ -22,12 +34,12 @@
.form-group {
a {
text-decoration: none;
- color: #2C9491;
+ color: $primary;
font-weight: bold;
font-size: 14px;
&:hover {
- color: #ff6701;
+ color: $primaryLight;
}
}
}
@@ -92,7 +104,7 @@
.sftp-module,
.fm-module {
font-size: 15px;
- color: #555;
+ color: $textColor;
}
.buy-license {
@@ -101,7 +113,7 @@
a {
color: #FFF;
- background: #9fbf0c;
+ background: $primary;
border: none;
border-radius: 3px;
font-size: 13px;
@@ -113,8 +125,13 @@
margin-right: 10px;
&:hover {
- color: #555;
- background: #c0e60f;
+ color: $hoverButtonText;
+ background: $primaryLight;
+ }
+
+ &:hover {
+ color: $activeButtonText;
+ background: $primaryActive;
}
}
@@ -132,7 +149,7 @@
margin: 1rem 0;
> span {
- color: #2c9491;
+ color: $primary;
}
.form-group {
diff --git a/web/js/react/src/components/Server/Edit/EditServerDnsOption.jsx b/web/js/react/src/components/Server/Edit/EditServerDnsOption.jsx
index 0c3bc3d65..d32d85a0d 100644
--- a/web/js/react/src/components/Server/Edit/EditServerDnsOption.jsx
+++ b/web/js/react/src/components/Server/Edit/EditServerDnsOption.jsx
@@ -3,9 +3,10 @@ import React from 'react';
import SelectInput from 'src/components/ControlPanel/AddItemLayout/Form/SelectInput/SelectInput';
import TextInput from 'src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput';
import { Link } from 'react-router-dom';
+import { useSelector } from 'react-redux';
const EditServerDnsOption = ({ dnsSystem, selected, dnsCluster, visible }) => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const printHosts = () => {
return dnsCluster.map((cluster, index) => (
diff --git a/web/js/react/src/components/Server/Edit/EditServerWebOption.jsx b/web/js/react/src/components/Server/Edit/EditServerWebOption.jsx
index afafbbad0..81a255c5e 100644
--- a/web/js/react/src/components/Server/Edit/EditServerWebOption.jsx
+++ b/web/js/react/src/components/Server/Edit/EditServerWebOption.jsx
@@ -2,9 +2,10 @@ import React from 'react';
import TextInput from 'src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput';
import { Link } from 'react-router-dom';
+import { useSelector } from 'react-redux';
const EditServerWebOption = ({ proxySystem, webSystem, webBackend, webBackendPool, visible = false }) => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
return (
diff --git a/web/js/react/src/components/Server/Edit/EditVestaPlugins.jsx b/web/js/react/src/components/Server/Edit/EditVestaPlugins.jsx
index 3206987aa..ee96f7d93 100644
--- a/web/js/react/src/components/Server/Edit/EditVestaPlugins.jsx
+++ b/web/js/react/src/components/Server/Edit/EditVestaPlugins.jsx
@@ -3,9 +3,10 @@ import React, { useEffect, useState } from 'react';
import SelectInput from 'src/components/ControlPanel/AddItemLayout/Form/SelectInput/SelectInput';
import TextInput from 'src/components/ControlPanel/AddItemLayout/Form/TextInput/TextInput';
import { Link } from 'react-router-dom';
+import { useSelector } from 'react-redux';
const EditVestaPluginsOption = ({ data, visible }) => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const [sftpOptions, setSftpOptions] = useState([]);
const [fmOptions, setFmOptions] = useState([]);
const [sftpDescription, setSftpDescription] = useState(false);
@@ -31,15 +32,15 @@ const EditVestaPluginsOption = ({ data, visible }) => {
setSftpOptions(sftpOptionsArray);
setFmOptions(fmOptionsArray);
- if (data.lead === 'sftp' || data.sftpjail_key != '') {
+ if (data.lead === 'sftp' || data.sftpjail_key !== 'no') {
setSftpDescription(true);
}
- if (data.lead === 'filemanager' || data.fm_key != '') {
+ if (data.lead === 'filemanager' || data.fm_key !== 'no') {
setFmDescription(true);
}
- if (data.lead === 'softaculous' || data.softaculous != '') {
+ if (data.lead === 'softaculous' || data.softaculous !== 'no') {
setSoftaculousDescription(true);
}
}, []);
@@ -199,10 +200,10 @@ const EditVestaPluginsOption = ({ data, visible }) => {
@@ -223,10 +224,10 @@ const EditVestaPluginsOption = ({ data, visible }) => {
id="softaculous" />
{
- softaculousDescription === 'yes' && (
+ softaculousDescription && (
-
{i18n['Browse, copy, edit, view, and retrieve all of your web domain files using fully featured File Manager.']}
-
+
+
{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
@@ -234,8 +235,11 @@ const EditVestaPluginsOption = ({ data, visible }) => {
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.
-
- {i18n['Get Premium License']}
+
+
+
@@ -245,4 +249,4 @@ const EditVestaPluginsOption = ({ data, visible }) => {
);
}
-export default EditVestaPluginsOption;
\ No newline at end of file
+export default EditVestaPluginsOption;
diff --git a/web/js/react/src/components/Server/Edit/EditVestaSslOption.jsx b/web/js/react/src/components/Server/Edit/EditVestaSslOption.jsx
index b591c5eaa..844b8aa85 100644
--- a/web/js/react/src/components/Server/Edit/EditVestaSslOption.jsx
+++ b/web/js/react/src/components/Server/Edit/EditVestaSslOption.jsx
@@ -4,9 +4,10 @@ import SelectInput from 'src/components/ControlPanel/AddItemLayout/Form/SelectIn
import TextArea from 'src/components/ControlPanel/AddItemLayout/Form/TextArea/TextArea';
import Checkbox from 'src/components/ControlPanel/AddItemLayout/Form/Checkbox/Checkbox';
import { Link } from 'react-router-dom';
+import { useSelector } from 'react-redux';
const EditVestaSslOption = ({ data, visible }) => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const [domainsVisible, setDomainsVisible] = useState(false);
const [sslDomains, setSslDomains] = useState([]);
diff --git a/web/js/react/src/components/Server/Edit/Httpd/EditHttpd.jsx b/web/js/react/src/components/Server/Edit/Httpd/EditHttpd.jsx
index 19d4ea6b9..1a62e6262 100644
--- a/web/js/react/src/components/Server/Edit/Httpd/EditHttpd.jsx
+++ b/web/js/react/src/components/Server/Edit/Httpd/EditHttpd.jsx
@@ -8,14 +8,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Spinner from '../../../../components/Spinner/Spinner';
import Toolbar from '../../../MainNav/Toolbar/Toolbar';
import { Link, useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './EditHttpd.scss';
import { Helmet } from 'react-helmet';
const EditHttpd = props => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
diff --git a/web/js/react/src/components/Server/Edit/Httpd/EditHttpd.scss b/web/js/react/src/components/Server/Edit/Httpd/EditHttpd.scss
index 16ec9e23e..bba176cc6 100644
--- a/web/js/react/src/components/Server/Edit/Httpd/EditHttpd.scss
+++ b/web/js/react/src/components/Server/Edit/Httpd/EditHttpd.scss
@@ -1,10 +1,13 @@
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+
.content .edit-template.edit-httpd {
.toolbar {
.search-toolbar-name {
width: fit-content;
a {
- color: #ff6701;
+ color: $secondary;
text-decoration: none;
&:hover {
@@ -25,7 +28,7 @@
font-weight: 700;
&:hover {
- color: #ff6701;
+ color: $secondaryLight;
}
}
}
diff --git a/web/js/react/src/components/Server/Edit/Mysql/Mysql.jsx b/web/js/react/src/components/Server/Edit/Mysql/Mysql.jsx
index a4172f031..31bd95f36 100644
--- a/web/js/react/src/components/Server/Edit/Mysql/Mysql.jsx
+++ b/web/js/react/src/components/Server/Edit/Mysql/Mysql.jsx
@@ -9,14 +9,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Spinner from '../../../../components/Spinner/Spinner';
import Toolbar from '../../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './Mysql.scss';
import { Helmet } from 'react-helmet';
const Mysql = ({ serviceName = '' }) => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
diff --git a/web/js/react/src/components/Server/Edit/Nginx/EditServerNginx.jsx b/web/js/react/src/components/Server/Edit/Nginx/EditServerNginx.jsx
index 9af48fab4..be95b496c 100644
--- a/web/js/react/src/components/Server/Edit/Nginx/EditServerNginx.jsx
+++ b/web/js/react/src/components/Server/Edit/Nginx/EditServerNginx.jsx
@@ -9,14 +9,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Spinner from '../../../../components/Spinner/Spinner';
import Toolbar from '../../../MainNav/Toolbar/Toolbar';
import { Link, useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './EditServerNginx.scss';
import { Helmet } from 'react-helmet';
const EditServerNginx = props => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
diff --git a/web/js/react/src/components/Server/Edit/Nginx/EditServerNginx.scss b/web/js/react/src/components/Server/Edit/Nginx/EditServerNginx.scss
index 53609fe0e..56f469d02 100644
--- a/web/js/react/src/components/Server/Edit/Nginx/EditServerNginx.scss
+++ b/web/js/react/src/components/Server/Edit/Nginx/EditServerNginx.scss
@@ -1,3 +1,5 @@
+$secondaryLight: #f8b014;
+
.content .edit-template.edit-nginx {
.toolbar {
.search-toolbar-name {
@@ -16,7 +18,7 @@
font-weight: 700;
&:hover {
- color: #ff6701;
+ color: $secondaryLight;
}
}
}
diff --git a/web/js/react/src/components/Server/Edit/PHP/EditPhp.jsx b/web/js/react/src/components/Server/Edit/PHP/EditPhp.jsx
index 9496494f7..d4923dbb9 100644
--- a/web/js/react/src/components/Server/Edit/PHP/EditPhp.jsx
+++ b/web/js/react/src/components/Server/Edit/PHP/EditPhp.jsx
@@ -9,14 +9,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Spinner from '../../../../components/Spinner/Spinner';
import Toolbar from '../../../MainNav/Toolbar/Toolbar';
import { Link, useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './EditPhp.scss';
import { Helmet } from 'react-helmet';
const EditPhp = ({ serviceName = '' }) => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
diff --git a/web/js/react/src/components/Server/Edit/PHP/EditPhp.scss b/web/js/react/src/components/Server/Edit/PHP/EditPhp.scss
index 742ae2115..5ff39c738 100644
--- a/web/js/react/src/components/Server/Edit/PHP/EditPhp.scss
+++ b/web/js/react/src/components/Server/Edit/PHP/EditPhp.scss
@@ -1,8 +1,12 @@
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$textColor: #555;
+
.content .edit-template.edit-php {
.toolbar {
.search-toolbar-name {
width: fit-content;
- color: rgb(119, 119, 119);
+ color: $textColor;
}
.search-toolbar-name,
@@ -13,11 +17,11 @@
text-decoration: none;
font-size: 12px;
text-transform: uppercase;
- color: rgb(119, 119, 119);
+ color: $textColor;
font-weight: 700;
&:hover {
- color: #ff6701;
+ color: $secondaryLight;
}
}
}
@@ -26,10 +30,10 @@
margin-left: 15px;
a {
- color: #ff6701;
+ color: $secondary;
&:hover {
- color: rgb(119, 119, 119);
+ color: $textColor;
}
}
}
diff --git a/web/js/react/src/components/Server/Edit/Postgresql/Postgresql.jsx b/web/js/react/src/components/Server/Edit/Postgresql/Postgresql.jsx
index bda2fc2c1..1950fe108 100644
--- a/web/js/react/src/components/Server/Edit/Postgresql/Postgresql.jsx
+++ b/web/js/react/src/components/Server/Edit/Postgresql/Postgresql.jsx
@@ -8,14 +8,14 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Spinner from '../../../../components/Spinner/Spinner';
import Toolbar from '../../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './Postgresql.scss';
import { Helmet } from 'react-helmet';
const Postgresql = () => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
diff --git a/web/js/react/src/components/Server/Edit/Service/Service.jsx b/web/js/react/src/components/Server/Edit/Service/Service.jsx
index 156696c9f..dded3e2fb 100644
--- a/web/js/react/src/components/Server/Edit/Service/Service.jsx
+++ b/web/js/react/src/components/Server/Edit/Service/Service.jsx
@@ -8,14 +8,14 @@ import { getServiceInfo, updateService } from 'src/ControlPanelService/Server';
import Spinner from '../../../../components/Spinner/Spinner';
import Toolbar from '../../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './Service.scss';
import { Helmet } from 'react-helmet';
const Service = ({ serviceName = '' }) => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
diff --git a/web/js/react/src/components/Server/Server.jsx b/web/js/react/src/components/Server/Server.jsx
index ef580b6b2..20c7d12a3 100644
--- a/web/js/react/src/components/Server/Server.jsx
+++ b/web/js/react/src/components/Server/Server.jsx
@@ -4,10 +4,11 @@ import Container from '../ControlPanel/Container/Container';
import ListItem from '../ControlPanel/ListItem/ListItem';
import './Server.scss';
import { Link } from 'react-router-dom';
+import { useSelector } from 'react-redux';
const Server = props => {
const { data } = props;
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const printTime = seconds => {
let hours = seconds / 60;
@@ -55,14 +56,14 @@ const Server = props => {
-
-
props.handleAction(`/api/restart/service/?srv=${data.NAME}`)}>
+ props.handleAction(`/api/v1/restart/service/?srv=${data.NAME}`)}>
{i18n.restart}
{
data.FOCUSED
diff --git a/web/js/react/src/components/Server/ServerSys.jsx b/web/js/react/src/components/Server/ServerSys.jsx
index 10b8b7277..c34f43180 100644
--- a/web/js/react/src/components/Server/ServerSys.jsx
+++ b/web/js/react/src/components/Server/ServerSys.jsx
@@ -4,10 +4,11 @@ import Container from '../ControlPanel/Container/Container';
import ListItem from '../ControlPanel/ListItem/ListItem';
import './ServerSys.scss';
import { Link } from 'react-router-dom';
+import { useSelector } from 'react-redux';
const Server = props => {
const { data } = props;
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const printTime = seconds => {
diff --git a/web/js/react/src/components/Statistic/Statistic.jsx b/web/js/react/src/components/Statistic/Statistic.jsx
index a8fc839b4..663c99fb5 100644
--- a/web/js/react/src/components/Statistic/Statistic.jsx
+++ b/web/js/react/src/components/Statistic/Statistic.jsx
@@ -1,10 +1,11 @@
import React from 'react';
+import { useSelector } from 'react-redux';
import Container from '../ControlPanel/Container/Container';
import './Statistic.scss';
const Statistic = props => {
const { data } = props;
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const printDate = date => {
let newDate = new Date(date);
diff --git a/web/js/react/src/components/TopPanel/TopPanel.jsx b/web/js/react/src/components/TopPanel/TopPanel.jsx
index 20533c1d8..90d12d0d0 100644
--- a/web/js/react/src/components/TopPanel/TopPanel.jsx
+++ b/web/js/react/src/components/TopPanel/TopPanel.jsx
@@ -10,7 +10,7 @@ import './TopPanel.scss';
const TopPanel = ({ menuItems = [], extraMenuItems = [] }) => {
const mainNavigation = useSelector(state => state.mainNavigation);
const [loading, setLoading] = useState(false);
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const dispatch = useDispatch();
const history = useHistory();
const { userName } = useSelector(state => state.session);
@@ -38,9 +38,13 @@ const TopPanel = ({ menuItems = [], extraMenuItems = [] }) => {
const renderExtraMenuItems = () => {
if (!extraMenuItems.length) return;
- return extraMenuItems.map(({ link, text }, index) => (
+ return extraMenuItems.map(({ link, text, type }, index) => (
-
{text}
+ {
+ type === 'download'
+ ?
{text}
+ :
{text}
+ }
));
}
@@ -73,7 +77,9 @@ const TopPanel = ({ menuItems = [], extraMenuItems = [] }) => {
-
+
+

+
diff --git a/web/js/react/src/components/TopPanel/TopPanel.scss b/web/js/react/src/components/TopPanel/TopPanel.scss
index c575dd403..4009fe023 100644
--- a/web/js/react/src/components/TopPanel/TopPanel.scss
+++ b/web/js/react/src/components/TopPanel/TopPanel.scss
@@ -1,11 +1,20 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$danger: #b00e5b;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
.panel-wrapper {
.logo-img {
- background-image: url("/images/sprite.png?1446554103");
- background-position: -117px -57px;
- background-repeat: no-repeat;
- height: 22px;
- width: 70px;
- margin-left: -2px;
+ img {
+ width: 82%;
+ }
&:hover {
background-color: transparent;
@@ -24,28 +33,27 @@
> div.nav-link {
padding: 0;
- width: fit-content;
}
}
.profile-menu {
> div:nth-child(1) a {
&:hover {
- color: #ffd62e;
+ color: $secondaryLight;
}
&:active {
- color: #f79b44;
+ color: $secondaryActive;
}
}
> div:nth-child(2) a {
&:hover {
- color: #C0E60E;
+ color: $secondaryActive;
}
&:active {
- color: #ffd62e;
+ color: $secondaryActive;
}
}
@@ -54,11 +62,11 @@
font-weight: 700;
&:hover {
- color: #ffd62e;
+ color: $secondaryLight;
}
&:active {
- color: #f79b44;
+ color: $secondaryActive;
}
}
@@ -68,11 +76,11 @@
font-weight: 100;
&:hover {
- color: #C0E60E;
+ color: $primaryLight;
}
&:active {
- color: #ffd62e;
+ color: $secondaryActive;
}
}
}
diff --git a/web/js/react/src/components/Update/Update.jsx b/web/js/react/src/components/Update/Update.jsx
index c95debd70..be6219502 100644
--- a/web/js/react/src/components/Update/Update.jsx
+++ b/web/js/react/src/components/Update/Update.jsx
@@ -1,11 +1,12 @@
import React, { } from 'react';
+import { useSelector } from 'react-redux';
import Container from '../ControlPanel/Container/Container';
import ListItem from '../ControlPanel/ListItem/ListItem';
import './Update.scss';
const Update = props => {
const { data } = props;
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const isUpdated = status => {
if (status === 'no') {
diff --git a/web/js/react/src/components/User/Add/AddUser.jsx b/web/js/react/src/components/User/Add/AddUser.jsx
index acc326e3b..f59bafb93 100644
--- a/web/js/react/src/components/User/Add/AddUser.jsx
+++ b/web/js/react/src/components/User/Add/AddUser.jsx
@@ -9,13 +9,13 @@ import { addUser } from '../../../ControlPanelService/Users';
import Spinner from '../../../components/Spinner/Spinner';
import Toolbar from '../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './AddUser.scss';
import { Helmet } from 'react-helmet';
const AddUser = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const userLanguage = localStorage.getItem("language");
const history = useHistory();
const dispatch = useDispatch();
diff --git a/web/js/react/src/components/User/Add/AddUser.scss b/web/js/react/src/components/User/Add/AddUser.scss
index 507af9a1f..6552b9c5e 100644
--- a/web/js/react/src/components/User/Add/AddUser.scss
+++ b/web/js/react/src/components/User/Add/AddUser.scss
@@ -1,13 +1,23 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$danger: #b00e5b;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
$textColor: #555;
.password-wrapper {
display: flex;
button {
- color: #2C9491;
+ color: $primary;
&:hover {
- color: #ff6701;
+ color: $secondaryLight;
}
}
@@ -21,15 +31,15 @@ $textColor: #555;
}
button.generate-password {
- color:#2C9491;
+ color:$primary;
font-weight: bold;
&:hover {
- color: #ff6701;
+ color: $secondaryLight;
}
&:active {
- color: #F7D616;
+ color: $secondaryActive;
}
}
diff --git a/web/js/react/src/components/User/Edit/EditUser.jsx b/web/js/react/src/components/User/Edit/EditUser.jsx
index 00fde50d8..8ec769783 100644
--- a/web/js/react/src/components/User/Edit/EditUser.jsx
+++ b/web/js/react/src/components/User/Edit/EditUser.jsx
@@ -10,7 +10,7 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Spinner from '../../../components/Spinner/Spinner';
import Toolbar from '../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import QS from 'qs';
import './EditUser.scss';
@@ -18,7 +18,7 @@ import { Helmet } from 'react-helmet';
const EditUser = props => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
diff --git a/web/js/react/src/components/User/User.jsx b/web/js/react/src/components/User/User.jsx
index 17a122e9a..aee76a991 100644
--- a/web/js/react/src/components/User/User.jsx
+++ b/web/js/react/src/components/User/User.jsx
@@ -1,20 +1,17 @@
-import React, { useState } from 'react';
+import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { loginAs, logout } from 'src/actions/Session/sessionActions';
import Container from '../ControlPanel/Container/Container';
import ListItem from '../ControlPanel/ListItem/ListItem';
import { useDispatch, useSelector } from 'react-redux';
-import { Link, useHistory } from 'react-router-dom';
+import { Link } from 'react-router-dom';
import './User.scss';
-const { i18n } = window.GLOBAL.App;
-
const User = ({ data, toggleFav, handleModal, checkItem }) => {
- const [loading, setLoading] = useState(false);
+ const { i18n } = useSelector(state => state.session);
const session = useSelector(state => state.session);
const token = localStorage.getItem("token");
- const history = useHistory();
const dispatch = useDispatch();
const printNameServers = servers => {
@@ -26,22 +23,11 @@ const User = ({ data, toggleFav, handleModal, checkItem }) => {
}
const signInAs = username => {
- setLoading(true);
-
- dispatch(loginAs(username))
- .then(() => {
- setLoading(false);
- });
+ dispatch(loginAs(username));
}
const signOut = () => {
- setLoading(true);
-
- dispatch(logout())
- .then(() => {
- history.push('/login/');
- setLoading(false);
- });
+ dispatch(logout());
}
const printLoginActionButton = user => {
@@ -79,11 +65,11 @@ const User = ({ data, toggleFav, handleModal, checkItem }) => {
const handleSuspend = () => {
let suspendedStatus = data.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend';
- handleModal(data.spnd_conf, `/${suspendedStatus}/user?user=${data.NAME}&token=${token}`);
+ handleModal(data.spnd_conf, `/api/v1/${suspendedStatus}/user/index.php?user=${data.NAME}`);
}
const handleDelete = () => {
- handleModal(data.delete_conf, `/delete/user/?user=${data.NAME}&token=${token}`);
+ handleModal(data.delete_conf, `/api/v1/delete/user/index.php?user=${data.NAME}`);
}
return (
@@ -135,7 +121,7 @@ const User = ({ data, toggleFav, handleModal, checkItem }) => {
{printLoginActionButton(data.NAME)}
- {i18n.edit}
+ {i18n.edit}
{data.FOCUSED ? ↩ : }
diff --git a/web/js/react/src/components/User/User.scss b/web/js/react/src/components/User/User.scss
index fa4b8a206..c64e2d08b 100644
--- a/web/js/react/src/components/User/User.scss
+++ b/web/js/react/src/components/User/User.scss
@@ -1,3 +1,15 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$danger: #b00e5b;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
.checkbox {
margin-bottom: 10px;
}
@@ -19,8 +31,8 @@
border-radius: 50%;
&:hover {
- background: #bfbfbf;
- color: #ff6701;
+ background: #b4b4b478;
+ color: $primary;
}
}
}
@@ -178,11 +190,11 @@ span.stat.email{
}
> div:nth-child(2) a:hover {
- background: #9fbf0c;
+ background: $primary;
}
> div:nth-child(4) a:hover {
- background: #ff3438;
+ background: $danger;
}
svg {
@@ -191,5 +203,5 @@ span.stat.email{
}
.list-item.focused .r-col .name {
- color: #36b3a9;
+ color: $secondaryLight;
}
\ No newline at end of file
diff --git a/web/js/react/src/components/WebDomain/Add/AddWebDomain.jsx b/web/js/react/src/components/WebDomain/Add/AddWebDomain.jsx
index 417a9f878..200a813c0 100644
--- a/web/js/react/src/components/WebDomain/Add/AddWebDomain.jsx
+++ b/web/js/react/src/components/WebDomain/Add/AddWebDomain.jsx
@@ -9,13 +9,13 @@ import { getIpList } from '../../../ControlPanelService/Ip';
import Toolbar from '../../MainNav/Toolbar/Toolbar';
import { useHistory } from 'react-router-dom';
import Spinner from '../../Spinner/Spinner';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import './AddWebDomain.scss';
import { Helmet } from 'react-helmet';
const AddWebDomain = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const dispatch = useDispatch();
const token = localStorage.getItem("token");
const history = useHistory();
diff --git a/web/js/react/src/components/WebDomain/Add/AdditionalFtp/AdditionalFtp.jsx b/web/js/react/src/components/WebDomain/Add/AdditionalFtp/AdditionalFtp.jsx
index 54e98ca56..4cd4eb97a 100644
--- a/web/js/react/src/components/WebDomain/Add/AdditionalFtp/AdditionalFtp.jsx
+++ b/web/js/react/src/components/WebDomain/Add/AdditionalFtp/AdditionalFtp.jsx
@@ -1,12 +1,11 @@
-import React, { useEffect, useState } from 'react';
+import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import Password from '../../../../components/ControlPanel/AddItemLayout/Form/Password/Password';
import './AdditionalFtp.scss';
-const AdditionalFtp = ({ domain, data = {}, index, onDeleteAdditionalFtp, prefixI18N }) => {
- const { i18n } = window.GLOBAL.App;
- const { userName } = useSelector(state => state.session);
+const AdditionalFtp = ({ domain, data = {}, onDeleteAdditionalFtp, prefixI18N }) => {
+ const { i18n, userName } = useSelector(state => state.session);
const [state, setState] = useState({
path: '',
username: ''
@@ -15,16 +14,16 @@ const AdditionalFtp = ({ domain, data = {}, index, onDeleteAdditionalFtp, prefix
return (
- {i18n.FTP} #{index}
+ {i18n.FTP} #{data.id}
- onDeleteAdditionalFtp(index)}>({i18n.Delete ?? 'Delete'})
+ onDeleteAdditionalFtp(data.id)}>({i18n.Delete ?? 'Delete'})
diff --git a/web/js/react/src/components/WebDomain/Add/AdditionalFtpForEditing/AdditionalFtpForEditing.jsx b/web/js/react/src/components/WebDomain/Add/AdditionalFtpForEditing/AdditionalFtpForEditing.jsx
index c7a9c1f45..d31c6ab38 100644
--- a/web/js/react/src/components/WebDomain/Add/AdditionalFtpForEditing/AdditionalFtpForEditing.jsx
+++ b/web/js/react/src/components/WebDomain/Add/AdditionalFtpForEditing/AdditionalFtpForEditing.jsx
@@ -1,82 +1,106 @@
-import React, { useEffect, useState } from 'react';
+import React, { useState } from 'react';
import { useSelector } from 'react-redux';
import Password from '../../../../components/ControlPanel/AddItemLayout/Form/Password/Password';
import './AdditionalFtpForEditing.scss';
-const AdditionalFtpForEditing = ({ domain, data = {}, index, onDeleteAdditionalFtp, prefixI18N }) => {
- const { i18n } = window.GLOBAL.App;
- const { user } = useSelector(state => state.session);
+const AdditionalFtpForEditing = ({ domain, data = {}, onDeleteAdditionalFtp, prefixI18N, prePath, checked }) => {
+ const { userName, i18n } = useSelector(state => state.session);
const [state, setState] = useState({
- username: '',
+ username: data.v_ftp_user,
path: ''
});
- return (
-
-
-
-
+ const renderForm = () => {
+ if (data.deleted) {
+ if (data.is_new === 0) {
+ return (<>
+
+
+
+
+
+
+ >);
+ }
+ } else {
+ if (!checked) {
+ return <>>;
+ }
- {i18n.FTP} #{index + 1}
-
-
- onDeleteAdditionalFtp(index)}>({i18n.Delete ?? 'Delete'})
-
-
+ return (
+
+
+
-
-
-
-
{prefixI18N}
-
- setState({ ...state, username: event.target.value })}
- type="text"
- className="form-control"
- id={`ftp_user_${index}`}
- name={`v_ftp_user[${index}][v_ftp_user]`} />
- {user + '_'}{state.username}
-
+
{i18n.FTP} #{data.id + 1}
+
+
+ onDeleteAdditionalFtp(data.id)}>
+ ({i18n.Delete ?? 'Delete'})
+
+
-
-
-
-
-
-
-
- setState({ ...state, path: event.target.value })}
- className="form-control"
- id={`path${index}`}
- name={`v_ftp_user[${index}][v_ftp_path]`} />
- {`${data.v_ftp_pre_path ? data.v_ftp_pre_path : ''}/${state.path}`}
-
-
- {
- data.is_new === 1
- && (
-
-
+
+
+
+
{prefixI18N}
+
setState({ ...state, username: event.target.value })}
+ type="text"
+ disabled={data.v_ftp_user}
className="form-control"
- id={`sendLoginCredentialsToEmailAddress_${index}`}
- defaultValue={data.v_ftp_email}
- name={`v_ftp_user[${index}][v_ftp_email]`} />
+ id={`ftp_user_${data.id}`}
+ name={`v_ftp_user[${data.id}][v_ftp_user]`} />
+ {`${userName}_${state.username}`}
- )
- }
+
-
-
- );
+
+
+
+
+
+
+
+ setState({ ...state, path: event.target.value })}
+ className="form-control"
+ id={`path${data.id}`}
+ name={`v_ftp_user[${data.id}][v_ftp_path]`} />
+ {`${data.v_ftp_pre_path ? data.v_ftp_pre_path : ''}/${state.path}`}
+
+
+ {
+ data.is_new === 1 && (
+
+
+
+
+ )
+ }
+
+
+
);
+ }
+
+ return <>>;
+ }
+
+ return renderForm();
}
-export default AdditionalFtpForEditing;
\ No newline at end of file
+export default AdditionalFtpForEditing;
diff --git a/web/js/react/src/components/WebDomain/Add/AdditionalFtpWrapper/AdditionalFtpWrapper.jsx b/web/js/react/src/components/WebDomain/Add/AdditionalFtpWrapper/AdditionalFtpWrapper.jsx
index dee8820f9..32889438d 100644
--- a/web/js/react/src/components/WebDomain/Add/AdditionalFtpWrapper/AdditionalFtpWrapper.jsx
+++ b/web/js/react/src/components/WebDomain/Add/AdditionalFtpWrapper/AdditionalFtpWrapper.jsx
@@ -1,60 +1,61 @@
import React, { useEffect, useState } from 'react';
-
+import { useSelector } from 'react-redux';
import AdditionalFtp from '../AdditionalFtp/AdditionalFtp';
import AdditionalFtpForEditing from '../AdditionalFtpForEditing/AdditionalFtpForEditing';
const AdditionalFtpWrapper = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const [state, setState] = useState({
- additionalFtp: [1],
- editIndexing: false
+ additionalFtp: []
});
useEffect(() => {
if (props.ftps) {
- // For EditWeb.jsx. Second state is kept for indexing Additional Ftp ( starting from 0 )
- setState({ ...state, additionalFtp: props.ftps, editIndexing: true });
+ const data = props.ftps.map((item, index) => {
+ item['deleted'] = false;
+ item['id'] = index;
+ return item;
+ });
+ setState({ ...state, additionalFtp: data });
}
}, [props.ftps]);
const renderAdditionalFtps = () => {
- if (state.additionalFtp.length) {
- return state.additionalFtp.map((ftp, index) => {
- if (state.editIndexing) {
- return
onDeleteFtp(index)} />;
- } else {
- return onDeleteFtp(index)} />;
- }
- });
- } else {
- props.unCheckAdditionalFtpBox();
- }
+ return state.additionalFtp.map(ftp => {
+ return onDeleteFtp(id)} />;
+ });
}
const onDeleteFtp = index => {
- let additionalFtpsDuplicate = [...state.additionalFtp];
+ let updatedAdditionalFtps = [];
- additionalFtpsDuplicate.splice(index - 1, 1);
+ state.additionalFtp.forEach(item => {
+ if (item.id === index) {
+ item.deleted = true;
+ }
- setState({ ...state, additionalFtp: additionalFtpsDuplicate });
+ updatedAdditionalFtps.push(item);
+ });
+
+ if (!updatedAdditionalFtps.length) {
+ props.unCheckAdditionalFtpBox();
+ }
+
+ setState({ ...state, additionalFtp: updatedAdditionalFtps });
}
const addAdditionalFtp = () => {
let additionalFtpArrayLength = state.additionalFtp.length;
let additionalFtpsDuplicate = [...state.additionalFtp];
- additionalFtpsDuplicate.push(additionalFtpArrayLength + 1);
+ additionalFtpsDuplicate.push({ id: additionalFtpArrayLength, deleted: false, is_new: 1 });
setState({ ...state, additionalFtp: additionalFtpsDuplicate });
}
@@ -63,11 +64,12 @@ const AdditionalFtpWrapper = props => {
{renderAdditionalFtps()}
- addAdditionalFtp()}>
- {i18n['Add one more FTP Account'] ?? 'Add'}
-
+ {props.checked && (
+ addAdditionalFtp()}>
+ {i18n['Add one more FTP Account'] ?? 'Add'}
+ )}
);
}
-export default AdditionalFtpWrapper;
\ No newline at end of file
+export default AdditionalFtpWrapper;
diff --git a/web/js/react/src/components/WebDomain/Add/AdvancedOptions/AdvancedOptions.jsx b/web/js/react/src/components/WebDomain/Add/AdvancedOptions/AdvancedOptions.jsx
index e824c7f34..59228d02a 100644
--- a/web/js/react/src/components/WebDomain/Add/AdvancedOptions/AdvancedOptions.jsx
+++ b/web/js/react/src/components/WebDomain/Add/AdvancedOptions/AdvancedOptions.jsx
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react';
+import { useSelector } from 'react-redux';
import Password from '../../../../components/ControlPanel/AddItemLayout/Form/Password/Password';
import AdditionalFtpWrapper from '../AdditionalFtpWrapper/AdditionalFtpWrapper';
import SslSupport from '../SslSupport/SslSupport';
@@ -6,7 +7,7 @@ import SslSupport from '../SslSupport/SslSupport';
import './AdvancedOptions.scss';
const AdvancedOptions = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const [state, setState] = useState({
sslSupport: false,
additionalFtp: false,
diff --git a/web/js/react/src/components/WebDomain/Add/SslSupport/SslSupport.jsx b/web/js/react/src/components/WebDomain/Add/SslSupport/SslSupport.jsx
index 1f3441f96..877179a1d 100644
--- a/web/js/react/src/components/WebDomain/Add/SslSupport/SslSupport.jsx
+++ b/web/js/react/src/components/WebDomain/Add/SslSupport/SslSupport.jsx
@@ -1,9 +1,10 @@
import React, { useState } from 'react';
+import { useSelector } from 'react-redux';
import './SslSupport.scss';
const SslSupport = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const [letsEncrypt, setLetsEncrypt] = useState(false);
return (
diff --git a/web/js/react/src/components/WebDomain/Edit/EditWeb.jsx b/web/js/react/src/components/WebDomain/Edit/EditWeb.jsx
index 31be57f3a..e998febe2 100644
--- a/web/js/react/src/components/WebDomain/Edit/EditWeb.jsx
+++ b/web/js/react/src/components/WebDomain/Edit/EditWeb.jsx
@@ -12,7 +12,7 @@ import Spinner from '../../../components/Spinner/Spinner';
import Toolbar from '../../MainNav/Toolbar/Toolbar';
import SslSupport from './SslSupport/SslSupport';
import { useHistory } from 'react-router-dom';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import QS from 'qs';
import './EditWeb.scss';
@@ -21,7 +21,7 @@ import { Helmet } from 'react-helmet';
const EditWeb = props => {
const token = localStorage.getItem("token");
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const [state, setState] = useState({
@@ -30,7 +30,7 @@ const EditWeb = props => {
webStat: '',
sslSupport: false,
letsEncrypt: false,
- additionalFtp: true,
+ additionalFtp: false,
statAuth: false,
loading: false,
errorMessage: '',
@@ -56,6 +56,8 @@ const EditWeb = props => {
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
@@ -233,8 +235,7 @@ const EditWeb = props => {
id="stats" />
{
- state.webStat !== 'none'
- && (
+ state.webStat !== 'none' && (
{
title={i18n['Statistics Authorization']} />
{
- state.statAuth
- && (
+ state.statAuth && (
<>
@@ -262,15 +262,14 @@ const EditWeb = props => {
name="v_ftp"
id="add-ftp"
checked={state.additionalFtp}
- defaultChecked={!!state.data.ftp_user}
title={i18n['Additional FTP Account']} />
- {
- state.additionalFtp
- && (
- onChangeAdditionalFtp(false)} />
- )
- }
+ onChangeAdditionalFtp(false)} />
{i18n.Save}
@@ -284,4 +283,4 @@ const EditWeb = props => {
);
}
-export default EditWeb;
\ No newline at end of file
+export default EditWeb;
diff --git a/web/js/react/src/components/WebDomain/Edit/SslSupport/SslSupport.jsx b/web/js/react/src/components/WebDomain/Edit/SslSupport/SslSupport.jsx
index ac33f25c8..dbf9ef264 100644
--- a/web/js/react/src/components/WebDomain/Edit/SslSupport/SslSupport.jsx
+++ b/web/js/react/src/components/WebDomain/Edit/SslSupport/SslSupport.jsx
@@ -1,4 +1,5 @@
import React, { useEffect, useState } from 'react';
+import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import Checkbox from '../../../ControlPanel/AddItemLayout/Form/Checkbox/Checkbox';
import SelectInput from '../../../ControlPanel/AddItemLayout/Form/SelectInput/SelectInput';
@@ -7,7 +8,7 @@ import TextArea from '../../../ControlPanel/AddItemLayout/Form/TextArea/TextArea
import './SslSupport.scss';
const SslSupport = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const [letsEncrypt, setLetsEncrypt] = useState(false);
const [sslHomeOptions, setSslHomeOptions] = useState(['public_html', 'public_shtml']);
diff --git a/web/js/react/src/components/WebDomain/Edit/SslSupport/SslSupport.scss b/web/js/react/src/components/WebDomain/Edit/SslSupport/SslSupport.scss
index 16227ea1a..7bcbca864 100644
--- a/web/js/react/src/components/WebDomain/Edit/SslSupport/SslSupport.scss
+++ b/web/js/react/src/components/WebDomain/Edit/SslSupport/SslSupport.scss
@@ -1,3 +1,12 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #2e5bb1;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$secondaryActive: #fdb51c;
+$textColor: #555;
+
.edit-web {
.ssl-support {
.additional-info {
@@ -18,11 +27,11 @@
a.generate-csr {
text-transform: initial;
text-decoration: none;
- color: #2C9491;
+ color: $primary;
font-weight: bold;
&:hover {
- color: #ff6701;
+ color: $secondaryLight;
}
}
}
diff --git a/web/js/react/src/components/WebDomain/WebDomain.jsx b/web/js/react/src/components/WebDomain/WebDomain.jsx
index 9128f6d13..a869c13f1 100644
--- a/web/js/react/src/components/WebDomain/WebDomain.jsx
+++ b/web/js/react/src/components/WebDomain/WebDomain.jsx
@@ -4,10 +4,11 @@ import Container from '../ControlPanel/Container/Container';
import ListItem from '../ControlPanel/ListItem/ListItem';
import { Link } from 'react-router-dom';
import './WebDomain.scss';
+import { useSelector } from 'react-redux';
export default function WebDomain(props) {
const { data } = props;
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const printStat = (stat, text) => {
@@ -32,11 +33,11 @@ export default function WebDomain(props) {
const handleSuspend = () => {
let suspendedStatus = data.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend';
- props.handleModal(data.spnd_confirmation, `/${suspendedStatus}/web?domain=${data.NAME}&token=${token}`);
+ props.handleModal(data.spnd_confirmation, `/api/v1/${suspendedStatus}/web/index.php?domain=${data.NAME}`);
}
const handleDelete = () => {
- props.handleModal(data.delete_confirmation, `/delete/web/?domain=${data.NAME}&token=${token}`);
+ props.handleModal(data.delete_confirmation, `/api/v1/delete/web/index.php?domain=${data.NAME}`);
}
return (
diff --git a/web/js/react/src/containers/AddDNSWrapper/AddDNSWrapper.jsx b/web/js/react/src/containers/AddDNSWrapper/AddDNSWrapper.jsx
index 86baf96da..e87f00e3f 100644
--- a/web/js/react/src/containers/AddDNSWrapper/AddDNSWrapper.jsx
+++ b/web/js/react/src/containers/AddDNSWrapper/AddDNSWrapper.jsx
@@ -4,9 +4,10 @@ import AddDNSRecord from 'src/components/DNSRecord/Add/AddDNSRecord';
import { useHistory } from 'react-router-dom';
import QueryString from 'qs';
import { Helmet } from 'react-helmet';
+import { useSelector } from 'react-redux';
export default function AddDNSWrapper() {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const parsedQueryString = QueryString.parse(history.location.search, { ignoreQueryPrefix: true });
const [isDnsRecord, setIsDnsRecord] = useState(false);
diff --git a/web/js/react/src/containers/AddMailWrapper/AddMailWrapper.jsx b/web/js/react/src/containers/AddMailWrapper/AddMailWrapper.jsx
index 25e777e57..ee496f2eb 100644
--- a/web/js/react/src/containers/AddMailWrapper/AddMailWrapper.jsx
+++ b/web/js/react/src/containers/AddMailWrapper/AddMailWrapper.jsx
@@ -4,9 +4,10 @@ import AddMail from 'src/components/Mail/Add/AddMail';
import { useHistory } from 'react-router-dom';
import QueryString from 'qs';
import { Helmet } from 'react-helmet';
+import { useSelector } from 'react-redux';
export default function AddMailWrapper() {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const [domain, setDomain] = useState(false);
diff --git a/web/js/react/src/containers/App/App.js b/web/js/react/src/containers/App/App.js
index e801c9c26..2b56f067c 100755
--- a/web/js/react/src/containers/App/App.js
+++ b/web/js/react/src/containers/App/App.js
@@ -1,6 +1,6 @@
-import React, { useEffect } from 'react';
+import React, { useEffect, useState } from 'react';
import FileManager from '../FileManager/FileManager';
-import { Route, Switch, useHistory } from "react-router-dom";
+import { Route, Switch, useHistory, Redirect } from "react-router";
import Preview from '../../components/Preview/Preview';
import { library } from '@fortawesome/fontawesome-svg-core';
import * as Icon from '@fortawesome/free-solid-svg-icons';
@@ -11,10 +11,11 @@ import ControlPanelContent from '../ControlPanelContent/ControlPanelContent';
import WebLogs from '../WebLogs/WebLogs';
import LoginForm from 'src/components/Login/LoginForm';
import { useDispatch, useSelector } from 'react-redux';
-import { getAuthToken } from 'src/utils/token';
-import { logout, setToken } from 'src/actions/Session/sessionActions';
+import { setAuthToken } from 'src/utils/token';
+import { checkAuthHandler } from 'src/actions/Session/sessionActions';
import ServiceInfo from 'src/containers/ServiceInfo';
import ForgotPassword from 'src/components/ForgotPassword';
+import Spinner from 'src/components/Spinner/Spinner';
library.add(
Icon.faBook,
@@ -65,35 +66,63 @@ const App = () => {
const history = useHistory();
const dispatch = useDispatch();
const session = useSelector(state => state.session);
+ const [loading, setLoading] = useState(true);
useEffect(() => {
- const windowSessionToken = getAuthToken();
+ if (!Object.entries(session.i18n).length) {
+ dispatch(checkAuthHandler()).then(token => {
+ if (token) {
+ setAuthToken(token);
+ }
- if (!session.session && !session.user) {
- dispatch(logout());
- return;
- }
-
- if (!session.token && !windowSessionToken) {
- dispatch(logout());
- } else if (!session.token && windowSessionToken) {
- dispatch(setToken(windowSessionToken));
- } else if (session.token && !windowSessionToken) {
- dispatch(logout());
+ setLoading(false);
+ });
}
}, [dispatch, history, session]);
+ const AuthenticatedRoute = ({ authenticated, ...rest }) => {
+ return (
+
+ authenticated
+ ?
+ : } />
+ );
+ }
+
return (
-
-
-
-
-
-
-
-
-
+ {
+ loading
+ ?
+ : (
+
+
+
+
+
+
+
+
+
+ )
+ }
);
}
diff --git a/web/js/react/src/containers/App/App.scss b/web/js/react/src/containers/App/App.scss
index 6087c149c..5770c85c1 100644
--- a/web/js/react/src/containers/App/App.scss
+++ b/web/js/react/src/containers/App/App.scss
@@ -1,3 +1,15 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$danger: #b00e5b;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
.App {
font-size: 25px;
font-family: Arial;
@@ -38,17 +50,17 @@
div {
a.link-download:hover, button.link-download:hover,
a.link-edit:hover, button.link-edit:hover {
- background: #9fbf0c !important;
+ background: $primary !important;
}
a.link-list:hover,
button.link-list:hover {
- background: #55c9c0 !important;
+ background: $primary !important;
}
-
+
a.link-delete:hover,
button.link-delete:hover {
- background: #ff3438 !important;
+ background: $danger !important;
}
a.link-gray:hover,
@@ -66,7 +78,7 @@
}
button:active, a:active, .period:active {
- color: #55C9C0;
+ color: $primaryActive;
}
.list-item:first-child {
@@ -81,4 +93,82 @@ button {
&:hover, &:active, &:focus {
outline: none;
}
-}
\ No newline at end of file
+}
+
+.fixed-buttons.fm {
+ position: fixed;
+ right: 15px;
+ bottom: 15px;
+ display: flex;
+ justify-content: space-around;
+ align-items: center;
+
+ > div {
+ width: 40px;
+ height: 40px;
+ padding: 5px;
+ margin: 5px;
+ border-radius: 50%;
+ background: #c3c3c3;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ &:hover {
+ color: $hoverButtonText;
+ background: $primaryLight;
+ }
+
+ &:active {
+ color: $activeButtonText;
+ background: $primaryActive;
+ }
+
+ button {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ background: none;
+ border: none;
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ transform: scale(1.32);
+
+ svg {
+ color: white;
+ height: 70%;
+ }
+ }
+ }
+
+ > div:first-child {
+ background: $primary;
+
+ &:hover {
+ color: $hoverButtonText;
+ background: $primaryLight;
+
+ button svg {
+ color: $hoverButtonText;
+ }
+ }
+
+ &:active {
+ color: $activeButtonText;
+ background: $primaryActive;
+
+ button svg {
+ color: $activeButtonText;
+ }
+ }
+
+ button {
+ padding: 0;
+
+ svg {
+ color: $activeButtonText;
+ }
+ }
+ }
+}
diff --git a/web/js/react/src/containers/BackupWrapper/BackupWrapper.jsx b/web/js/react/src/containers/BackupWrapper/BackupWrapper.jsx
index 198a14a59..862d5b1ac 100644
--- a/web/js/react/src/containers/BackupWrapper/BackupWrapper.jsx
+++ b/web/js/react/src/containers/BackupWrapper/BackupWrapper.jsx
@@ -4,9 +4,10 @@ import { useHistory } from 'react-router-dom';
import Backups from '../Backups/Backups';
import QueryString from 'qs';
import { Helmet } from 'react-helmet';
+import { useSelector } from 'react-redux';
export default function BackupWrapper(props) {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const parsedQueryString = QueryString.parse(history.location.search, { ignoreQueryPrefix: true });
const [isBackupSettings, setIsBackupSettings] = useState(false);
diff --git a/web/js/react/src/containers/Backups/Backups.jsx b/web/js/react/src/containers/Backups/Backups.jsx
index 6ac1b7df8..4c5cc5750 100644
--- a/web/js/react/src/containers/Backups/Backups.jsx
+++ b/web/js/react/src/containers/Backups/Backups.jsx
@@ -18,7 +18,7 @@ import { Link } from 'react-router-dom';
import './Backups.scss';
const Backups = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
@@ -146,14 +146,14 @@ const Backups = props => {
}
const download = () => {
- props.history.push(`/download/backup?backup=${controlPanelFocusedElement}&token=${token}`);
+ props.history.push(`/download/backup?backup=${controlPanelFocusedElement}`);
}
const handleDelete = () => {
const { backups } = state;
let currentBackupData = backups.filter(backup => backup.NAME === controlPanelFocusedElement)[0];
- displayModal(currentBackupData.delete_conf, `/delete/cron/?job=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentBackupData.delete_conf, `/api/v1/delete/cron/?job=${controlPanelFocusedElement}`);
}
const fetchData = () => {
@@ -164,6 +164,8 @@ const Backups = props => {
backups: reformatData(result.data.data),
backupFav: result.data.backup_fav,
totalAmount: result.data.totalAmount,
+ selection: [],
+ toggledAll: false,
loading: false
});
})
diff --git a/web/js/react/src/containers/Backups/Exclusions/index.jsx b/web/js/react/src/containers/Backups/Exclusions/index.jsx
index 71d98e999..9a7e8168d 100644
--- a/web/js/react/src/containers/Backups/Exclusions/index.jsx
+++ b/web/js/react/src/containers/Backups/Exclusions/index.jsx
@@ -12,7 +12,7 @@ import Exclusion from 'src/components/Backup/Exclusion';
import { getBackupExclusions } from 'src/ControlPanelService/Backup';
const BackupExclusions = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
diff --git a/web/js/react/src/containers/ControlPanelContent/ControlPanelContent.jsx b/web/js/react/src/containers/ControlPanelContent/ControlPanelContent.jsx
index c2caf7dc2..5c90fd7dd 100644
--- a/web/js/react/src/containers/ControlPanelContent/ControlPanelContent.jsx
+++ b/web/js/react/src/containers/ControlPanelContent/ControlPanelContent.jsx
@@ -45,6 +45,7 @@ import Servers from '../../containers/Servers/Servers';
import MainNav from '../../components/MainNav/MainNav';
import BackupExclusions from '../Backups/Exclusions';
import MailWrapper from '../MailWrapper/MailWrapper';
+import Spinner from 'src/components/Spinner/Spinner';
import DNSWrapper from '../DNSWrapper/DNSWrapper';
import Statistics from '../Statistics/Statistics';
import Users from '../../containers/Users/Users';
@@ -57,17 +58,31 @@ import Logs from '../Logs/Logs';
import './ControlPanelContent.scss';
const ControlPanelContent = props => {
+ const { userName, session: { look } } = useSelector(state => state.session);
const history = useHistory();
const [searchTerm, setSearchTerm] = useState('');
const [hotkeysList, setHotkeysList] = useState(null);
- const { user, token } = useSelector(state => state.session);
+ const [loading, setLoading] = useState(true);
const dispatch = useDispatch();
useEffect(() => {
- if (!user && !token) {
- history.push('/login/');
+ if (userName) {
+ setLoading(false);
+ } else {
+ 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('/');
+ }
+ }
+ }, [userName, look]);
useEffect(() => {
dispatch(removeFocusedElement());
@@ -75,8 +90,8 @@ const ControlPanelContent = props => {
window.addEventListener("keyup", addNewObject);
return () => {
- window.addEventListener("keyup", switchPanelTab);
- window.addEventListener("keyup", addNewObject);
+ window.removeEventListener("keyup", switchPanelTab);
+ window.removeEventListener("keyup", addNewObject);
}
}, []);
@@ -87,22 +102,19 @@ const ControlPanelContent = props => {
return;
}
+ console.log(event);
switch (event.keyCode) {
- case 49: history.push('/list/user/'); return dispatchActiveElement('/list/user/');
- case 50: history.push('/list/web/'); return dispatchActiveElement('/list/web/');
- case 51: history.push('/list/dns/'); return dispatchActiveElement('/list/dns/');
- case 52: history.push('/list/mail/'); return dispatchActiveElement('/list/mail/');
- case 53: history.push('/list/db/'); return dispatchActiveElement('/list/db/');
- case 54: history.push('/list/cron/'); return dispatchActiveElement('/list/cron/');
- case 55: history.push('/list/backup/'); return dispatchActiveElement('/list/backup/');
+ case 49: return history.push('/list/user/');
+ case 50: return history.push('/list/web/');
+ case 51: return history.push('/list/dns/');
+ case 52: return history.push('/list/mail/');
+ case 53: return history.push('/list/db/');
+ case 54: return history.push('/list/cron/');
+ case 55: return history.push('/list/backup/');
default: break;
}
}
- const dispatchActiveElement = tab => {
- dispatch(addActiveElement(tab));
- }
-
const addNewObject = event => {
let isSearchInputFocused = document.querySelector('input:focus') || document.querySelector('textarea:focus');
@@ -112,7 +124,7 @@ const ControlPanelContent = props => {
if (event.keyCode === 65) {
switch (history.location.pathname) {
- case '/list/user/': return history.push('/add/user/');
+ case '/list/user/': return look ? history.push('/add/web/') : history.push('/add/user/');
case '/list/web/': return history.push('/add/web/');
case '/list/dns/': return history.push('/add/dns/');
case '/list/mail/': return history.push('/add/mail/');
@@ -141,72 +153,77 @@ const ControlPanelContent = props => {
return (
-
+
-
-
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
-
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
+ {
+ loading
+ ?
+ : (
+
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
- {
- !!services.length && services.map((service, index) => {
- if (service === 'iptables') {
- return
- } else {
- return } />
- }
- })
- }
+ {
+ !!services.length && services.map((service, index) => {
+ if (service === 'iptables') {
+ return
+ } else {
+ return } />
+ }
+ })
+ }
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
- } />
-
- } />
-
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+ } />
+
+ )}
@@ -225,4 +242,4 @@ const ControlPanelContent = props => {
);
}
-export default ControlPanelContent;
\ No newline at end of file
+export default ControlPanelContent;
diff --git a/web/js/react/src/containers/ControlPanelContent/ControlPanelContent.scss b/web/js/react/src/containers/ControlPanelContent/ControlPanelContent.scss
index d8710471e..1d24049f3 100644
--- a/web/js/react/src/containers/ControlPanelContent/ControlPanelContent.scss
+++ b/web/js/react/src/containers/ControlPanelContent/ControlPanelContent.scss
@@ -1,3 +1,15 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$danger: #b00e5b;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
.content {
padding: 0 13%;
padding-bottom: 1%;
@@ -49,14 +61,19 @@
align-items: center;
&:hover {
- background: #55c9c0;
+ color: $hoverButtonText;
+ background: $primaryLight;
}
&:active {
- background: #51beb5;
+ color: $activeButtonText;
+ background: $primaryActive;
}
button {
+ display: flex;
+ justify-content: center;
+ align-items: center;
background: none;
border: none;
width: 100%;
@@ -72,18 +89,20 @@
}
> div:first-child {
+ color: #c3c3c3;
background: none;
&:hover {
- background: #55c9c0;
+ background: $primaryLight;
button svg {
- color: white;
+ color: $activeButtonText;
}
}
&:active {
- background: #51beb5;
+ color: $activeButtonText;
+ background: $primaryActive;
}
button {
@@ -94,4 +113,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/web/js/react/src/containers/CronJobs/CronJobs.jsx b/web/js/react/src/containers/CronJobs/CronJobs.jsx
index dd00608ea..8872e60a5 100644
--- a/web/js/react/src/containers/CronJobs/CronJobs.jsx
+++ b/web/js/react/src/containers/CronJobs/CronJobs.jsx
@@ -18,7 +18,7 @@ import './CronJobs.scss';
import { Helmet } from 'react-helmet';
const CronJobs = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
@@ -153,14 +153,14 @@ const CronJobs = props => {
let currentCronJobData = cronJobs.filter(cronJob => cronJob.NAME === controlPanelFocusedElement)[0];
let suspendedStatus = currentCronJobData.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend';
- displayModal(currentCronJobData.suspend_conf, `/${suspendedStatus}/cron?job=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentCronJobData.suspend_conf, `/api/v1/${suspendedStatus}/cron/index.php?job=${controlPanelFocusedElement}`);
}
const handleDelete = () => {
const { cronJobs } = state;
let currentCronJobData = cronJobs.filter(cronJob => cronJob.NAME === controlPanelFocusedElement)[0];
- displayModal(currentCronJobData.delete_conf, `/delete/cron/?job=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentCronJobData.delete_conf, `/api/v1/delete/cron/index.php?job=${controlPanelFocusedElement}`);
}
const fetchData = () => {
@@ -171,6 +171,8 @@ const CronJobs = props => {
cronJobs: reformatData(result.data.data),
cronReports: result.data.cron_reports,
cronFav: result.data.cron_fav,
+ selection: [],
+ toggledAll: false,
totalAmount: result.data.totalAmount,
loading: false
});
@@ -360,7 +362,7 @@ const CronJobs = props => {
const handleCronNotifications = () => {
const token = localStorage.getItem("token");
- const url = `/api/${state.cronReports === 'yes' ? 'delete' : 'add'}/cron/reports/?token=${token}`;
+ const url = `/api/v1/${state.cronReports === 'yes' ? 'delete' : 'add'}/cron/reports/?token=${token}`;
handleAction(url)
.then(res => {
diff --git a/web/js/react/src/containers/CronJobs/CronJobs.scss b/web/js/react/src/containers/CronJobs/CronJobs.scss
index e0775ee5c..09953fb68 100644
--- a/web/js/react/src/containers/CronJobs/CronJobs.scss
+++ b/web/js/react/src/containers/CronJobs/CronJobs.scss
@@ -1,15 +1,27 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$danger: #b00e5b;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
.r-menu {
> div {
> button {
font-size: 13px;
background: white;
border-color: white;
- color: gray;
+ color: $textColor;
&:hover {
background: white;
border-color: white;
- color: gray;
+ color: $textColor;
}
}
}
@@ -24,7 +36,7 @@
.actions {
> div:nth-child(1) a:hover,
> div:nth-child(1) button:hover {
- background: #9fbf0c;
+ background: $primaryLight;
}
> div:nth-child(2) a:hover,
diff --git a/web/js/react/src/containers/DNSRecords/DNSRecords.jsx b/web/js/react/src/containers/DNSRecords/DNSRecords.jsx
index 63d611c88..730d5f90e 100644
--- a/web/js/react/src/containers/DNSRecords/DNSRecords.jsx
+++ b/web/js/react/src/containers/DNSRecords/DNSRecords.jsx
@@ -19,7 +19,7 @@ import './DNSRecords.scss';
import { Helmet } from 'react-helmet';
export default function DnsRecords(props) {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem('token');
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
@@ -151,7 +151,7 @@ export default function DnsRecords(props) {
const { databases } = state;
let currentDatabaseData = databases.filter(database => database.NAME === controlPanelFocusedElement)[0];
- displayModal(currentDatabaseData.delete_conf, `/delete/database/?domain=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentDatabaseData.delete_conf, `/api/v1/delete/database/?domain=${controlPanelFocusedElement}`);
}
const fetchData = () => {
@@ -167,6 +167,8 @@ export default function DnsRecords(props) {
dnsRecordFav: result.data.dnsRecordsFav,
totalAmount: result.data.totalAmount,
domain: parsedQueryString.domain,
+ toggledAll: false,
+ selection: [],
loading: false
});
})
diff --git a/web/js/react/src/containers/DNSRecords/DNSRecords.scss b/web/js/react/src/containers/DNSRecords/DNSRecords.scss
index e46d6395d..5d186f124 100644
--- a/web/js/react/src/containers/DNSRecords/DNSRecords.scss
+++ b/web/js/react/src/containers/DNSRecords/DNSRecords.scss
@@ -1,6 +1,18 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$danger: #b00e5b;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
.dns-records {
div.subtitle {
- color: #ff6701;
+ color: $primary;
font-size: 12px;
margin: 30px 0 18px 14.3%;
text-transform: uppercase;
diff --git a/web/js/react/src/containers/DNSWrapper/DNSWrapper.jsx b/web/js/react/src/containers/DNSWrapper/DNSWrapper.jsx
index 7d81fd18e..73eaa5ada 100644
--- a/web/js/react/src/containers/DNSWrapper/DNSWrapper.jsx
+++ b/web/js/react/src/containers/DNSWrapper/DNSWrapper.jsx
@@ -1,12 +1,13 @@
import QueryString from 'qs';
import React, { useEffect, useState } from 'react';
import { Helmet } from 'react-helmet';
+import { useSelector } from 'react-redux';
import { useHistory } from 'react-router-dom';
import DnsRecords from '../DNSRecords/DNSRecords';
import DomainNameSystems from '../DomainNameSystems/DomainNameSystems';
export default function DNSWrapper(props) {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const parsedQueryString = QueryString.parse(history.location.search, { ignoreQueryPrefix: true });
const [isDnsRecords, setIsDnsRecords] = useState(false);
diff --git a/web/js/react/src/containers/Databases/Databases.jsx b/web/js/react/src/containers/Databases/Databases.jsx
index b1d3debd7..fd39ef907 100644
--- a/web/js/react/src/containers/Databases/Databases.jsx
+++ b/web/js/react/src/containers/Databases/Databases.jsx
@@ -18,7 +18,7 @@ import './Databases.scss';
import { Helmet } from 'react-helmet';
const Databases = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
@@ -154,14 +154,14 @@ const Databases = props => {
let currentDatabaseData = databases.filter(database => database.NAME === controlPanelFocusedElement)[0];
let suspendedStatus = currentDatabaseData.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend';
- displayModal(currentDatabaseData.suspend_conf, `/${suspendedStatus}/database?domain=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentDatabaseData.suspend_conf, `/api/v1/${suspendedStatus}/database/index.php?domain=${controlPanelFocusedElement}`);
}
const handleDelete = () => {
const { databases } = state;
let currentDatabaseData = databases.filter(database => database.NAME === controlPanelFocusedElement)[0];
- displayModal(currentDatabaseData.delete_conf, `/delete/database/?domain=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentDatabaseData.delete_conf, `/api/v1/delete/database/index.php?domain=${controlPanelFocusedElement}`);
}
const fetchData = () => {
@@ -174,6 +174,7 @@ const Databases = props => {
dbAdminLink: result.data.db_admin_link,
dbFav: result.data.dbFav,
selection: [],
+ toggledAll: false,
totalAmount: result.data.totalAmount,
loading: false
});
diff --git a/web/js/react/src/containers/DomainNameSystems/DomainNameSystems.jsx b/web/js/react/src/containers/DomainNameSystems/DomainNameSystems.jsx
index 2691528b6..738eaa78b 100644
--- a/web/js/react/src/containers/DomainNameSystems/DomainNameSystems.jsx
+++ b/web/js/react/src/containers/DomainNameSystems/DomainNameSystems.jsx
@@ -19,7 +19,7 @@ import { useDispatch, useSelector } from 'react-redux';
import { Helmet } from 'react-helmet';
const DomainNameSystems = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
@@ -163,14 +163,14 @@ const DomainNameSystems = props => {
let currentDomainNameSystemData = domainNameSystems.filter(domainNameSystem => domainNameSystem.NAME === controlPanelFocusedElement)[0];
let suspendedStatus = currentDomainNameSystemData.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend';
- displayModal(currentDomainNameSystemData.suspend_conf, `/${suspendedStatus}/dns?domain=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentDomainNameSystemData.suspend_conf, `/api/v1/${suspendedStatus}/dns/index.php?domain=${controlPanelFocusedElement}`);
}
const handleDelete = () => {
const { domainNameSystems } = state;
let currentDomainNameSystemData = domainNameSystems.filter(domainNameSystem => domainNameSystem.NAME === controlPanelFocusedElement)[0];
- displayModal(currentDomainNameSystemData.delete_conf, `/delete/dns/?domain=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentDomainNameSystemData.delete_conf, `/api/v1/delete/dns/index.php?domain=${controlPanelFocusedElement}`);
}
const fetchData = () => {
@@ -183,6 +183,7 @@ const DomainNameSystems = props => {
domainNameSystems: reformatData(result.data.data),
dnsFav: result.data.dnsFav,
selection: [],
+ toggledAll: false,
totalAmount: result.data.totalAmount,
loading: false
});
diff --git a/web/js/react/src/containers/EditDNSWrapper/EditDNSWrapper.jsx b/web/js/react/src/containers/EditDNSWrapper/EditDNSWrapper.jsx
index 47c1f3cf9..9dfd91fab 100644
--- a/web/js/react/src/containers/EditDNSWrapper/EditDNSWrapper.jsx
+++ b/web/js/react/src/containers/EditDNSWrapper/EditDNSWrapper.jsx
@@ -4,9 +4,10 @@ import EditDNSRecord from 'src/components/DNSRecord/Edit/EditDNSRecord';
import { useHistory } from 'react-router-dom';
import QueryString from 'qs';
import { Helmet } from 'react-helmet';
+import { useSelector } from 'react-redux';
export default function EditDNSWrapper() {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const parsedQueryString = QueryString.parse(history.location.search, { ignoreQueryPrefix: true });
const [isDnsRecord, setIsDnsRecord] = useState(false);
diff --git a/web/js/react/src/containers/EditMailWrapper/EditMailWrapper.jsx b/web/js/react/src/containers/EditMailWrapper/EditMailWrapper.jsx
index f8146021d..f182df2ef 100644
--- a/web/js/react/src/containers/EditMailWrapper/EditMailWrapper.jsx
+++ b/web/js/react/src/containers/EditMailWrapper/EditMailWrapper.jsx
@@ -4,9 +4,10 @@ import EditMail from 'src/components/Mail/Edit/EditMail';
import { useHistory } from 'react-router-dom';
import QueryString from 'qs';
import { Helmet } from 'react-helmet';
+import { useSelector } from 'react-redux';
export default function EditMailWrapper() {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const parsedQueryString = QueryString.parse(history.location.search, { ignoreQueryPrefix: true });
const [isMailAccount, setIsMailAccount] = useState(false);
diff --git a/web/js/react/src/containers/FileManager/FileManager.js b/web/js/react/src/containers/FileManager/FileManager.js
index 5ca4c5b5c..452d7ada9 100644
--- a/web/js/react/src/containers/FileManager/FileManager.js
+++ b/web/js/react/src/containers/FileManager/FileManager.js
@@ -1,7 +1,6 @@
import React, { Component } from 'react';
import DirectoryList from '../../components/Lists/DirectoryList/DirectoryList';
import ProgressBar from '../../components/ProgressBar/ProgressBar';
-import HotkeysButton from '../../components/Hotkeys/HotkeysButton';
import { toast, ToastContainer } from 'react-toastify';
import Hotkeys from '../../components/Hotkeys/Hotkeys';
import Modal from '../../components/Modal/Modal';
@@ -9,27 +8,27 @@ import 'react-toastify/dist/ReactToastify.css';
import { withRouter } from 'react-router-dom';
import Menu from '../../components/Menu/Menu';
import * as FM from '../../FileManagerHelper';
-import '../App/App.scss';
import axios from 'axios';
import { Helmet } from 'react-helmet';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import 'src/containers/App/App.scss';
+import { connect } from 'react-redux';
const server = window.location.origin + "/file_manager/fm_api.php?";
-const { i18n } = window.GLOBAL.App;
-
class FileManager extends Component {
constructor(props) {
super(props);
this.state = {
leftList: {
- path: window.GLOBAL.ROOT_DIR,
+ path: this.props.session.user.HOME,
files: { listing: [] },
},
rightList: {
- path: window.GLOBAL.ROOT_DIR,
+ path: this.props.session.user.HOME,
files: { listing: [] },
},
- currentPath: window.GLOBAL.ROOT_DIR,
- currentUser: window.GLOBAL.ROOT_DIR,
+ currentPath: this.props.session.user.HOME,
+ currentUser: this.props.session.user.HOME,
activeWindow: "left",
modalWindow: null,
modalVisible: false,
@@ -40,20 +39,19 @@ class FileManager extends Component {
itemsSelected: [],
modalInputValue: "",
uploadPercent: "0",
- hotkeysPanel: "inactive",
loading: false
}
}
UNSAFE_componentWillMount = () => {
- FM.cacheData(this.state.currentUser, this.props.history);
+ FM.cacheData(this.state.currentUser, this.props.history, this.props.session.user.HOME);
let currentPath = FM.activeWindowPath();
this.setState({ currentPath });
this.changeDirectoryOnLoading();
}
componentDidMount = () => {
- if (!localStorage.getItem("token")) {
+ if (!localStorage.getItem("token") || !this.props.session.userName) {
this.props.history.push('/login/');
}
@@ -422,7 +420,7 @@ class FileManager extends Component {
}
render() {
- const { activeWindow, modalWindow, modalVisible, itemsSelected, itemName, loading, uploadPercent, hotkeysPanel, itemType } = this.state;
+ const { activeWindow, modalWindow, modalVisible, itemsSelected, itemName, loading, uploadPercent, itemType } = this.state;
const DirectoryLists = ['left', 'right'].map((side) =>
this[`${side}List`] = el}
download={this.download}
moveBack={this.moveBack}
@@ -448,7 +447,7 @@ class FileManager extends Component {
return (
- {i18n['File Manager']}
+ {this.props.session.i18n['File Manager']}
{uploadPercent !== "0" ?
: null}
@@ -464,8 +463,14 @@ class FileManager extends Component {
name={itemName} />
{DirectoryLists}
-
-
+
+
+ this.hotkeysList.classList.toggle('hide')}>
+
+
+
+
+
this.hotkeysList = inp} toggleHotkeys={() => this.hotkeysList.classList.toggle('hide')} />
{modalVisible && modalWindow}
@@ -473,4 +478,10 @@ class FileManager extends Component {
}
}
-export default withRouter(FileManager);
+function mapStateToProps(state) {
+ return {
+ session: state.session
+ }
+}
+
+export default connect(mapStateToProps)(withRouter(FileManager));
diff --git a/web/js/react/src/containers/Firewalls/Banlist/index.jsx b/web/js/react/src/containers/Firewalls/Banlist/index.jsx
index 6828f1fa9..a6e526e75 100644
--- a/web/js/react/src/containers/Firewalls/Banlist/index.jsx
+++ b/web/js/react/src/containers/Firewalls/Banlist/index.jsx
@@ -18,7 +18,7 @@ import { useHistory } from 'react-router';
import './styles.scss';
const BanLists = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
@@ -156,6 +156,8 @@ const BanLists = props => {
...state,
banIps: reformatData(result.data.data),
totalAmount: result.data.total_amount,
+ toggledAll: false,
+ selection: [],
loading: false
});
})
diff --git a/web/js/react/src/containers/Firewalls/Firewalls.jsx b/web/js/react/src/containers/Firewalls/Firewalls.jsx
index 54916d1db..b3bf6981e 100644
--- a/web/js/react/src/containers/Firewalls/Firewalls.jsx
+++ b/web/js/react/src/containers/Firewalls/Firewalls.jsx
@@ -19,7 +19,7 @@ import { Helmet } from 'react-helmet';
import { Link } from 'react-router-dom';
const Firewalls = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
@@ -154,14 +154,14 @@ const Firewalls = props => {
let currentFirewallData = firewalls.filter(firewall => firewall.NAME === controlPanelFocusedElement)[0];
let suspendedStatus = currentFirewallData.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend';
- displayModal(currentFirewallData.suspend_conf, `/${suspendedStatus}/firewall?rule=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentFirewallData.suspend_conf, `/api/v1/${suspendedStatus}/firewall/index.php?rule=${controlPanelFocusedElement}`);
}
const handleDelete = () => {
const { firewalls } = state;
let currentFirewallData = firewalls.filter(firewall => firewall.NAME === controlPanelFocusedElement)[0];
- displayModal(currentFirewallData.delete_conf, `/delete/firewall/?rule=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentFirewallData.delete_conf, `/api/v1/delete/firewall/index.php?rule=${controlPanelFocusedElement}`);
}
const fetchData = () => {
@@ -173,8 +173,10 @@ const Firewalls = props => {
...state,
firewalls: reformatData(result.data.data),
firewallFav: result.data.firewallFav,
+ selection: [],
firewallExtension: result.data.firewallExtension,
totalAmount: result.data.totalAmount,
+ toggledAll: false,
loading: false
});
})
diff --git a/web/js/react/src/containers/InternetProtocols/InternetProtocols.jsx b/web/js/react/src/containers/InternetProtocols/InternetProtocols.jsx
index 14f638eff..7a7357c7d 100644
--- a/web/js/react/src/containers/InternetProtocols/InternetProtocols.jsx
+++ b/web/js/react/src/containers/InternetProtocols/InternetProtocols.jsx
@@ -18,8 +18,7 @@ import './InternetProtocols.scss';
import { Helmet } from 'react-helmet';
const InternetProtocols = props => {
- const { i18n } = window.GLOBAL.App;
- const token = localStorage.getItem("token");
+ const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
@@ -150,7 +149,7 @@ const InternetProtocols = props => {
const { internetProtocols } = state;
let currentInternetProtocolData = internetProtocols.filter(pack => pack.NAME === controlPanelFocusedElement)[0];
- displayModal(currentInternetProtocolData.delete_conf, `/delete/ip/?ip=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentInternetProtocolData.delete_conf, `/api/v1/delete/ip/?ip=${controlPanelFocusedElement}`);
}
const fetchData = () => {
@@ -164,6 +163,7 @@ const InternetProtocols = props => {
ipFav: result.data.ipFav,
selection: [],
totalAmount: result.data.totalAmount,
+ toggledAll: false,
loading: false
});
})
diff --git a/web/js/react/src/containers/Logs/Logs.jsx b/web/js/react/src/containers/Logs/Logs.jsx
index e4ac90fd6..cbb87f951 100644
--- a/web/js/react/src/containers/Logs/Logs.jsx
+++ b/web/js/react/src/containers/Logs/Logs.jsx
@@ -13,7 +13,7 @@ import './Logs.scss';
import { Helmet } from 'react-helmet';
const Logs = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
diff --git a/web/js/react/src/containers/MailAccounts/MailAccounts.jsx b/web/js/react/src/containers/MailAccounts/MailAccounts.jsx
index 21f9084a7..a1fc89d4e 100644
--- a/web/js/react/src/containers/MailAccounts/MailAccounts.jsx
+++ b/web/js/react/src/containers/MailAccounts/MailAccounts.jsx
@@ -19,7 +19,7 @@ import './MailAccounts.scss';
import { Helmet } from 'react-helmet';
export default function MailAccounts(props) {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
@@ -153,14 +153,14 @@ export default function MailAccounts(props) {
let currentMailData = mailAccounts.filter(mail => mail.NAME === controlPanelFocusedElement)[0];
let suspendedStatus = currentMailData.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend';
- displayModal(currentMailData.suspend_conf, `/${suspendedStatus}/mail?domain=${props.domain}&account=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentMailData.suspend_conf, `/api/v1/${suspendedStatus}/mail/index.php?domain=${props.domain}&account=${controlPanelFocusedElement}`);
}
const handleDelete = () => {
const { mailAccounts } = state;
let currentMailData = mailAccounts.filter(mail => mail.NAME === controlPanelFocusedElement)[0];
- displayModal(currentMailData.delete_conf, `/delete/mail/?domain=${props.domain}&account=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentMailData.delete_conf, `/api/v1/delete/mail/index.php?domain=${props.domain}&account=${controlPanelFocusedElement}`);
}
const fetchData = () => {
@@ -173,6 +173,7 @@ export default function MailAccounts(props) {
mailAccounts: reformatData(result.data.data),
webMail: result.data.webMail,
selection: [],
+ toggledAll: false,
mailAccountsFav: result.data.mailAccountsFav,
totalAmount: result.data.totalAmount,
loading: false
diff --git a/web/js/react/src/containers/MailAccounts/MailAccounts.scss b/web/js/react/src/containers/MailAccounts/MailAccounts.scss
index ac776b06e..60edd05d5 100644
--- a/web/js/react/src/containers/MailAccounts/MailAccounts.scss
+++ b/web/js/react/src/containers/MailAccounts/MailAccounts.scss
@@ -1,6 +1,8 @@
+$primary: #2c54ac;
+
.mail-accounts {
div.subtitle {
- color: #ff6701;
+ color: $primary;
font-size: 12px;
margin: 30px 0 18px 14.3%;
text-transform: uppercase;
diff --git a/web/js/react/src/containers/MailWrapper/MailWrapper.jsx b/web/js/react/src/containers/MailWrapper/MailWrapper.jsx
index f7e8cfb91..ba1f1bfa4 100644
--- a/web/js/react/src/containers/MailWrapper/MailWrapper.jsx
+++ b/web/js/react/src/containers/MailWrapper/MailWrapper.jsx
@@ -4,9 +4,10 @@ import { useHistory } from 'react-router-dom';
import Mails from '../Mails/Mails';
import QueryString from 'qs';
import { Helmet } from 'react-helmet';
+import { useSelector } from 'react-redux';
export default function MailWrapper(props) {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const [mailDomain, setMailDomain] = useState('');
const history = useHistory();
diff --git a/web/js/react/src/containers/Mails/Mails.jsx b/web/js/react/src/containers/Mails/Mails.jsx
index fcd9d8109..aa77a1e29 100644
--- a/web/js/react/src/containers/Mails/Mails.jsx
+++ b/web/js/react/src/containers/Mails/Mails.jsx
@@ -19,7 +19,7 @@ import { useSelector, useDispatch } from 'react-redux';
import { Helmet } from 'react-helmet';
const Mails = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
@@ -164,14 +164,14 @@ const Mails = props => {
let currentMailData = mails.filter(mail => mail.NAME === controlPanelFocusedElement)[0];
let suspendedStatus = currentMailData.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend';
- displayModal(currentMailData.suspend_conf, `/${suspendedStatus}/mail?domain=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentMailData.suspend_conf, `/api/v1/${suspendedStatus}/mail/index.php?domain=${controlPanelFocusedElement}`);
}
const handleDelete = () => {
const { mails } = state;
let currentMailData = mails.filter(mail => mail.NAME === controlPanelFocusedElement)[0];
- displayModal(currentMailData.delete_conf, `/delete/mail/?domain=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentMailData.delete_conf, `/api/v1/delete/mail/index.php?domain=${controlPanelFocusedElement}`);
}
const fetchData = () => {
@@ -185,6 +185,7 @@ const Mails = props => {
webMail: result.data.webMail,
mailFav: result.data.mailFav,
selection: [],
+ toggledAll: false,
totalAmount: result.data.totalAmount,
loading: false
});
diff --git a/web/js/react/src/containers/Packages/Packages.jsx b/web/js/react/src/containers/Packages/Packages.jsx
index 0a4efcf8c..b9afb81a1 100644
--- a/web/js/react/src/containers/Packages/Packages.jsx
+++ b/web/js/react/src/containers/Packages/Packages.jsx
@@ -18,8 +18,7 @@ import './Packages.scss';
import { Helmet } from 'react-helmet';
const Packages = props => {
- const { i18n } = window.GLOBAL.App;
- const token = localStorage.getItem("token");
+ const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
@@ -150,7 +149,7 @@ const Packages = props => {
const { packages } = state;
let currentPackageData = packages.filter(pack => pack.NAME === controlPanelFocusedElement)[0];
- displayModal(currentPackageData.delete_conf, `/delete/package/?package=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentPackageData.delete_conf, `/api/v1/delete/package/?package=${controlPanelFocusedElement}`);
}
const fetchData = () => {
@@ -161,6 +160,8 @@ const Packages = props => {
packages: reformatData(result.data.data),
packagesFav: result.data.packagesFav,
totalAmount: result.data.totalAmount,
+ selection: [],
+ toggledAll: false,
loading: false
});
})
diff --git a/web/js/react/src/containers/RRDs/RRDs.jsx b/web/js/react/src/containers/RRDs/RRDs.jsx
index 229fe76d6..a7ab40bc1 100644
--- a/web/js/react/src/containers/RRDs/RRDs.jsx
+++ b/web/js/react/src/containers/RRDs/RRDs.jsx
@@ -13,7 +13,7 @@ import './RRDs.scss';
import { Helmet } from 'react-helmet';
const RRDs = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
diff --git a/web/js/react/src/containers/RRDs/RRDs.scss b/web/js/react/src/containers/RRDs/RRDs.scss
index 9acbfe230..d8d56698c 100644
--- a/web/js/react/src/containers/RRDs/RRDs.scss
+++ b/web/js/react/src/containers/RRDs/RRDs.scss
@@ -1,9 +1,21 @@
+$whiteBackground: #ececec;
+$primary: #2c54ac;
+$primaryLight: #d7dcef;
+$primaryActive: #1e5cb2;
+$secondary: #fcac04;
+$secondaryLight: #f8b014;
+$danger: #b00e5b;
+$secondaryActive: #fdb51c;
+$hoverButtonText: #2c54ac;
+$activeButtonText: #fff;
+$textColor: #555;
+
div.content {
margin-top: 0;
}
.rrd-list {
- color: #686868;
+ color: $textColor;
.toolbar {
padding-bottom: 10px;
@@ -49,11 +61,11 @@ div.content {
font-size: 14px;
&:hover {
- color: #ff6701;
+ color: $secondaryLight;
}
&:active {
- color: #55C9C0;
+ color: $primaryActive;
}
}
@@ -61,11 +73,11 @@ div.content {
> button svg {
&:hover {
- color: #ff6701;
+ color: $secondaryLight;
}
&:active {
- color: #55C9C0;
+ color: $primaryActive;
}
}
@@ -75,6 +87,6 @@ div.content {
}
> div.active {
- color: #ff6701;
+ color: $secondaryActive;
}
}
\ No newline at end of file
diff --git a/web/js/react/src/containers/Search/Search.jsx b/web/js/react/src/containers/Search/Search.jsx
index e7cc60477..02dd1e8f8 100644
--- a/web/js/react/src/containers/Search/Search.jsx
+++ b/web/js/react/src/containers/Search/Search.jsx
@@ -1,4 +1,4 @@
-import React, { Component } from 'react';
+import React, { Component, useEffect, useState } from 'react';
import DropdownFilter from '../../components/MainNav/Toolbar/DropdownFilter/DropdownFilter';
import { getSearchResultsList, handleAction } from '../../ControlPanelService/Search';
import SearchInput from '../../components/MainNav/Toolbar/SearchInput/SearchInput';
@@ -7,77 +7,84 @@ import Toolbar from '../../components/MainNav/Toolbar/Toolbar';
import Modal from '../../components/ControlPanel/Modal/Modal';
import Spinner from '../../components/Spinner/Spinner';
import './Search.scss';
+import { useSelector } from 'react-redux';
+import { useHistory } from 'react-router-dom';
-class Search extends Component {
- state = {
+const Search = props => {
+ const { i18n } = useSelector(state => state.session);
+ const history = useHistory();
+ const [state, setState] = useState({
searchResults: [],
totalAmount: '',
- modalText: '',
- modalVisible: false,
- modalActionUrl: '',
- sorting: window.GLOBAL.App.i18n.Date,
+ sorting: i18n.Date,
order: "descending",
loading: false,
total: 0
- }
+ });
+ const [modal, setModal] = useState({
+ visible: false,
+ text: '',
+ actionUrl: ''
+ });
- componentWillMount() {
- const { search } = this.props.history.location;
+ useEffect(() => {
+ const { search } = history.location;
if (search) {
let searchTerm = search.split('=')[1];
if (searchTerm !== '') {
- this.fetchData(searchTerm);
+ fetchData(searchTerm);
} else {
- return this.props.history.push({ pathname: '/list/user/', search: '' });
+ return history.push({ pathname: '/list/user/', search: '' });
}
- } else if (this.props.searchTerm !== '') {
- this.fetchData(this.props.searchTerm);
+ } else if (props.searchTerm !== '') {
+ fetchData(props.searchTerm);
} else {
- return this.props.history.push({ pathname: '/list/user/', search: '' });
+ return history.push({ pathname: '/list/user/', search: '' });
}
+ }, []);
+
+ const fetchData = searchTerm => {
+ setState({ ...state, loading: true });
+ getSearchResultsList(searchTerm)
+ .then(result => {
+ setState({
+ ...state,
+ searchResults: result.data.data,
+ totalAmount: result.data.total_amount,
+ loading: false
+ });
+ })
+ .catch(err => console.error(err));
}
- fetchData = searchTerm => {
- this.setState({ loading: true }, () => {
- getSearchResultsList(searchTerm)
- .then(result => {
- this.setState({
- searchResults: result.data.data,
- totalAmount: result.data.totalAmount,
- loading: false
- });
- })
- .catch(err => console.error(err));
- });
- }
-
- searchResults = () => {
- const { searchResults } = this.state;
+ const searchResults = () => {
+ const { searchResults } = state;
const result = [];
for (let i in searchResults) {
result.push(searchResults[i]);
}
- let sortedResult = this.sortArray(result);
+ let sortedResult = sortArray(result);
return sortedResult.map((item, index) => {
- return ;
+ return ;
});
}
- changeSorting = (sorting, order) => {
- this.setState({
+ const changeSorting = (sorting, order) => {
+ setState({
+ ...state,
sorting,
order
});
}
- sortArray = array => {
- const { order, sorting } = this.state;
- let sortBy = this.sortBy(sorting);
+ const sortArray = array => {
+ const { order, sorting } = state;
+ let sortBy = sortByHandler(sorting);
if (order === "descending") {
return array.sort((a, b) => (a[sortBy] < b[sortBy]) ? 1 : ((b[sortBy] < a[sortBy]) ? -1 : 0));
@@ -86,8 +93,8 @@ class Search extends Component {
}
}
- sortBy = sorting => {
- const { Date, Name, Starred } = window.GLOBAL.App.i18n;
+ const sortByHandler = sorting => {
+ const { Date, Name, Starred } = i18n;
switch (sorting) {
case Date: return 'DATE';
@@ -97,53 +104,53 @@ class Search extends Component {
}
}
- displayModal = (text, url) => {
- this.setState({
- modalVisible: !this.state.modalVisible,
- modalText: text,
- modalActionUrl: url
+ const displayModal = (text, url) => {
+ setModal({
+ ...modal,
+ visible: !modal.visible,
+ text,
+ actionUrl: url
});
}
- modalConfirmHandler = () => {
- handleAction(this.state.modalActionUrl)
+ const modalConfirmHandler = () => {
+ handleAction(state.modalActionUrl)
.then(() => {
- this.fetchData();
- this.modalCancelHandler();
+ fetchData();
+ modalCancelHandler();
})
.catch(err => console.error(err));
}
- modalCancelHandler = () => {
- this.setState({
- modalVisible: false,
- modalText: '',
- modalActionUrl: ''
+ const modalCancelHandler = () => {
+ setModal({
+ ...modal,
+ visible: false,
+ text: '',
+ actionUrl: ''
});
}
- render() {
- return (
-
-
- {window.GLOBAL.App.i18n['Search Results']}
-
-
- this.props.changeSearchTerm(term)} />
-
-
-
- {this.state.loading ?
: this.searchResults()}
+ return (
+
+
+ {i18n['Search Results']}
+
+
+ props.changeSearchTerm(term)} />
- {this.state.totalAmount}
-
+
+
+ {state.loading ? : searchResults()}
- );
- }
+
{state.totalAmount}
+
+
+ );
}
-export default Search;
\ No newline at end of file
+export default Search;
diff --git a/web/js/react/src/containers/Search/Search.scss b/web/js/react/src/containers/Search/Search.scss
index b67d6ff6b..ace8cf0a0 100644
--- a/web/js/react/src/containers/Search/Search.scss
+++ b/web/js/react/src/containers/Search/Search.scss
@@ -1,9 +1,11 @@
+$secondary: #fcac04;
+
.content {
.toolbar {
.search-toolbar-name {
font-size: 12px;
text-transform: uppercase;
- color: #ff6701;
+ color: $secondary;
font-weight: bold;
margin-left: 14.3%;
padding-left: 7px;
diff --git a/web/js/react/src/containers/Servers/Servers.jsx b/web/js/react/src/containers/Servers/Servers.jsx
index 8b69b7566..8e6c86e03 100644
--- a/web/js/react/src/containers/Servers/Servers.jsx
+++ b/web/js/react/src/containers/Servers/Servers.jsx
@@ -17,7 +17,7 @@ import { Helmet } from 'react-helmet';
import './Servers.scss';
const Servers = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
@@ -148,11 +148,11 @@ const Servers = props => {
}
const handleStop = () => {
- onHandleAction(controlPanelFocusedElement.action_url);
+ onHandleAction('/api/v1' + controlPanelFocusedElement.action_url);
}
const handleRestart = () => {
- onHandleAction(`/api/restart/service/?srv=${controlPanelFocusedElement.NAME}`);
+ onHandleAction(`/api/v1/restart/service/?srv=${controlPanelFocusedElement.NAME}`);
}
const fetchData = () => {
@@ -162,6 +162,8 @@ const Servers = props => {
.then(result => {
setState({
...state,
+ selection: [],
+ toggledAll: false,
servers: reformatData(result.data.data, result.data.sys),
loading: false
});
diff --git a/web/js/react/src/containers/ServiceInfo/index.jsx b/web/js/react/src/containers/ServiceInfo/index.jsx
index 4bd926037..6c169ea4b 100644
--- a/web/js/react/src/containers/ServiceInfo/index.jsx
+++ b/web/js/react/src/containers/ServiceInfo/index.jsx
@@ -13,10 +13,9 @@ import ReactHtmlParser from 'react-html-parser';
import './styles.scss';
const ServiceInfo = () => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n, userName } = useSelector(state => state.session);
const dispatch = useDispatch();
- const mainNavigation = useSelector(state => state.mainNavigation);
- const { user, token } = useSelector(state => state.session);
+ const { activeElement } = useSelector(state => state.mainNavigation);
const history = useHistory();
const { service } = useParams();
const [state, setState] = useState({
@@ -25,15 +24,15 @@ const ServiceInfo = () => {
});
useEffect(() => {
- if (!user && !token) {
+ if (!userName) {
history.push('/login/');
}
- }, []);
+ }, [userName]);
useEffect(() => {
fetchData();
dispatch(addActiveElement(`/list/server/${service}`));
- }, [mainNavigation.activeElement]);
+ }, [activeElement]);
const fetchData = () => {
setState({ ...state, loading: true });
diff --git a/web/js/react/src/containers/Statistics/Statistics.jsx b/web/js/react/src/containers/Statistics/Statistics.jsx
index f2f28d301..9ed4f8e97 100644
--- a/web/js/react/src/containers/Statistics/Statistics.jsx
+++ b/web/js/react/src/containers/Statistics/Statistics.jsx
@@ -14,7 +14,7 @@ import './Statistics.scss';
import { Helmet } from 'react-helmet';
const Statistics = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
diff --git a/web/js/react/src/containers/Updates/Updates.jsx b/web/js/react/src/containers/Updates/Updates.jsx
index 1cacceae6..94a126815 100644
--- a/web/js/react/src/containers/Updates/Updates.jsx
+++ b/web/js/react/src/containers/Updates/Updates.jsx
@@ -15,7 +15,7 @@ import './Updates.scss';
import { Helmet } from 'react-helmet';
const Updates = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
@@ -124,6 +124,7 @@ const Updates = props => {
.then(result => {
setState({
...state,
+ selection: [],
updates: reformatData(result.data.data),
autoUpdate: result.data.totalAmount,
loading: false
diff --git a/web/js/react/src/containers/Users/Users.jsx b/web/js/react/src/containers/Users/Users.jsx
index a3f1d4c38..f3739d0c0 100644
--- a/web/js/react/src/containers/Users/Users.jsx
+++ b/web/js/react/src/containers/Users/Users.jsx
@@ -18,8 +18,7 @@ import { Helmet } from 'react-helmet';
import './Users.scss';
const Users = props => {
- const { i18n } = window.GLOBAL.App;
- const { token, userName } = useSelector(state => state.session);
+ const { userName, i18n, session: { look } } = useSelector(state => state.session);
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
const dispatch = useDispatch();
@@ -50,10 +49,6 @@ const Users = props => {
}
}, []);
- useEffect(() => {
- fetchData();
- }, [userName]);
-
useEffect(() => {
window.addEventListener("keydown", handleContentSelection);
window.addEventListener("keydown", handleFocusedElementShortcuts);
@@ -74,6 +69,8 @@ const Users = props => {
users: reformatData(result.data.data),
userFav: result.data.userFav,
totalAmount: result.data.totalAmount,
+ toggledAll: false,
+ selection: [],
loading: false
});
})
@@ -111,14 +108,14 @@ const Users = props => {
let currentUserData = users.filter(user => user.NAME === controlPanelFocusedElement)[0];
let suspendedStatus = currentUserData.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend';
- displayModal(currentUserData.spnd_conf, `/${suspendedStatus}/user?user=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentUserData.spnd_conf, `/api/v1/${suspendedStatus}/user/index.php?user=${controlPanelFocusedElement}`);
}
const handleDelete = () => {
const { users } = state;
let currentUserData = users.filter(user => user.NAME === controlPanelFocusedElement)[0];
- displayModal(currentUserData.delete_conf, `/delete/user?user=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentUserData.delete_conf, `/api/v1/delete/user/index.php?user=${controlPanelFocusedElement}`);
}
const handleContentSelection = event => {
@@ -372,7 +369,10 @@ const Users = props => {
{`Vesta - ${i18n.USER}`}
-
+
diff --git a/web/js/react/src/containers/Web/Web.jsx b/web/js/react/src/containers/Web/Web.jsx
index 563ac86e9..4d367bedd 100644
--- a/web/js/react/src/containers/Web/Web.jsx
+++ b/web/js/react/src/containers/Web/Web.jsx
@@ -18,7 +18,7 @@ import { Helmet } from 'react-helmet';
import './Web.scss';
const Web = props => {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const token = localStorage.getItem("token");
const { controlPanelFocusedElement } = useSelector(state => state.controlPanelContent);
const { focusedElement } = useSelector(state => state.mainNavigation);
@@ -157,14 +157,14 @@ const Web = props => {
let currentWebDomainData = webDomains.filter(webDomain => webDomain.NAME === controlPanelFocusedElement)[0];
let suspendedStatus = currentWebDomainData.SUSPENDED === 'yes' ? 'unsuspend' : 'suspend';
- displayModal(currentWebDomainData.spnd_confirmation, `/${suspendedStatus}/web?domain=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentWebDomainData.spnd_confirmation, `/api/v1/${suspendedStatus}/web/index.php?domain=${controlPanelFocusedElement}`);
}
const handleDelete = () => {
const { webDomains } = state;
let currentWebDomainData = webDomains.filter(webDomain => webDomain.NAME === controlPanelFocusedElement)[0];
- displayModal(currentWebDomainData.delete_confirmation, `/delete/web/?domain=${controlPanelFocusedElement}&token=${token}`);
+ displayModal(currentWebDomainData.delete_confirmation, `/api/v1/web/index.php?domain=${controlPanelFocusedElement}`);
}
const fetchData = () => {
@@ -177,6 +177,8 @@ const Web = props => {
webDomains: reformatData(result.data.data),
webFav: result.data.webFav,
totalAmount: result.data.totalAmount,
+ toggledAll: false,
+ selection: [],
loading: false
});
})
@@ -363,7 +365,7 @@ const Web = props => {
{`Vesta - ${i18n.WEB}`}
-
+
diff --git a/web/js/react/src/containers/WebLogs/WebLogs.jsx b/web/js/react/src/containers/WebLogs/WebLogs.jsx
index 33570dbab..76d7c4c31 100644
--- a/web/js/react/src/containers/WebLogs/WebLogs.jsx
+++ b/web/js/react/src/containers/WebLogs/WebLogs.jsx
@@ -12,11 +12,11 @@ import Spinner from 'src/components/Spinner/Spinner';
import { Helmet } from 'react-helmet';
export default function WebLogs() {
- const { i18n } = window.GLOBAL.App;
+ const { i18n } = useSelector(state => state.session);
const history = useHistory();
const dispatch = useDispatch();
const mainNavigation = useSelector(state => state.mainNavigation);
- const { user, token } = useSelector(state => state.session);
+ const { userName } = useSelector(state => state.session);
const [domain, setDomain] = useState();
const [state, setState] = useState({
data: "",
@@ -24,25 +24,24 @@ export default function WebLogs() {
});
useEffect(() => {
- if (!user && !token) {
+ if (!userName) {
history.push('/login/');
}
}, []);
useEffect(() => {
let parsedQueryString = QueryString.parse(history.location.search, { ignoreQueryPrefix: true });
+ const { domain, type } = parsedQueryString;
- if (!parsedQueryString && !parsedQueryString.domain && !parsedQueryString.type) {
+ if (!parsedQueryString && !domain && !type) {
return history.goBack();
}
setDomain(domain);
- let uri = `/list/web-log/?domain=${domain}&type=${parsedQueryString.type}`;
- history.push(uri);
-
+ let uri = `/list/web-log/?domain=${domain}&type=${type}`;
fetchData(uri);
- dispatch(addActiveElement(`/list/web-log/${parsedQueryString.type}`));
+ dispatch(addActiveElement(`/list/web-log/${type}`));
}, [mainNavigation.activeElement]);
const fetchData = uri => {
@@ -77,10 +76,12 @@ export default function WebLogs() {
const extraMenuItems = [
{
link: `/download/web-log/?domain=${domain ?? ''}&type=access`,
+ type: 'download',
text: i18n['Download AccessLog']
},
{
link: `/download/web-log/?domain=${domain ?? ''}&type=error`,
+ type: 'download',
text: i18n['Download ErrorLog'],
}
];
@@ -104,4 +105,4 @@ export default function WebLogs() {
);
-}
\ No newline at end of file
+}
diff --git a/web/js/react/src/containers/WebLogs/WebLogs.scss b/web/js/react/src/containers/WebLogs/WebLogs.scss
index eefdc5558..7c0ee04ee 100644
--- a/web/js/react/src/containers/WebLogs/WebLogs.scss
+++ b/web/js/react/src/containers/WebLogs/WebLogs.scss
@@ -4,4 +4,9 @@
color: #7d7d7d;
font-size: 20px;
}
+
+ .nav-link:nth-child(3),
+ .nav-link:nth-child(4) {
+ width: 9rem;
+ }
}
\ No newline at end of file
diff --git a/web/js/react/src/reducers/MainNavigation/mainNavigationReducer.js b/web/js/react/src/reducers/MainNavigation/mainNavigationReducer.js
index ab8bc67d7..3f6fa428b 100644
--- a/web/js/react/src/reducers/MainNavigation/mainNavigationReducer.js
+++ b/web/js/react/src/reducers/MainNavigation/mainNavigationReducer.js
@@ -3,7 +3,7 @@ import { ADD_FOCUSED_ELEMENT, ADD_ACTIVE_ELEMENT, REMOVE_ACTIVE_ELEMENT, REMOVE_
const INITIAL_STATE = {
focusedElement: '',
activeElement: '',
- menuTabs: [
+ adminMenuTabs: [
'/list/user/',
'/list/web/',
'/list/dns/',
@@ -19,7 +19,21 @@ const INITIAL_STATE = {
'/list/updates/',
'/list/firewall/',
'/list/directory/',
+ '/softaculous/',
'/list/server/'
+ ],
+ userMenuTabs: [
+ '/list/user/',
+ '/list/web/',
+ '/list/dns/',
+ '/list/mail/',
+ '/list/db/',
+ '/list/cron/',
+ '/list/backup/',
+ '/list/stats/',
+ '/list/log/',
+ '/list/directory/',
+ '/softaculous/',
]
};
diff --git a/web/js/react/src/reducers/Notification/notificationReducer.js b/web/js/react/src/reducers/Notification/notificationReducer.js
new file mode 100644
index 000000000..0e3a269eb
--- /dev/null
+++ b/web/js/react/src/reducers/Notification/notificationReducer.js
@@ -0,0 +1,25 @@
+import { ADD_NOTIFICATIONS, REMOVE_NOTIFICATIONS } from 'src/actions/Notification/notificationTypes';
+
+const INITIAL_STATE = {
+ notifications: []
+};
+
+const notificationReducer = (state = INITIAL_STATE, action) => {
+ switch (action.type) {
+ case ADD_NOTIFICATIONS:
+ return {
+ ...state,
+ notifications: action.value,
+ };
+
+ case REMOVE_NOTIFICATIONS:
+ return {
+ ...state,
+ notifications: action.value,
+ };
+
+ default: return state;
+ }
+};
+
+export default notificationReducer;
diff --git a/web/js/react/src/reducers/Session/sessionReducer.js b/web/js/react/src/reducers/Session/sessionReducer.js
index ace9a7291..7556b7bca 100644
--- a/web/js/react/src/reducers/Session/sessionReducer.js
+++ b/web/js/react/src/reducers/Session/sessionReducer.js
@@ -1,10 +1,11 @@
-import { LOGGED_OUT_AS, LOGIN, LOGOUT } from '../../actions/Session/sessionTypes';
+import { LOGGED_OUT_AS, LOGIN, LOGOUT, CHECK_AUTH } from '../../actions/Session/sessionTypes';
const INITIAL_STATE = {
token: '',
user: {},
error: '',
session: {},
+ i18n: {},
userName: '',
panel: {}
};
@@ -18,6 +19,7 @@ const sessionReducer = (state = INITIAL_STATE, action) => {
user: action.value.user,
session: action.value.session,
userName: action.value.userName,
+ i18n: action.value.i18n || {},
panel: action.value.panel,
error: action.value.error
};
@@ -29,6 +31,7 @@ const sessionReducer = (state = INITIAL_STATE, action) => {
user: action.value.user,
session: action.value.session,
userName: action.value.userName,
+ i18n: action.value.i18n || {},
panel: action.value.panel,
error: action.value.error
};
@@ -40,10 +43,22 @@ const sessionReducer = (state = INITIAL_STATE, action) => {
user: action.value.user,
session: action.value.session,
userName: action.value.userName,
+ i18n: action.value.i18n || {},
panel: action.value.panel,
error: action.value.error
};
+ case CHECK_AUTH: return {
+ ...state,
+ token: action.value.token,
+ user: action.value.user,
+ session: action.value.session,
+ userName: action.value.userName,
+ i18n: action.value.i18n || {},
+ panel: action.value.panel,
+ error: action.value.error
+ };
+
default: return state;
}
};
diff --git a/web/js/react/src/reducers/rootReducer.js b/web/js/react/src/reducers/rootReducer.js
index fa420d530..28925154f 100644
--- a/web/js/react/src/reducers/rootReducer.js
+++ b/web/js/react/src/reducers/rootReducer.js
@@ -1,10 +1,12 @@
import { combineReducers } from 'redux';
import mainNavigationReducer from './MainNavigation/mainNavigationReducer';
import controlPanelContentReducer from './ControlPanelContent/controlPanelContentReducer';
+import notificationReducer from './Notification/notificationReducer';
import sessionReducer from './Session/sessionReducer';
export default combineReducers({
mainNavigation: mainNavigationReducer,
controlPanelContent: controlPanelContentReducer,
+ notifications: notificationReducer,
session: sessionReducer,
});
\ No newline at end of file
diff --git a/web/js/react/src/services/session.js b/web/js/react/src/services/session.js
index a272f62ee..412cbf5f5 100644
--- a/web/js/react/src/services/session.js
+++ b/web/js/react/src/services/session.js
@@ -1,26 +1,52 @@
import axios from 'axios';
+import { getAuthToken } from 'src/utils/token';
const BASE_URL = window.location.origin;
-export const signIn = (user, password) => {
- return axios.post(`${BASE_URL}/api/login/index.php`, {
- user,
- password,
- });
+export const signIn = (data) => {
+ let formDataObject = new FormData();
+
+ for (let key in data) {
+ formDataObject.append(key, data[key]);
+ }
+
+ formDataObject.append("token", getAuthToken());
+
+ return axios.post(`${BASE_URL}/api/v1/login/index.php`, formDataObject);
+};
+
+export const checkAuth = () => {
+ let uri = '/api/v1/login/index.php';
+ const token = getAuthToken();
+
+ if (token) uri += `?token=${token}`;
+
+ return axios.get(`${BASE_URL}${uri}`);
};
export const signInAs = (username) => {
- return axios.get(`${BASE_URL}/api/login/index.php`, {
+ return axios.get(`${BASE_URL}/api/v1/login/index.php`, {
params: {
- loginas: username
+ loginas: username,
+ token: getAuthToken()
}
});
};
export const signOut = () => {
- return axios.get(`${BASE_URL}/api/logout/index.php`);
+ return axios.get(`${BASE_URL}/api/v1/logout/index.php`);
};
-export const checkAuth = token => {
- return axios.get(`${BASE_URL}/api/login/session.php?token=${token}`);
+export const getMainData = () => {
+ let uri = `${BASE_URL}/api/v1/login/session.php`;
+
+ return axios.get(uri);
+};
+
+export const checkAuthToken = token => {
+ let uri = `${BASE_URL}/api/v1/login/session.php`;
+
+ if (token) uri += `?token=${token}`;
+
+ return axios.get(uri);
};