Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix server status behavior on not-loaded-yet state; adjust texts; lin…
…t fixes
  • Loading branch information
aine-etke committed Apr 7, 2025
commit a2dee49cfaf603c6b9f81f3a7beb10e20a9d3bdd
5 changes: 2 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ import { Route } from "react-router-dom";
import AdminLayout from "./components/AdminLayout";
import ServerNotificationsPage from "./components/etke.cc/ServerNotificationsPage";
import ServerStatusPage from "./components/etke.cc/ServerStatusPage";
import ServerSchedulesPage from "./components/etke.cc/schedules/components/ServerSchedulesPage";
import RecurringCommandEdit from "./components/etke.cc/schedules/components/recurring/RecurringCommandEdit";
import ScheduledCommandEdit from "./components/etke.cc/schedules/components/scheduled/ScheduledCommandEdit";
import ScheduledCommandShow from "./components/etke.cc/schedules/components/scheduled/ScheduledCommandShow";
import RecurringCommandEdit from "./components/etke.cc/schedules/components/recurring/RecurringCommandEdit";
import ServerSchedulesPage from "./components/etke.cc/schedules/components/ServerSchedulesPage";
import UserImport from "./components/user-import/UserImport";
import germanMessages from "./i18n/de";
import englishMessages from "./i18n/en";
Expand All @@ -29,7 +29,6 @@ import users from "./resources/users";
import authProvider from "./synapse/authProvider";
import dataProvider from "./synapse/dataProvider";


