mirror of
https://github.com/serghey-rodin/vesta.git
synced 2025-07-05 20:41:51 -07:00
FM progress bar while uploading. Minor CPanel improvements as well as performance.
This commit is contained in:
parent
eb5a045252
commit
5b2c180d86
36 changed files with 310 additions and 243 deletions
|
@ -17,6 +17,18 @@ export const getBanList = () => {
|
|||
return axios.get(BASE_URL + banListUri);
|
||||
}
|
||||
|
||||
export const bulkFirewallAction = (action, ips) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
formData.append("token", getAuthToken());
|
||||
|
||||
ips.forEach(ip => {
|
||||
formData.append("rule[]", ip);
|
||||
});
|
||||
|
||||
return axios.post(BASE_URL + '/api/v1/bulk/firewall/', formData);
|
||||
};
|
||||
|
||||
export const bulkAction = (action, ips, banIps) => {
|
||||
const formData = new FormData();
|
||||
formData.append("action", action);
|
||||
|
|
|
@ -9,7 +9,7 @@ const TextInput = ({ id, name, title, optionalTitle = '', type = 'text', onChang
|
|||
}
|
||||
}, [value]);
|
||||
|
||||
const changeCheckbox = event => {
|
||||
const changeInputHandler = event => {
|
||||
setInputValue(event.target.value);
|
||||
onChange(event);
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ const TextInput = ({ id, name, title, optionalTitle = '', type = 'text', onChang
|
|||
type={type}
|
||||
name={name}
|
||||
id={id}
|
||||
onChange={changeCheckbox}
|
||||
onChange={changeInputHandler}
|
||||
readOnly={disabled}
|
||||
value={inputValue}
|
||||
className="form-control" />
|
||||
|
|
|
@ -52,14 +52,10 @@ const ListItem = (props) => {
|
|||
className += ' outdated';
|
||||
}
|
||||
|
||||
if (suspended) {
|
||||
if (suspended || stopped) {
|
||||
className += ' suspended';
|
||||
}
|
||||
|
||||
if (stopped) {
|
||||
className += ' stopped';
|
||||
}
|
||||
|
||||
if (focused) {
|
||||
className += ' focused';
|
||||
}
|
||||
|
@ -84,6 +80,7 @@ const ListItem = (props) => {
|
|||
<div onClick={starItem}><FontAwesomeIcon icon="star" /></div>
|
||||
</div>
|
||||
{props.suspended && <div className='suspended'>{i18n.suspended}</div>}
|
||||
{props.stopped && <div className='stopped'>{i18n.stopped}</div>}
|
||||
</Container>
|
||||
{props.children}
|
||||
</div>
|
||||
|
|
|
@ -23,13 +23,13 @@ const AddFirewall = props => {
|
|||
const [state, setState] = useState({
|
||||
loading: false,
|
||||
actions: [
|
||||
i18n['DROP'],
|
||||
i18n['ACCEPT']
|
||||
'DROP',
|
||||
'ACCEPT'
|
||||
],
|
||||
protocols: [
|
||||
i18n['TCP'],
|
||||
i18n['UDP'],
|
||||
i18n['ICMP']
|
||||
'TCP',
|
||||
'UDP',
|
||||
'ICMP'
|
||||
],
|
||||
okMessage: '',
|
||||
errorMessage: ''
|
||||
|
|
|
@ -70,7 +70,7 @@ const EditInternetProtocol = () => {
|
|||
|
||||
updatedIP['token'] = token;
|
||||
updatedIP['save'] = 'save';
|
||||
updatedIP['v_ip'] = state.data.database;
|
||||
updatedIP['v_ip'] = state.data.ip;
|
||||
|
||||
if (Object.keys(updatedIP).length !== 0 && updatedIP.constructor === Object) {
|
||||
setState({ ...state, loading: true });
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
import React, { Component } from 'react';
|
||||
import React from 'react';
|
||||
import ListItem from '../ControlPanel/ListItem/ListItem';
|
||||
import Container from '../ControlPanel/Container/Container';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import './InternetProtocol.scss';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { useSelector } from 'react-redux';
|
||||
import './InternetProtocol.scss';
|
||||
|
||||
const InternetProtocol = props => {
|
||||
const { data } = props;
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const token = localStorage.getItem("token");
|
||||
|
||||
const toggleFav = (starred) => {
|
||||
if (starred) {
|
||||
|
@ -38,7 +37,7 @@ const InternetProtocol = props => {
|
|||
checkItem={checkItem}>
|
||||
|
||||
<Container className="r-col w-85">
|
||||
<div className="name">{data.NAME}</div>
|
||||
<div className="name">{data.NAT ? <>{data.NAT} <FontAwesomeIcon icon="long-arrow-alt-right" /> {data.NAME}</> : data.NAME}</div>
|
||||
<br />
|
||||
<div className="stats">
|
||||
<Container className="c-1 w-35">
|
||||
|
@ -51,7 +50,7 @@ const InternetProtocol = props => {
|
|||
</Container>
|
||||
<Container className="c-3 w-35">
|
||||
<div>{i18n.Owner}: <span className="stat">{data.OWNER}</span></div>
|
||||
<div>{i18n.Users}: <span className="stat">{data.U_SYS_USERS.replace(',', ', ')}</span></div>
|
||||
<div>{i18n.Users}: <span className="stat">{data.U_SYS_USERS.replaceAll(',', ', ')}</span></div>
|
||||
</Container>
|
||||
</div>
|
||||
</Container>
|
||||
|
@ -74,4 +73,4 @@ const InternetProtocol = props => {
|
|||
);
|
||||
}
|
||||
|
||||
export default InternetProtocol;
|
||||
export default InternetProtocol;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
.internetProtocols {
|
||||
.ip-wrapper {
|
||||
.name svg {
|
||||
margin: 0 10px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -174,7 +174,7 @@ class Row extends Component {
|
|||
render() {
|
||||
const { data: { name, owner, permissions, size, date, time } } = this.props;
|
||||
return (
|
||||
<li className={this.className()} onClick={this.selectRow} >
|
||||
<li className={this.className()} onClick={this.selectRow} id={name}>
|
||||
<span className="marker"></span>
|
||||
{this.glyph()}
|
||||
<span className="fName"><span className="name" onClick={(e) => this.openItem(e)}>{this.props.cursor === 0 ? ".." : name}</span></span>
|
||||
|
|
|
@ -169,8 +169,20 @@ li.inactive {
|
|||
background: rgb(220, 220, 220);
|
||||
}
|
||||
|
||||
@media (max-width: 1320px){
|
||||
@media (max-width: 1400px){
|
||||
.fPermissions, .fOwner {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1100px){
|
||||
.fDate {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 970px){
|
||||
.fTime {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ export default function AddMailAccount(props) {
|
|||
|
||||
<TextInput
|
||||
title={i18n['Account']}
|
||||
onChange={e => setState({ ...state, username: e.target.value })}
|
||||
onChange={e => setState({ ...state, userName: e.target.value })}
|
||||
name="v_account"
|
||||
id="account" />
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ export default function MailInfoBlock({ webMail, hostName, domain, userName = ''
|
|||
|
||||
<div>
|
||||
<span>{i18n['Webmail URL']}:</span>
|
||||
<span><Link to={{ pathname: `${window.location.protocol}//${window.location.hostname}${state.webMail}` }}>{webMail}</Link></span>
|
||||
<span><Link to={{ pathname: `http://${window.location.hostname}${webMail}` }} target="_blank">{webMail}</Link></span>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name={i18n['Username']} value={`@${domain}`} />
|
||||
|
|
|
@ -9,7 +9,7 @@ import { Link } from "react-router-dom";
|
|||
import './Panel.scss';
|
||||
|
||||
const Panel = props => {
|
||||
const { i18n, userName } = useSelector(state => state.session);
|
||||
const { i18n, userName, panel } = useSelector(state => state.session);
|
||||
const { session } = useSelector(state => state.userSession);
|
||||
const { activeElement, focusedElement } = useSelector(state => state.mainNavigation);
|
||||
const dispatch = useDispatch();
|
||||
|
@ -113,8 +113,8 @@ const Panel = props => {
|
|||
)}
|
||||
</div>
|
||||
<div className="container profile-menu">
|
||||
<Notifications />
|
||||
<div>
|
||||
{panel[userName]['NOTIFICATIONS'] === 'yes' && <Notifications />}
|
||||
<div className="edit-user">
|
||||
<Link to={`/edit/user?user=${userName}`}>
|
||||
{session.look
|
||||
? <div className="long-username">
|
||||
|
@ -126,7 +126,7 @@ const Panel = props => {
|
|||
}
|
||||
</Link>
|
||||
</div>
|
||||
<div><button onClick={signOut}>{i18n['Log out']}</button></div>
|
||||
<div className="logout-button"><button onClick={signOut}>{i18n['Log out']}</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -144,7 +144,6 @@ $textColor: #555;
|
|||
width: auto;
|
||||
|
||||
div {
|
||||
width: 4rem;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
|
@ -169,7 +168,7 @@ $textColor: #555;
|
|||
}
|
||||
}
|
||||
|
||||
div + div a {
|
||||
.edit-user a {
|
||||
color: #a4abad;
|
||||
font-weight: 700;
|
||||
|
||||
|
@ -182,8 +181,8 @@ $textColor: #555;
|
|||
}
|
||||
}
|
||||
|
||||
div + div + div a,
|
||||
div + div + div button {
|
||||
.logout-button a,
|
||||
.logout-button button {
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
font-weight: 100;
|
||||
|
@ -220,7 +219,7 @@ $textColor: #555;
|
|||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
> div + div {
|
||||
> .edit-user {
|
||||
width: max-content;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ const style = ({ menuHeight, mobile }) => {
|
|||
|
||||
const Menu = props => {
|
||||
const { activeElement, focusedElement } = useSelector(state => state.mainNavigation);
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
const { i18n, panel, userName } = useSelector(state => state.session);
|
||||
const { session } = useSelector(state => state.userSession);
|
||||
const { user } = useSelector(state => state.menuCounters);
|
||||
const dispatch = useDispatch();
|
||||
|
@ -72,10 +72,16 @@ const Menu = props => {
|
|||
<h3>{i18n.USER}</h3>
|
||||
<div className="stats">
|
||||
{
|
||||
session.look
|
||||
session.look && panel[session.look]
|
||||
? (<>
|
||||
<div><span>{i18n.Disk}:</span> <span>{sizeFormatter(user.U_DISK)}</span></div>
|
||||
<div><span>{i18n.Bandwidth}:</span> <span>{sizeFormatter(user.U_BANDWIDTH)}</span></div>
|
||||
<div>
|
||||
<span>{i18n.Disk}:</span>
|
||||
<span><span className="value">{user.U_DISK} <span className="unit">{panel[session.look]['U_DISK_MEASURE']}</span></span></span>
|
||||
</div>
|
||||
<div>
|
||||
<span>{i18n.Bandwidth}:</span>
|
||||
<span><span className="value">{user.U_BANDWIDTH} <span className="unit">{panel[session.look]['U_BANDWIDTH_MEASURE']}</span></span></span>
|
||||
</div>
|
||||
</>)
|
||||
: (<>
|
||||
<div><span>{i18n.users}:</span> <span>{user.U_USERS}</span></div>
|
||||
|
@ -85,62 +91,79 @@ const Menu = props => {
|
|||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className={statClassName("/list/web/")}>
|
||||
<Link to="/list/web/" onClick={event => handleState("/list/web/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.WEB}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.domains}:</span> <span>{user.U_WEB_DOMAINS}</span></div>
|
||||
<div><span>{i18n.aliases}:</span> <span>{user.U_WEB_ALIASES}</span></div>
|
||||
<div><span>{i18n.spnd}:</span> <span>{user.SUSPENDED_WEB}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className={statClassName("/list/dns/")}>
|
||||
<Link to="/list/dns/" onClick={event => handleState("/list/dns/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.DNS}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.domains}:</span> <span>{user.U_DNS_DOMAINS}</span></div>
|
||||
<div><span>{i18n.records}:</span> <span>{user.U_DNS_RECORDS}</span></div>
|
||||
<div><span>{i18n.spnd}:</span> <span>{user.SUSPENDED_DNS}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className={statClassName("/list/mail/")}>
|
||||
<Link to="/list/mail/" onClick={event => handleState("/list/mail/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.MAIL}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.domains}:</span> <span>{user.U_MAIL_DOMAINS}</span></div>
|
||||
<div><span>{i18n.accounts}:</span> <span>{user.U_MAIL_ACCOUNTS}</span></div>
|
||||
<div><span>{i18n.spnd}:</span> <span>{user.SUSPENDED_MAIL}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className={statClassName("/list/db/")}>
|
||||
<Link to="/list/db/" onClick={event => handleState("/list/db/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.DB}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.databases}:</span> <span>{user.U_DATABASES}</span></div>
|
||||
<div><span>{i18n.spnd}:</span> <span>{user.SUSPENDED_DB}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className={statClassName("/list/cron/")}>
|
||||
<Link to="/list/cron/" onClick={event => handleState("/list/cron/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.CRON}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.jobs}:</span> <span>{user.U_CRON_JOBS}</span></div>
|
||||
<div><span>{i18n.spnd}:</span> <span>{user.SUSPENDED_CRON}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
<div className={statClassName("/list/backup/") + ' last'}>
|
||||
<Link to="/list/backup/" onClick={event => handleState("/list/backup/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.BACKUP}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.backups}:</span> <span>{user.U_BACKUPS}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
{
|
||||
panel[userName]['WEB_DOMAINS'] !== '0' && (<div className={statClassName("/list/web/")}>
|
||||
<Link to="/list/web/" onClick={event => handleState("/list/web/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.WEB}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.domains}:</span> <span>{user.U_WEB_DOMAINS}</span></div>
|
||||
<div><span>{i18n.aliases}:</span> <span>{user.U_WEB_ALIASES}</span></div>
|
||||
<div><span>{i18n.spnd}:</span> <span>{user.SUSPENDED_WEB}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>)
|
||||
}
|
||||
|
||||
{
|
||||
panel[userName]['DNS_DOMAINS'] !== '0' && (<div className={statClassName("/list/dns/")}>
|
||||
<Link to="/list/dns/" onClick={event => handleState("/list/dns/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.DNS}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.domains}:</span> <span>{user.U_DNS_DOMAINS}</span></div>
|
||||
<div><span>{i18n.records}:</span> <span>{user.U_DNS_RECORDS}</span></div>
|
||||
<div><span>{i18n.spnd}:</span> <span>{user.SUSPENDED_DNS}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>)
|
||||
}
|
||||
|
||||
{
|
||||
panel[userName]['MAIL_DOMAINS'] !== '0' && (<div className={statClassName("/list/mail/")}>
|
||||
<Link to="/list/mail/" onClick={event => handleState("/list/mail/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.MAIL}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.domains}:</span> <span>{user.U_MAIL_DOMAINS}</span></div>
|
||||
<div><span>{i18n.accounts}:</span> <span>{user.U_MAIL_ACCOUNTS}</span></div>
|
||||
<div><span>{i18n.spnd}:</span> <span>{user.SUSPENDED_MAIL}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>)
|
||||
}
|
||||
|
||||
{
|
||||
panel[userName]['DATABASES'] !== '0' && (<div className={statClassName("/list/db/")}>
|
||||
<Link to="/list/db/" onClick={event => handleState("/list/db/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.DB}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.databases}:</span> <span>{user.U_DATABASES}</span></div>
|
||||
<div><span>{i18n.spnd}:</span> <span>{user.SUSPENDED_DB}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>)
|
||||
}
|
||||
|
||||
{
|
||||
panel[userName]['CRON_JOBS'] !== '0' && (<div className={statClassName("/list/cron/")}>
|
||||
<Link to="/list/cron/" onClick={event => handleState("/list/cron/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.CRON}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.jobs}:</span> <span>{user.U_CRON_JOBS}</span></div>
|
||||
<div><span>{i18n.spnd}:</span> <span>{user.SUSPENDED_CRON}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>)
|
||||
}
|
||||
|
||||
{
|
||||
panel[userName]['BACKUPS'] !== '0' && (<div className={statClassName("/list/backup/") + ' last'}>
|
||||
<Link to="/list/backup/" onClick={event => handleState("/list/backup/", event)} onKeyPress={event => event.preventDefault()}>
|
||||
<h3>{i18n.BACKUP}</h3>
|
||||
<div className="stats">
|
||||
<div><span>{i18n.backups}:</span> <span>{user.U_BACKUPS}</span></div>
|
||||
</div>
|
||||
</Link>
|
||||
</div>)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -15,7 +15,7 @@ const Archive = (props) => {
|
|||
<input type="text" autoFocus defaultValue={`${props.path}/${props.fName}.tar.gz`} onBlur={props.onChange} ref={props.reference}></input>
|
||||
</div>
|
||||
<div className="modal-footer">
|
||||
<button type="button" className="btn btn-danger mr-auto" onClick={props.close}>{i18n.Compress}</button>
|
||||
<button type="button" className="btn btn-danger mr-auto" onClick={props.close}>{i18n.Cancel}</button>
|
||||
<button type="button" className="btn btn-primary" onClick={props.save}>{i18n.Compress}</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
import React from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import { useHistory } from 'react-router';
|
||||
|
||||
import Dropdown from './Dropdown/Dropdown';
|
||||
import './Path.scss';
|
||||
|
||||
const Path = ({ path, isActive, className, openDirectory, changeSorting, sorting, order }) => {
|
||||
const { user } = useSelector(state => state.menuCounters);
|
||||
const history = useHistory();
|
||||
|
||||
useEffect(() => {
|
||||
if (!user) return history.push('/login');
|
||||
}, [user]);
|
||||
|
||||
const clickablePath = () => {
|
||||
let splitPath = path.split('/');
|
||||
|
|
|
@ -3,10 +3,10 @@ import './ProgressBar.scss';
|
|||
|
||||
const ProgressBar = (props) => {
|
||||
return (
|
||||
<div class="progress">
|
||||
<div class="progress upload" style={{ overflow: props.progress !== "0" ? 'visible' : 'hidden' }}>
|
||||
<div class="progress-bar" role="progressbar" style={{ width: `${props.progress}%` }} aria-valuenow={props.progress} aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ProgressBar;
|
||||
export default ProgressBar;
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
.spinner-wrapper .progress {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
z-index: 5;
|
||||
.progress.upload {
|
||||
position: fixed;
|
||||
left: 0px;
|
||||
top: 0px;
|
||||
z-index: 9999;
|
||||
height: 5px;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
height: 6px;
|
||||
display: inline-table;
|
||||
background: transparent;
|
||||
|
||||
.progress-bar {
|
||||
height: 10px;
|
||||
height: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,51 +31,47 @@ const EditBackupOption = ({ data, visible }) => {
|
|||
name="v_backup_dir"
|
||||
id="v-backup-dir" />
|
||||
|
||||
<button type="button" onClick={() => setRemoteBackup(!remoteBackup)}>
|
||||
{i18n['Remote backup']}
|
||||
{remoteBackup ? <FontAwesomeIcon icon="caret-up" /> : <FontAwesomeIcon icon="caret-down" />}
|
||||
</button>
|
||||
|
||||
{
|
||||
data.backup_remote_adv && (
|
||||
<>
|
||||
<button type="button" onClick={() => setRemoteBackup(!remoteBackup)}>
|
||||
{i18n['Remote backup']}
|
||||
{remoteBackup ? <FontAwesomeIcon icon="caret-up" /> : <FontAwesomeIcon icon="caret-down" />}
|
||||
</button>
|
||||
remoteBackup && (
|
||||
<div style={{ transform: 'translateX(3rem)' }}>
|
||||
<br />
|
||||
|
||||
{
|
||||
remoteBackup && (
|
||||
<>
|
||||
<SelectInput
|
||||
selected={data.backup_type}
|
||||
options={data.protocols}
|
||||
title={i18n['Protocol']}
|
||||
name="v_backup_type"
|
||||
id="backup_type" />
|
||||
<SelectInput
|
||||
selected={data.backup_type}
|
||||
options={data.protocols}
|
||||
title={i18n['Protocol']}
|
||||
name="v_backup_type"
|
||||
id="backup_type" />
|
||||
|
||||
<TextInput
|
||||
title={i18n['Host']}
|
||||
value={data.backup_host}
|
||||
name="v_backup_host"
|
||||
id="backup_host" />
|
||||
<TextInput
|
||||
title={i18n['Host']}
|
||||
value={data.backup_host}
|
||||
name="v_backup_host"
|
||||
id="backup_host" />
|
||||
|
||||
<TextInput
|
||||
title={i18n['Username']}
|
||||
value={data.backup_username}
|
||||
name="v_backup_username"
|
||||
id="backup_username" />
|
||||
<TextInput
|
||||
title={i18n['Username']}
|
||||
value={data.backup_username}
|
||||
name="v_backup_username"
|
||||
id="backup_username" />
|
||||
|
||||
<TextInput
|
||||
title={i18n['Password']}
|
||||
value={data.backup_password}
|
||||
name="v_backup_password"
|
||||
id="backup_password" />
|
||||
<TextInput
|
||||
title={i18n['Password']}
|
||||
value={data.backup_password}
|
||||
name="v_backup_password"
|
||||
id="backup_password" />
|
||||
|
||||
<TextInput
|
||||
title={i18n['Directory']}
|
||||
value={data.backup_bpath}
|
||||
name="v_backup_bpath"
|
||||
id="backup_bpath" />
|
||||
</>
|
||||
)
|
||||
}
|
||||
</>
|
||||
<TextInput
|
||||
title={i18n['Directory']}
|
||||
value={data.backup_bpath}
|
||||
name="v_backup_bpath"
|
||||
id="backup_bpath" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
|
|
|
@ -163,6 +163,12 @@ const EditServer = props => {
|
|||
name="v_language"
|
||||
id="language" />
|
||||
|
||||
{/* <TextInput
|
||||
value={state.data.port}
|
||||
title={i18n['Default Port'] ?? 'Default Port'}
|
||||
name="port"
|
||||
id="port" /> */}
|
||||
|
||||
<div className="modules">
|
||||
<button type="button" onClick={() => toggleOption('webOption')}>
|
||||
{i18n['WEB']}
|
||||
|
|
|
@ -156,14 +156,14 @@ const EditVestaPluginsOption = ({ data, visible }) => {
|
|||
|
||||
<SelectInput
|
||||
title={i18n['Reseller Role']}
|
||||
options={[i18n['yes']]}
|
||||
options={[i18n['no']]}
|
||||
name="v_reseller"
|
||||
id="reseller"
|
||||
disabled />
|
||||
|
||||
<SelectInput
|
||||
title={i18n['Backup Migration Manager']}
|
||||
options={[i18n['yes']]}
|
||||
options={[i18n['no']]}
|
||||
name="v_backup_manager"
|
||||
id="backup_manager"
|
||||
disabled />
|
||||
|
|
|
@ -19,6 +19,7 @@ const Server = props => {
|
|||
id={data.NAME}
|
||||
focused={data.FOCUSED}
|
||||
checked={data.isChecked}
|
||||
stopped={data.STATE === 'stopped'}
|
||||
checkItem={checkItem}>
|
||||
|
||||
<Container className="r-col w-85">
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
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 { useSelector } from 'react-redux';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import './User.scss';
|
||||
|
||||
const User = ({ data, toggleFav, handleModal, checkItem }) => {
|
||||
const User = ({ data, toggleFav, handleModal, checkItem, logOut, logInAs }) => {
|
||||
const { i18n, userName } = useSelector(state => state.session);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const printNameServers = servers => {
|
||||
let serversArray = servers.split(',');
|
||||
|
@ -20,20 +18,12 @@ const User = ({ data, toggleFav, handleModal, checkItem }) => {
|
|||
);
|
||||
}
|
||||
|
||||
const signInAs = username => {
|
||||
dispatch(loginAs(username));
|
||||
}
|
||||
|
||||
const signOut = () => {
|
||||
dispatch(logout());
|
||||
}
|
||||
|
||||
const printLoginActionButton = user => {
|
||||
let currentUser = userName;
|
||||
if (currentUser === user) {
|
||||
return (
|
||||
<div>
|
||||
<button onClick={signOut}>{i18n['Log out']}
|
||||
<button onClick={logOut}>{i18n['Log out']}
|
||||
{data.FOCUSED ? <span className="shortcut-button">L</span> : <FontAwesomeIcon icon="user-lock" />}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -41,7 +31,7 @@ const User = ({ data, toggleFav, handleModal, checkItem }) => {
|
|||
} else {
|
||||
return (
|
||||
<div>
|
||||
<button onClick={() => signInAs(user)}>{i18n['login as']} {user}
|
||||
<button onClick={() => logInAs(user)}>{i18n['login as']} {user}
|
||||
{data.FOCUSED ? <span className="shortcut-button">L</span> : <FontAwesomeIcon icon="user-lock" />}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -86,16 +76,16 @@ const User = ({ data, toggleFav, handleModal, checkItem }) => {
|
|||
<div>{data.FNAME} {data.LNAME}</div>
|
||||
<div className="stats">
|
||||
<Container className="c-1">
|
||||
<div className="bandwidth">{i18n.Bandwidth} <span><span className="stat">{data.U_BANDWIDTH}</span> {i18n.mb}</span></div>
|
||||
<div className="disk">{i18n.Disk}: <span><span className="stat">{data.U_DISK}</span> {i18n.mb}</span></div>
|
||||
<div className="bandwidth">{i18n.Bandwidth} <span><span className="stat">{data.U_BANDWIDTH}</span> {data.U_BANDWIDTH_MEASURE}</span></div>
|
||||
<div className="disk">{i18n.Disk}: <span><span className="stat">{data.U_DISK}</span> {data.U_DISK_MEASURE}</span></div>
|
||||
<div className="sub-disk-stats">
|
||||
<div>
|
||||
<div><span>{i18n.Web}:</span> <span><b>{data.U_DISK_WEB}</b> {i18n.mb}</span></div>
|
||||
<div><span>{i18n.Mail}:</span> <span><b>{data.U_DISK_MAIL}</b> {i18n.mb}</span></div>
|
||||
<div><span>{i18n.Web}:</span> <span><b>{data.U_DISK_WEB}</b> {data.U_DISK_WEB_MEASURE}</span></div>
|
||||
<div><span>{i18n.Mail}:</span> <span><b>{data.U_DISK_MAIL}</b> {data.U_DISK_MAIL_MEASURE}</span></div>
|
||||
</div>
|
||||
<div>
|
||||
<div><span>{i18n.Databases}:</span> <span><b>{data.U_DATABASES}</b> {i18n.mb}</span></div>
|
||||
<div><span>{i18n['User Directories']}:</span> <span><b>{data.U_DISK_DIRS}</b> {i18n.mb}</span></div>
|
||||
<div><span>{i18n.Databases}:</span> <span><b>{data.U_DATABASES}</b> {data.U_DATABASES_MEASURE}</span></div>
|
||||
<div><span>{i18n['User Directories']}:</span> <span><b>{data.U_DISK_DIRS}</b> {data.U_DISK_DIRS_MEASURE}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</Container>
|
||||
|
|
|
@ -40,6 +40,7 @@ const AddWebDomain = props => {
|
|||
webStats: [],
|
||||
prefixI18N: '',
|
||||
prePath: '',
|
||||
aliases: '',
|
||||
proxy_ext: '',
|
||||
internetProtocols: []
|
||||
});
|
||||
|
@ -99,7 +100,7 @@ const AddWebDomain = props => {
|
|||
}
|
||||
|
||||
const onBlurChangeAliases = value => {
|
||||
setState({ ...state, domain: value });
|
||||
setState({ ...state, aliases: `www.${value}`});
|
||||
}
|
||||
|
||||
const checkboxHandler = (input, checked) => {
|
||||
|
|
|
@ -9,7 +9,7 @@ const AdditionalFtpForEditing = ({ domain, data = {}, onDeleteAdditionalFtp, pre
|
|||
const { i18n, userName } = useSelector(state => state.session);
|
||||
const [state, setState] = useState({
|
||||
username: data.v_ftp_user || '',
|
||||
path: ''
|
||||
path: data.v_ftp_path || '',
|
||||
});
|
||||
|
||||
const renderForm = () => {
|
||||
|
@ -32,8 +32,9 @@ const AdditionalFtpForEditing = ({ domain, data = {}, onDeleteAdditionalFtp, pre
|
|||
return (
|
||||
<div className="additional-ftp">
|
||||
<div className="title">
|
||||
<input type="hidden" name={`v_ftp_user[${data.id}][v_ftp_user]`} value={data.v_ftp_user} />
|
||||
<input type="hidden" name={`v_ftp_user[${data.id}][delete]`} value="0" />
|
||||
<input type="hidden" name={`v_ftp_user[${data.id}][is_new]`} value="1" />
|
||||
<input type="hidden" name={`v_ftp_user[${data.id}][is_new]`} value={data.is_new} />
|
||||
|
||||
<span className="data.indexed-name">{i18n.FTP} #{data.id + 1}</span>
|
||||
<span>
|
||||
|
@ -67,17 +68,17 @@ const AdditionalFtpForEditing = ({ domain, data = {}, onDeleteAdditionalFtp, pre
|
|||
|
||||
<div className="form-group">
|
||||
<input type="hidden" name="v_ftp_pre_path" value={prePath} />
|
||||
<input type="hidden" name={`v_ftp_user[${data.id}][v_ftp_path_prev]`} value={data.v_ftp_path !== '/' ? '/' : ''} />
|
||||
<input type="hidden" name={`v_ftp_user[${data.id}][v_ftp_path_prev]`} value={data.v_ftp_path} />
|
||||
|
||||
<label htmlFor={`path${data.id}`}>{i18n.Path}</label>
|
||||
<input
|
||||
type="text"
|
||||
value={state.path}
|
||||
onChange={event => setState({ ...state, path: event.target.value })}
|
||||
onChange={event => setState({ ...state, path: event.target.value.indexOf('/') !== 0 ? `/${event.target.value}` : event.target.value })}
|
||||
className="form-control"
|
||||
id={`path${data.id}`}
|
||||
name={`v_ftp_user[${data.id}][v_ftp_path]`} />
|
||||
<span className="path-note">{prePath}</span>
|
||||
<span className="path-note">{prePath}{state.path}</span>
|
||||
</div>
|
||||
|
||||
{
|
||||
|
|
|
@ -72,7 +72,7 @@ export default function WebDomain(props) {
|
|||
<Container className="r-col w-85">
|
||||
<div className="name">
|
||||
<div>{data.NAME}</div>
|
||||
<div><span className="dns-name-span">{data.ALIAS}</span></div>
|
||||
<div><span className="dns-name-span">{data.ALIAS.replaceAll(',', ', ')}</span></div>
|
||||
</div>
|
||||
<div>{data.IP}</div>
|
||||
<div className="stats">
|
||||
|
|
|
@ -17,6 +17,7 @@ import Spinner from '../../components/Spinner/Spinner';
|
|||
import './Databases.scss';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
const Databases = props => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
|
@ -35,6 +36,8 @@ const Databases = props => {
|
|||
toggledAll: false,
|
||||
dbAdmin: '',
|
||||
dbAdminLink: '',
|
||||
db_myadmin_link: '',
|
||||
db_pgadmin_link: '',
|
||||
sorting: i18n.Date,
|
||||
order: "descending",
|
||||
selection: [],
|
||||
|
@ -174,6 +177,8 @@ const Databases = props => {
|
|||
databases: reformatData(result.data.data),
|
||||
dbAdmin: result.data.db_admin,
|
||||
dbAdminLink: result.data.db_admin_link,
|
||||
db_myadmin_link: result.data.db_myadmin_link,
|
||||
db_pgadmin_link: result.data.db_pgadmin_link,
|
||||
dbFav: result.data.dbFav,
|
||||
selection: [],
|
||||
toggledAll: false,
|
||||
|
@ -387,7 +392,8 @@ const Databases = props => {
|
|||
<LeftButton name="Add Database" href="/add/db" showLeftMenu={true} />
|
||||
<div className="r-menu">
|
||||
<div className="input-group input-group-sm">
|
||||
<a href={state.dbAdminLink} className="button-extra" type="submit" target="_blank" rel="noopener noreferrer">{state.dbAdmin}</a>
|
||||
{state.db_myadmin_link && <Link to={{ pathname: state.db_myadmin_link }} className="button-extra" type="submit" target="_blank">phpMyAdmin</Link>}
|
||||
{state.db_pgadmin_link && <Link to={{ pathname: state.db_pgadmin_link }} className="button-extra" type="submit" target="_blank">phpPgAdmin</Link>}
|
||||
<Checkbox toggleAll={toggleAll} toggled={state.toggledAll} />
|
||||
<Select list='dbList' bulkAction={bulk} />
|
||||
<DropdownFilter changeSorting={changeSorting} sorting={state.sorting} order={state.order} list="dbList" />
|
||||
|
|
|
@ -20,15 +20,15 @@ class FileManager extends Component {
|
|||
super(props);
|
||||
this.state = {
|
||||
leftList: {
|
||||
path: this.props.menuCounters.user.HOME,
|
||||
path: '',
|
||||
files: { listing: [] },
|
||||
},
|
||||
rightList: {
|
||||
path: this.props.menuCounters.user.HOME,
|
||||
path: '',
|
||||
files: { listing: [] },
|
||||
},
|
||||
currentPath: this.props.menuCounters.user.HOME,
|
||||
currentUser: this.props.menuCounters.user.HOME,
|
||||
currentPath: '',
|
||||
currentUser: '',
|
||||
activeWindow: "left",
|
||||
modalWindow: null,
|
||||
modalVisible: false,
|
||||
|
@ -44,17 +44,20 @@ class FileManager extends Component {
|
|||
}
|
||||
|
||||
UNSAFE_componentWillMount = () => {
|
||||
if (!this.props.session.userName) return this.props.history.push('/login');
|
||||
|
||||
FM.cacheData(this.state.currentUser, this.props.history, this.props.menuCounters.user.HOME);
|
||||
let currentPath = FM.activeWindowPath();
|
||||
this.setState({ currentPath });
|
||||
this.setState({
|
||||
currentPath,
|
||||
currentUser: this.props.menuCounters.user.HOME,
|
||||
leftList: { ...this.state.leftList, path: this.props.menuCounters.user.HOME },
|
||||
rightList: { ...this.state.rightList, path: this.props.menuCounters.user.HOME }
|
||||
});
|
||||
this.changeDirectoryOnLoading();
|
||||
}
|
||||
|
||||
componentDidMount = () => {
|
||||
if (!localStorage.getItem("token") || !this.props.session.userName) {
|
||||
this.props.history.push('/login/');
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", this.switchActiveList);
|
||||
window.addEventListener("keydown", this.toggleActiveListOnTab);
|
||||
document.addEventListener("keydown", this.hotkeysListener);
|
||||
|
@ -90,22 +93,17 @@ class FileManager extends Component {
|
|||
}
|
||||
|
||||
changeDirectory = () => {
|
||||
const { activeWindow, currentPath } = this.state;
|
||||
FM.changeDirectory(server, currentPath)
|
||||
const { leftList, rightList } = this.state;
|
||||
Promise.all([FM.changeDirectory(server, leftList.path), FM.changeDirectory(server, rightList.path)])
|
||||
.then(result => {
|
||||
let listing = result.data.listing;
|
||||
const [leftListResponse, rightListResponse] = result;
|
||||
let leftListing = leftListResponse.data.listing;
|
||||
let rightListing = rightListResponse.data.listing;
|
||||
|
||||
if (this.state.leftList.path === this.state.rightList.path) {
|
||||
this.setState({ leftList: { files: { listing }, path: currentPath }, rightList: { files: { listing }, path: currentPath }, loading: false });
|
||||
this.leftList.resetData();
|
||||
this.rightList.resetData();
|
||||
} else if (activeWindow === "left") {
|
||||
this.setState({ leftList: { files: { listing }, path: currentPath }, loading: false });
|
||||
this.leftList.resetData();
|
||||
} else {
|
||||
this.setState({ rightList: { files: { listing }, path: currentPath }, loading: false });
|
||||
this.rightList.resetData();
|
||||
}
|
||||
this.setState({ leftList: { ...leftList, files: { listing: leftListing } }, rightList: { ...rightList, files: { listing: rightListing } }, loading: false });
|
||||
|
||||
this.leftList.resetData();
|
||||
this.rightList.resetData();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -235,6 +233,7 @@ class FileManager extends Component {
|
|||
if (itemsSelected.length > 0) {
|
||||
await this.setStateAsync({ loading: true });
|
||||
await FM.deleteItems(server, FM.encodePath(currentPath), itemsSelected);
|
||||
await this.setStateAsync({ itemsSelected: [] });
|
||||
this.changeDirectory();
|
||||
} else {
|
||||
this.validateAction(`${server}item=${FM.encodePath(currentPath)}%2F${itemName}&dir=${FM.encodePath(currentPath)}&action=delete_files`);
|
||||
|
@ -421,35 +420,12 @@ class FileManager extends Component {
|
|||
|
||||
render() {
|
||||
const { activeWindow, modalWindow, modalVisible, itemsSelected, itemName, loading, uploadPercent, itemType } = this.state;
|
||||
const DirectoryLists = ['left', 'right'].map((side) =>
|
||||
<DirectoryList
|
||||
changePathAfterToggle={this.changePathAfterToggle}
|
||||
openCertainDirectory={this.openCertainDirectory}
|
||||
isActive={activeWindow === side}
|
||||
openDirectory={this.openDirectory}
|
||||
passSelection={this.passSelection}
|
||||
data={this.state[`${side}List`].files}
|
||||
onClick={this.toggleActiveList}
|
||||
changePath={this.changePath}
|
||||
modalVisible={modalVisible}
|
||||
addToPath={this.addToPath}
|
||||
cursor={this.state.cursor}
|
||||
passData={this.passData}
|
||||
rootDir={this.props.menuCounters.user.HOME}
|
||||
ref={el => this[`${side}List`] = el}
|
||||
download={this.download}
|
||||
moveBack={this.moveBack}
|
||||
path={this.state[`${side}List`].path}
|
||||
history={this.props.history}
|
||||
loading={loading}
|
||||
list={side} />
|
||||
)
|
||||
return (
|
||||
<div className="window">
|
||||
<Helmet>
|
||||
<title>{this.props.session.i18n['File Manager']}</title>
|
||||
</Helmet>
|
||||
{uploadPercent !== "0" ? <ProgressBar progress={uploadPercent} /> : null}
|
||||
{uploadPercent !== "0" && <ProgressBar progress={uploadPercent} />}
|
||||
<ToastContainer />
|
||||
<Menu
|
||||
onDelete={this.onDeleteFileHandler}
|
||||
|
@ -462,7 +438,29 @@ class FileManager extends Component {
|
|||
cursor={this.state.cursor}
|
||||
name={itemName} />
|
||||
<div className="lists-container">
|
||||
{DirectoryLists}
|
||||
{this.props.session.userName && ['left', 'right'].map((side) =>
|
||||
<DirectoryList
|
||||
changePathAfterToggle={this.changePathAfterToggle}
|
||||
openCertainDirectory={this.openCertainDirectory}
|
||||
isActive={activeWindow === side}
|
||||
openDirectory={this.openDirectory}
|
||||
passSelection={this.passSelection}
|
||||
data={this.state[`${side}List`].files}
|
||||
onClick={this.toggleActiveList}
|
||||
changePath={this.changePath}
|
||||
modalVisible={modalVisible}
|
||||
addToPath={this.addToPath}
|
||||
cursor={this.state.cursor}
|
||||
passData={this.passData}
|
||||
rootDir={this.props.menuCounters.user.HOME}
|
||||
ref={el => this[`${side}List`] = el}
|
||||
download={this.download}
|
||||
moveBack={this.moveBack}
|
||||
path={this.state[`${side}List`].path}
|
||||
history={this.props.history}
|
||||
loading={loading}
|
||||
list={side} />
|
||||
)}
|
||||
<div className="fixed-buttons fm">
|
||||
<div className="hotkey-button">
|
||||
<button onClick={() => this.hotkeysList.classList.toggle('hide')}>
|
||||
|
|
|
@ -16,7 +16,6 @@ import { Helmet } from 'react-helmet';
|
|||
import { useHistory } from 'react-router';
|
||||
|
||||
import './styles.scss';
|
||||
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
|
||||
|
||||
const BanLists = props => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
|
@ -237,7 +236,7 @@ const BanLists = props => {
|
|||
.then(result => {
|
||||
if (result.status === 200) {
|
||||
toggleAll(false);
|
||||
fetchData();
|
||||
fetchData().then(() => setLoading(false));
|
||||
}
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
|
@ -261,7 +260,7 @@ const BanLists = props => {
|
|||
setLoading(false);
|
||||
return displayModal(res.data.error, '');
|
||||
}
|
||||
fetchData();
|
||||
fetchData().then(() => setLoading(false));
|
||||
})
|
||||
.catch(err => { setLoading(false); console.error(err); });
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { addControlPanelContentFocusedElement, removeControlPanelContentFocusedElement } from '../../actions/ControlPanelContent/controlPanelContentActions';
|
||||
import { addActiveElement, removeFocusedElement } from '../../actions/MainNavigation/mainNavigationActions';
|
||||
import { bulkAction, getFirewallList, handleAction } from '../../ControlPanelService/Firewalls';
|
||||
import { bulkFirewallAction, getFirewallList, handleAction } from '../../ControlPanelService/Firewalls';
|
||||
import DropdownFilter from '../../components/MainNav/Toolbar/DropdownFilter/DropdownFilter';
|
||||
import * as MainNavigation from '../../actions/MainNavigation/mainNavigationActions';
|
||||
import SearchInput from '../../components/MainNav/Toolbar/SearchInput/SearchInput';
|
||||
|
@ -321,7 +321,7 @@ const Firewalls = props => {
|
|||
|
||||
if (selection.length && action) {
|
||||
setLoading(true);
|
||||
bulkAction(action, selection)
|
||||
bulkFirewallAction(action, selection)
|
||||
.then(result => {
|
||||
if (result.status === 200) {
|
||||
toggleAll(false);
|
||||
|
|
|
@ -28,8 +28,8 @@ export default function MailWrapper(props) {
|
|||
</Helmet>
|
||||
{
|
||||
mailDomain
|
||||
? <MailAccounts {...props} domain={mailDomain} changeSearchTerm={props.handleSearchTerm} />
|
||||
: <Mails {...props} changeSearchTerm={props.handleSearchTerm} />
|
||||
? <MailAccounts {...props} domain={mailDomain} changeSearchTerm={props.changeSearchTerm} />
|
||||
: <Mails {...props} changeSearchTerm={props.changeSearchTerm} />
|
||||
}
|
||||
</>
|
||||
);
|
||||
|
|
|
@ -396,7 +396,7 @@ const Mails = props => {
|
|||
<div className="r-menu">
|
||||
<div className="input-group input-group-sm">
|
||||
<Link
|
||||
to={{ pathname: `${window.location.protocol}//${window.location.hostname}${state.webmail}` }}
|
||||
to={{ pathname: `http://${window.location.hostname}${state.webmail}` }}
|
||||
target="_blank"
|
||||
className="button-extra"
|
||||
type="submit">
|
||||
|
|
|
@ -15,7 +15,6 @@ import Server from '../../components/Server/Server';
|
|||
import { Link } from 'react-router-dom';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import './Servers.scss';
|
||||
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
|
||||
|
||||
const Servers = props => {
|
||||
const { i18n } = useSelector(state => state.session);
|
||||
|
@ -216,7 +215,7 @@ const Servers = props => {
|
|||
displayModal(res.data.error);
|
||||
}
|
||||
|
||||
setLoading(false);
|
||||
fetchData().then(() => setLoading(false));
|
||||
})
|
||||
.catch(err => {
|
||||
setLoading(false);
|
||||
|
@ -260,7 +259,7 @@ const Servers = props => {
|
|||
}
|
||||
|
||||
toggleAll(false);
|
||||
fetchData().then(() => refreshMenuCounters());
|
||||
fetchData().then(() => setLoading(false));
|
||||
})
|
||||
.catch(err => console.error(err));
|
||||
}
|
||||
|
@ -302,15 +301,11 @@ const Servers = props => {
|
|||
return displayModal(res.data.error, '');
|
||||
}
|
||||
|
||||
fetchData().then(() => refreshMenuCounters());
|
||||
fetchData().then(() => setLoading(false));
|
||||
})
|
||||
.catch(err => { setLoading(false); console.error(err); });
|
||||
}
|
||||
|
||||
const refreshMenuCounters = () => {
|
||||
dispatch(refreshCounters()).then(() => setLoading(false));
|
||||
}
|
||||
|
||||
const modalCancelHandler = () => {
|
||||
setModal({ ...modal, visible: false, text: '' });
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import { Helmet } from 'react-helmet';
|
|||
import './Users.scss';
|
||||
import { refreshCounters } from 'src/actions/MenuCounters/menuCounterActions';
|
||||
import { useHistory } from 'react-router';
|
||||
import { loginAs, logout } from 'src/actions/Session/sessionActions';
|
||||
|
||||
const Users = props => {
|
||||
const { userName, i18n } = useSelector(state => state.session);
|
||||
|
@ -248,10 +249,20 @@ const Users = props => {
|
|||
let sortedResult = sortArray(users);
|
||||
|
||||
return sortedResult.map((item, index) => {
|
||||
return <User data={item} key={index} toggleFav={toggleFav} checkItem={checkItem} handleModal={displayModal} />;
|
||||
return <User data={item} key={index} toggleFav={toggleFav} checkItem={checkItem} handleModal={displayModal} logOut={logOutHandler} logInAs={logInAsHandler} />;
|
||||
});
|
||||
}
|
||||
|
||||
const logOutHandler = () => {
|
||||
setLoading(true);
|
||||
dispatch(logout()).then(() => setLoading(false));
|
||||
}
|
||||
|
||||
const logInAsHandler = username => {
|
||||
setLoading(true);
|
||||
dispatch(loginAs(username)).then(() => setLoading(false));
|
||||
}
|
||||
|
||||
const checkItem = name => {
|
||||
const { selection, users } = state;
|
||||
let duplicate = [...selection];
|
||||
|
|
|
@ -10,6 +10,7 @@ import './WebLogs.scss';
|
|||
import { getWebLogs } from 'src/ControlPanelService/WebLogs';
|
||||
import Spinner from 'src/components/Spinner/Spinner';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import HtmlParser from 'react-html-parser';
|
||||
|
||||
export default function WebLogs() {
|
||||
const { i18n, userName } = useSelector(state => state.session);
|
||||
|
@ -19,6 +20,7 @@ export default function WebLogs() {
|
|||
const [domain, setDomain] = useState();
|
||||
const [state, setState] = useState({
|
||||
data: "",
|
||||
prefix: "",
|
||||
loading: false
|
||||
});
|
||||
|
||||
|
@ -40,7 +42,7 @@ export default function WebLogs() {
|
|||
let uri = `/list/web-log/?domain=${domain}&type=${type}`;
|
||||
fetchData(uri);
|
||||
|
||||
dispatch(addActiveElement(`/list/web-log/${type}`));
|
||||
dispatch(addActiveElement(`/list/web-log/?domain=${domain}&type=${type}`));
|
||||
}, [mainNavigation.activeElement]);
|
||||
|
||||
const fetchData = uri => {
|
||||
|
@ -52,7 +54,7 @@ export default function WebLogs() {
|
|||
getWebLogs(uri)
|
||||
.then(result => {
|
||||
if (result.data) {
|
||||
setState({ ...state, data: result.data.data, loading: false });
|
||||
setState({ ...state, data: result.data.data, prefix: result.data.prefix, loading: false });
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
|
@ -92,12 +94,14 @@ export default function WebLogs() {
|
|||
</Helmet>
|
||||
<TopPanel menuItems={menuItems} extraMenuItems={extraMenuItems} />
|
||||
<div className="content">
|
||||
<h6>{state.prefix}</h6>
|
||||
<br />
|
||||
{
|
||||
state.loading
|
||||
? <Spinner />
|
||||
: (
|
||||
<pre>
|
||||
{state.data}
|
||||
{HtmlParser(state.data)}
|
||||
</pre>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
.web-logs {
|
||||
.content {
|
||||
padding: 50px 10px 0;
|
||||
color: #7d7d7d;
|
||||
font-size: 20px;
|
||||
font-size: 14px;
|
||||
color: #555;
|
||||
padding-top: 4rem;
|
||||
}
|
||||
|
||||
.nav-link:nth-child(3),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue