Merge pull request #25 from hubHarmony/ServerHistory

+ ServerHistory v1 and sidebar status bug fixed
This commit is contained in:
Antoninop 2024-08-22 17:20:14 +02:00 committed by GitHub
commit bc8ad3f096
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 135 additions and 38 deletions

View File

@ -6,7 +6,7 @@ import serviiApi from "../../service/api.tsx";
import Loading from '../Loading/loading.jsx'; import Loading from '../Loading/loading.jsx';
import PropTypes from "prop-types"; import PropTypes from "prop-types";
const ServerConsole = ({ user }) => { const ServerConsole = () => {
const navigate = useNavigate(); const navigate = useNavigate();
const { serverName } = useParams(); const { serverName } = useParams();
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@ -24,23 +24,23 @@ const ServerConsole = ({ user }) => {
const fetchServerLogs = async () => { const fetchServerLogs = async () => {
setError(null); setError(null);
setLoading(true);
try { try {
const response = await serviiApi.fetchLogs(serverName); const response = await serviiApi.fetchLogs(serverName);
if (response.return_code === 200) { if (response.return_code === 200) {
let logString = response.message; let logString = response.message;
logString = logString.slice(1, -1); logString = logString.slice(1, -1);
logString = logString.replace(/\\n/g, '\n'); logString = logString.replace(/\\n/g, '\n');
logString = logString.replace(/\\\"/g, '"'); logString = logString.replace(/\\"/g, '"');
logString = logString.replace(/, ?/g, ''); logString = logString.replace(/, ?/g, '');
logString = logString.replace(/"{2,}/g, ''); logString = logString.replace(/"{2,}/g, '');
logString = logString.replace(/'{2,}/g, ''); logString = logString.replace(/'{2,}/g, '');
logString = logString.trim(); logString = logString.trim();
setLogs(logString); setLogs(logString);
setLoading(false);
} }
} catch (err) { } catch (err) {
setError(`Erreur: ${err.message}`); setError(`Erreur: ${err.message}`);
} finally {
} }
}; };
@ -57,7 +57,7 @@ const ServerConsole = ({ user }) => {
return; return;
} }
try { try {
const response = await serviiApi.command(message, serverName); await serviiApi.command(message, serverName);
setMessage(''); setMessage('');
fetchServerLogs(); fetchServerLogs();
} catch (err) { } catch (err) {

View File

@ -1,8 +1,9 @@
import { useParams, useNavigate, Route, Routes, Link } from 'react-router-dom'; import { useParams, Route, Routes } from 'react-router-dom';
import { useState, useEffect } from 'react';
import Navbar from '../../components/navbar/Navbar'; import Navbar from '../../components/navbar/Navbar';
import ServerProperties from '../ServerProperties/ServerProperties'; import ServerProperties from '../ServerProperties/ServerProperties';
import ServerConsole from '../ServerConsole/ServerConsole'; import ServerConsole from '../ServerConsole/ServerConsole';
// import ServerHistory from '../ServerHistory/ServerHistory'; import ServerHistory from '../ServerHistory/ServerHistory';
// import ServerPlayers from '../ServerPlayers/ServerPlayers'; // import ServerPlayers from '../ServerPlayers/ServerPlayers';
// import ServerWorlds from '../ServerWorlds/ServerWorlds'; // import ServerWorlds from '../ServerWorlds/ServerWorlds';
// import ServerBackups from '../ServerBackups/ServerBackups'; // import ServerBackups from '../ServerBackups/ServerBackups';
@ -14,29 +15,31 @@ import NotFoundPage from '../NotFoundPage/NotFoundPage';
import { NavLink } from 'react-router-dom'; import { NavLink } from 'react-router-dom';
import { useLocation } from 'react-router-dom'; import { useLocation } from 'react-router-dom';
const ServerDetails = ({ user }) => { const ServerDetails = ({ user }) => {
const { serverName } = useParams(); const { serverName } = useParams();
const navigate = useNavigate();
const location = useLocation(); const location = useLocation();
const status = location.state?.status; const initialStatus = location.state?.status || false;
const [status, setStatus] = useState(initialStatus);
const handleQuit = () => {
navigate('/dashboard');
};
useEffect(() => {
if (location.state?.status !== undefined) {
setStatus(location.state.status);
}
}, [location]);
return ( return (
<> <>
<Navbar user={user} /> <Navbar user={user} />
<div className={styles.container}> <div className={styles.container}>
<div className={styles.sidebar}> <div className={styles.sidebar}>
<div className={styles.userinfo}>
<div className={styles.user}>
<p>{user.displayName}</p>
</div>
</div>
<div className={styles.menu}> <div className={styles.menu}>
<NavLink
to={`/dashboard`}
className={`${styles.menuItem} ${styles.extraMargin}`}>
<FaServer /> Retour aux serveurs
</NavLink>
<NavLink <NavLink
to={`/server/${serverName}/options`} to={`/server/${serverName}/options`}
className={({ isActive }) => isActive ? `${styles.menuItem} ${styles.active}` : styles.menuItem}> className={({ isActive }) => isActive ? `${styles.menuItem} ${styles.active}` : styles.menuItem}>
@ -80,14 +83,13 @@ const ServerDetails = ({ user }) => {
<FaLock /> Accès <FaLock /> Accès
</NavLink> </NavLink>
</div> </div>
<button className={styles.BackButton} onClick={handleQuit}>Retour</button>
</div> </div>
<div className={styles.serverDetailsContainer}> <div className={styles.serverDetailsContainer}>
<Routes> <Routes>
<Route path="options" element={<ServerProperties user={user} status={status} />} /> <Route path="options" element={<ServerProperties user={user} status={status} />} />
<Route path="console" element={<ServerConsole user={user} status={status} />} /> <Route path="console" element={<ServerConsole user={user} status={status} />} />
<Route path="history" element={<h2>Cette fonctionnalité sera prochainement disponible.</h2>} /> <Route path="history" element={<ServerHistory user={user} status={status} />} />
<Route path="players" element={<h2>Cette fonctionnalité sera prochainement disponible.</h2>} /> <Route path="players" element={<h2 >Cette fonctionnalité sera prochainement disponible.</h2>} />
<Route path="worlds" element={<h2>Cette fonctionnalité sera prochainement disponible.</h2>} /> <Route path="worlds" element={<h2>Cette fonctionnalité sera prochainement disponible.</h2>} />
<Route path="backups" element={<h2>Cette fonctionnalité sera prochainement disponible.</h2>} /> <Route path="backups" element={<h2>Cette fonctionnalité sera prochainement disponible.</h2>} />
<Route path="access" element={<h2>Cette fonctionnalité sera prochainement disponible.</h2>} /> <Route path="access" element={<h2>Cette fonctionnalité sera prochainement disponible.</h2>} />

View File

@ -6,8 +6,8 @@
.sidebar { .sidebar {
width: 20rem; width: 20rem;
background-color: #100D25; background-color: #100D25;
padding: 2rem 1rem;
padding-left: 0rem; padding-left: 0rem;
padding-right: 1rem;
box-sizing: border-box; box-sizing: border-box;
position: fixed; position: fixed;
height: calc(100vh - var(--navbar-height)); height: calc(100vh - var(--navbar-height));
@ -19,7 +19,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
padding: 0.7rem 1rem ; padding: 0.7rem 1rem ;
margin: .5rem 0rem; margin: .8rem 0rem;
padding-right: 0rem; padding-right: 0rem;
font-size: 1.5rem; font-size: 1.5rem;
cursor: pointer; cursor: pointer;
@ -54,6 +54,8 @@
.menu { .menu {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-around;
margin-top: 2.5rem;
} }
@ -66,18 +68,6 @@
font-size: 1.25rem; font-size: 1.25rem;
} }
.BackButton {
margin-top: 1rem;
padding: 0.70rem 1.5rem;
background-color: #1D1836;
border: none;
color: white;
cursor: pointer;
width: 20rem;
text-align: center;
font-size: 1.25rem;
}
.serverDetailsContainer { .serverDetailsContainer {
margin-top: var(--navbar-height); margin-top: var(--navbar-height);

View File

@ -0,0 +1,91 @@
import { useEffect, useState, useRef } from 'react';
import { useParams, useNavigate, useLocation } from 'react-router-dom';
import styles from './ServerHistory.module.scss';
import serviiApi from "../../service/api.tsx";
import Loading from '../Loading/loading.jsx';
import PropTypes from "prop-types";
const ServerHistory = ({ user }) => {
const navigate = useNavigate();
const { serverName } = useParams();
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const [history, setHistory] = useState('');
const location = useLocation();
const status = location.state?.status;
const historyEndRef = useRef(null);
const scrollToBottom = () => {
historyEndRef.current?.scrollIntoView({ behavior: "smooth" });
};
const fetchServerHistory = async () => {
setError(null);
setLoading(true);
try {
const response = await serviiApi.fetchHistory(serverName);
if (response.return_code === 200) {
let historyString = response.message;
historyString = historyString.slice(1, -1);
historyString = historyString.replace(/\\n/g, '\n');
historyString = historyString.replace(/\\\"/g, '"');
historyString = historyString.replace(/, ?/g, '');
historyString = historyString.replace(/"{2,}/g, '');
historyString = historyString.replace(/'{2,}/g, '');
historyString = historyString.trim();
setHistory(historyString);
}
} catch (err) {
setError(`Erreur: ${err.message}`);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchServerHistory();
}, [serverName]);
useEffect(() => {
scrollToBottom();
}, [history]);
if (loading) {
return <Loading />;
}
if (error) {
return (
<div className={styles.serverDetailsContainer}>
<div className={styles.error}>
<h1>{error}</h1>
<button onClick={() => navigate('/dashboard')}>Retour au Dashboard</button>
</div>
</div>
);
}
return (
<div className={styles.container}>
<div className={styles.containerHistory}>
<div className={styles.header}>
<pre className={styles.logs}>
{history}
</pre>
</div>
</div>
</div>
);
};
ServerHistory.propTypes = {
user: PropTypes.oneOfType([
PropTypes.shape({
uid: PropTypes.string.isRequired,
}),
]),
};
export default ServerHistory;

View File

@ -0,0 +1,8 @@
.container{
margin-top: var(--navbar-height);
}
.extraMargin{
margin-bottom: 5rem;
color:red;
}

View File

@ -39,7 +39,6 @@ interface CommandRequest extends BaseRequest {
enum serviiRequest { enum serviiRequest {
setSubdomain = 'SetSubdomain', setSubdomain = 'SetSubdomain',
fetchServers = 'FetchServers', fetchServers = 'FetchServers',
fetchLogs = 'FetchLogs',
accountCreate = 'AccountCreate', accountCreate = 'AccountCreate',
serverCreate = 'ServerCreate', serverCreate = 'ServerCreate',
serverDelete = 'ServerDelete', serverDelete = 'ServerDelete',
@ -48,12 +47,14 @@ enum serviiRequest {
serverStop = 'ServerStop', serverStop = 'ServerStop',
updateProperty = 'UpdateProperties', updateProperty = 'UpdateProperties',
command = 'Command', command = 'Command',
fetchLogs = 'FetchLogs',
fetchHistory = 'FetchHistory',
} }
const nonToastableCalls: string[] = [ const nonToastableCalls: string[] = [
serviiRequest.fetchServers, serviiRequest.fetchServers,
serviiRequest.fetchLogs, serviiRequest.fetchLogs,
serviiRequest.fetchHistory,
]; ];
class serviiApi { class serviiApi {
@ -128,6 +129,11 @@ class serviiApi {
return this.call(serviiRequest.fetchLogs, payload); return this.call(serviiRequest.fetchLogs, payload);
} }
public static async fetchHistory(name: string): Promise<ApiResponse> {
const payload: ServerRequest = { token: this.token(), name: name };
return this.call(serviiRequest.fetchHistory, payload);
}
public static async accountCreate(): Promise<ApiResponse> { public static async accountCreate(): Promise<ApiResponse> {
const payload: BaseRequest = { token: this.token() }; const payload: BaseRequest = { token: this.token() };
return this.call(serviiRequest.accountCreate, payload); return this.call(serviiRequest.accountCreate, payload);