// TODO: Can we use lazy loading together with browser locale?
const messages = {
de: germanMessages,
Expand Down
36 changes: 25 additions & 11 deletions src/components/AdminLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import ManageHistoryIcon from "@mui/icons-material/ManageHistory";
import { useEffect, useState, Suspense } from "react";
import {
CheckForApplicationUpdate,
Expand All @@ -21,7 +22,6 @@ import { ServerNotificationsBadge } from "./etke.cc/ServerNotificationsBadge";
import { ServerProcessResponse, ServerStatusResponse } from "../synapse/dataProvider";
import ServerStatusBadge from "./etke.cc/ServerStatusBadge";
import { ServerStatusStyledBadge } from "./etke.cc/ServerStatusBadge";
import ManageHistoryIcon from '@mui/icons-material/ManageHistory';

const AdminUserMenu = () => {
const [open, setOpen] = useState(false);
Expand Down Expand Up @@ -96,16 +96,30 @@ const AdminMenu = props => {

return (
<Menu {...props}>
{etkeRoutesEnabled && <Menu.Item key="server_status" to="/server_status" leftIcon={
<ServerStatusStyledBadge
inSidebar={true}
command={serverProcess.command}
locked_at={serverProcess.locked_at}
isOkay={serverStatus.ok} />
}
primaryText="Server Status" />
}
{etkeRoutesEnabled && <Menu.Item key="server_schedules" to="/server_schedules" leftIcon={<ManageHistoryIcon />} primaryText="Server Schedules" />}
{etkeRoutesEnabled && (
<Menu.Item
key="server_status"
to="/server_status"
leftIcon={
<ServerStatusStyledBadge
inSidebar={true}
command={serverProcess.command}
locked_at={serverProcess.locked_at}
isOkay={serverStatus.ok}
isLoaded={serverStatus.success}
/>
}
primaryText="Server Status"
/>
)}
{etkeRoutesEnabled && (
<Menu.Item
key="server_schedules"
to="/server_schedules"
leftIcon={<ManageHistoryIcon />}
primaryText="Server Schedules"
/>
)}
<Menu.ResourceItems />
{menu &&
menu.map((item, index) => {
Expand Down
33 changes: 17 additions & 16 deletions src/components/etke.cc/ServerCommandsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@ import {
} from "@mui/material";
import { useEffect, useState } from "react";
import { Button, Loading, useDataProvider, useCreatePath, useStore } from "react-admin";
import { useAppContext } from "../../Context";
import { Icons } from "../../utils/icons";
import { ServerCommand, ServerProcessResponse } from "../../synapse/dataProvider";
import { Link } from "react-router-dom";

import { useAppContext } from "../../Context";
import { useServerCommands } from "./hooks/useServerCommands";
import { ServerCommand, ServerProcessResponse } from "../../synapse/dataProvider";
import { Icons } from "../../utils/icons";

const renderIcon = (icon: string) => {
const IconComponent = Icons[icon] as React.ComponentType<any> | undefined;
Expand All @@ -32,7 +33,10 @@ const ServerCommandsPanel = () => {

const createPath = useCreatePath();
const { isLoading, serverCommands, setServerCommands } = useServerCommands();
const [serverProcess, setServerProcess] = useStore<ServerProcessResponse>("serverProcess", { command: "", locked_at: "" });
const [serverProcess, setServerProcess] = useStore<ServerProcessResponse>("serverProcess", {
command: "",
locked_at: "",
});
const [commandIsRunning, setCommandIsRunning] = useState<boolean>(serverProcess.command !== "");
const [commandResult, setCommandResult] = useState<React.ReactNode[]>([]);
const dataProvider = useDataProvider();
Expand All @@ -44,10 +48,10 @@ const ServerCommandsPanel = () => {
}, [serverProcess]);

const setCommandAdditionalArgs = (command: string, additionalArgs: string) => {
const updatedServerCommands = {...serverCommands};
const updatedServerCommands = { ...serverCommands };
updatedServerCommands[command].additionalArgs = additionalArgs;
setServerCommands(updatedServerCommands);
}
};

const runCommand = async (command: string) => {
setCommandResult([]);
Expand Down Expand Up @@ -89,15 +93,16 @@ const ServerCommandsPanel = () => {
results.push(<Box key="command-text">{commandScheduledText}</Box>);
results.push(
<Box key="notification-link">
Expect your result in the <Link to={createPath({ resource: "server_notifications", type: "list" })}>Notifications</Link> page soon.
Expect your result in the{" "}
<Link to={createPath({ resource: "server_notifications", type: "list" })}>Notifications</Link> page soon.
</Box>
);

return results;
};

const resetCommandArgs = (command: string) => {
const updatedServerCommands = {...serverCommands};
const updatedServerCommands = { ...serverCommands };
updatedServerCommands[command].additionalArgs = "";
setServerCommands(updatedServerCommands);
};
Expand All @@ -111,7 +116,7 @@ const ServerCommandsPanel = () => {
serverProcess["locked_at"] = new Date().toISOString();
}

setServerProcess({...serverProcess});
setServerProcess({ ...serverProcess });
};

if (isLoading) {
Expand All @@ -132,10 +137,7 @@ const ServerCommandsPanel = () => {
</TableHead>
<TableBody>
{Object.entries(serverCommands).map(([command, { icon, args, description, additionalArgs }]) => (
<TableRow
key={command}
sx={{ "&:last-child td, &:last-child th": { border: 0 } }}
>
<TableRow key={command} sx={{ "&:last-child td, &:last-child th": { border: 0 } }}>
<TableCell scope="row">
<Box>
{renderIcon(icon)}
Expand All @@ -148,7 +150,7 @@ const ServerCommandsPanel = () => {
<TextField
size="small"
variant="standard"
onChange={(e) => {
onChange={e => {
setCommandAdditionalArgs(command, e.target.value);
}}
value={additionalArgs}
Expand All @@ -164,8 +166,7 @@ const ServerCommandsPanel = () => {
runCommand(command);
}}
disabled={
commandIsRunning ||
(args && typeof additionalArgs === "string" && additionalArgs.length === 0)
commandIsRunning || (args && typeof additionalArgs === "string" && additionalArgs.length === 0)
}
></Button>
</TableCell>
Expand Down
15 changes: 13 additions & 2 deletions src/components/etke.cc/ServerStatusBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,16 +157,26 @@ export const ServerStatusStyledBadge = ({
command,
locked_at,
isOkay,
isLoaded,
inSidebar = false,
}: {
command: string;
locked_at: string;
isOkay: boolean;
isLoaded: boolean;
inSidebar: boolean;
}) => {
const theme = useTheme();
let badgeBackgroundColor = isOkay ? theme.palette.success.light : theme.palette.error.main;
let badgeColor = isOkay ? theme.palette.success.light : theme.palette.error.main;
let badgeBackgroundColor = isLoaded
? isOkay
? theme.palette.success.light
: theme.palette.error.main
: theme.palette.grey[600];
let badgeColor = isLoaded
? isOkay
? theme.palette.success.light
: theme.palette.error.main
: theme.palette.grey[600];

if (command && locked_at) {
badgeBackgroundColor = theme.palette.warning.main;
Expand Down Expand Up @@ -220,6 +230,7 @@ const ServerStatusBadge = () => {
command={command || ""}
locked_at={locked_at || ""}
isOkay={isOkay}
isLoaded={successCheck}
/>
</Box>
</Tooltip>
Expand Down
22 changes: 19 additions & 3 deletions src/components/etke.cc/ServerStatusPage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import CheckIcon from "@mui/icons-material/Check";
import CloseIcon from "@mui/icons-material/Close";
import EngineeringIcon from "@mui/icons-material/Engineering";
import { Box, Stack, Typography, Paper, Link, Chip, Divider, Tooltip, ChipProps } from "@mui/material";
import { Alert, Box, Stack, Typography, Paper, Link, Chip, Divider, Tooltip, ChipProps } from "@mui/material";
import { useStore } from "ra-core";

import ServerCommandsPanel from "./ServerCommandsPanel";
Expand Down Expand Up @@ -68,8 +68,7 @@ const ServerStatusPage = () => {
return (
<Paper elevation={3} sx={{ p: 3, mt: 3 }}>
<Stack direction="row" spacing={2} alignItems="center">
<CloseIcon color="error" />
<Typography color="error">Unable to fetch server status. Please try again later.</Typography>
<Typography color="info">Fetching real-time server health... Just a moment!</Typography>
</Stack>
</Paper>
);
Expand Down Expand Up @@ -106,6 +105,23 @@ const ServerStatusPage = () => {

<ServerCommandsPanel />

<Alert severity="info">
<Typography variant="body" sx={{ px: 2 }}>
This is a{" "}
<Link href="https://etke.cc/services/monitoring/" target="_blank">
monitoring report
</Link>{" "}
of the server. If any of the checks below concern you, please check the{" "}
<Link
href="https://etke.cc/services/monitoring/#what-to-do-if-the-monitoring-report-shows-issues"
target="_blank"
>
suggested actions
</Link>
.
</Typography>
</Alert>

<Stack spacing={2} direction="row">
{Object.keys(groupedResults).map((category, idx) => (
<Box key={`category_${category}`} sx={{ flex: 1 }}>
Expand Down
7 changes: 4 additions & 3 deletions src/components/etke.cc/hooks/useServerCommands.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { useState, useEffect } from "react";
import { useDataProvider } from "react-admin";
import { ServerCommand } from "../../../synapse/dataProvider";

import { useAppContext } from "../../../Context";
import { ServerCommand } from "../../../synapse/dataProvider";

export const useServerCommands = () => {
const { etkeccAdmin } = useAppContext();
const [isLoading, setLoading] = useState(true);
const [serverCommands, setServerCommands] = useState<{ [key: string]: ServerCommand }>({});
const [serverCommands, setServerCommands] = useState<Record<string, ServerCommand>>({});
const dataProvider = useDataProvider();

useEffect(() => {
Expand All @@ -25,4 +26,4 @@ export const useServerCommands = () => {
}, [dataProvider, etkeccAdmin]);

return { isLoading, serverCommands, setServerCommands };
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ const transformCommandsToChoices = (commands: Record<string, any>) => {
return Object.entries(commands).map(([key, value]) => ({
id: key,
name: value.name,
description: value.description
description: value.description,
}));
};

Expand All @@ -14,8 +14,8 @@ const ScheduledCommandCreate = () => {
<SelectInput
source="command"
choices={commandChoices}
optionText={(choice) => `${choice.name} - ${choice.description}`}
optionText={choice => `${choice.name} - ${choice.description}`}
/>
</SimpleForm>
);
};
};
42 changes: 28 additions & 14 deletions src/components/etke.cc/schedules/components/ServerSchedulesPage.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import RestoreIcon from "@mui/icons-material/Restore";
import ScheduleIcon from "@mui/icons-material/Schedule";
import { Box, Typography, Link, Alert, Divider } from "@mui/material";
import { Stack } from "@mui/material"
import ScheduleIcon from '@mui/icons-material/Schedule';
import RestoreIcon from '@mui/icons-material/Restore';
import ScheduledCommandsList from "./scheduled/ScheduledCommandsList";
import { Stack } from "@mui/material";

import RecurringCommandsList from "./recurring/RecurringCommandsList";
import ScheduledCommandsList from "./scheduled/ScheduledCommandsList";

const ServerSchedulesPage = () => {
return (
Expand All @@ -12,20 +13,30 @@ const ServerSchedulesPage = () => {
<Box sx={{ display: "flex", alignItems: "center", gap: 1 }}>
<Typography variant="h4">Server Schedules</Typography>
</Box>
<Alert severity="info">
<Typography variant="body1">
This is a web interface for the <Link target="_blank" href="https://etke.cc/help/extras/scheduler/">Scheduler Service</Link> that allows you to manage and maintain your server without using the Matrix bot directly.
</Typography>
</Alert>
<Typography variant="body1">
Here you can{" "}
<Link target="_blank" href="https://etke.cc/help/extras/scheduler/#schedule">
schedule
</Link>{" "}
commands to run them either once at a certain time or on{" "}
<Link target="_blank" href="https://etke.cc/help/extras/scheduler/#recurring">
a recurring basis
</Link>
.
</Typography>
</Stack>

<Box sx={{ mt: 2 }}>
<Typography variant="h5">
<ScheduleIcon sx={{ verticalAlign: "middle", mr: 1 }} /> Scheduled commands
</Typography>
<Typography variant="body1">
The following commands are scheduled to run at specific times. You can view their details and modify them as needed.
More details about the mode can be found <Link href="https://etke.cc/help/extras/scheduler/#schedule" target="_blank">here</Link>.
The following commands are scheduled to run at specific times. You can view their details and modify them as
needed. More details about the mode can be found{" "}
<Link href="https://etke.cc/help/extras/scheduler/#schedule" target="_blank">
here
</Link>
.
</Typography>
<ScheduledCommandsList />
</Box>
Expand All @@ -37,9 +48,12 @@ const ServerSchedulesPage = () => {
<RestoreIcon sx={{ verticalAlign: "middle", mr: 1 }} /> Recurring commands
</Typography>
<Typography variant="body1">
The following commands are set to run at specific weekday and time (weekly).
You can view their details and modify them as needed.
More details about the mode can be found <Link href="https://etke.cc/help/extras/scheduler/#recurring" target="_blank">here</Link>.
The following commands are set to run at specific weekday and time (weekly). You can view their details and
modify them as needed. More details about the mode can be found{" "}
<Link href="https://etke.cc/help/extras/scheduler/#recurring" target="_blank">
here
</Link>
.
</Typography>
<RecurringCommandsList />
</Box>
Expand Down
Loading