Add unused experimental settings modal

This commit is contained in:
Corey 2024-04-22 18:41:17 +00:00
parent feb2dc528c
commit 34b498cbfc
5 changed files with 185 additions and 99 deletions

View File

@ -4,12 +4,12 @@ import { BrowserRouter, Route, Routes } from 'react-router-dom';
import AlertComponent from './components/Alert';
import Footer from './components/Footer';
import Header from './components/Header';
import ServerDetails from './components/ServerDetails';
import SearchState from './data/SearchState';
import ServerData from './data/ServerData';
import About from './pages/About';
import Home from './pages/Home';
import NotFound from './pages/NotFound';
import ServerDetails from './pages/ServerDetails';
export function App() {
const [alertInfo, setAlertInfo] = useState<{

View File

@ -277,9 +277,11 @@ export default function ServerCard({ server }: { server: ServerData }) {
</AccordionDetails>
</Accordion>
<Divider />
<CardContent className="flex justify-between py-0">
<Typography variant="caption" className="flex items-center">
{server.active_sessions} active sessions
<CardContent className="flex flex-wrap justify-between py-0">
<Box className="flex items-center whitespace-nowrap">
<Typography variant="caption">
{server.active_sessions} active sessions
</Typography>
{server.login_limit !== 1 && (
<Tooltip
title={`Server allows ${server.login_limit === 0 ? 'unlimited' : server.login_limit} simultaneous game sessions per IP.`}
@ -290,16 +292,16 @@ export default function ServerCard({ server }: { server: ServerData }) {
src={CopyImageIcon}
alt=""
style={{
maxHeight: '1.5em',
maxHeight: '1em',
marginLeft: '0.5em',
verticalAlign: 'middle',
}}
onContextMenu={(event) => event.preventDefault()}
/>
</Tooltip>
)}
</Typography>
<Typography variant="caption" className="flex items-center">
</Box>
<Box className="flex items-center whitespace-nowrap">
{/* <ServerDetailsModal id={server.id} /> */}
<Tooltip title="View full settings." arrow disableInteractive>
<IconButton
component={Link}
@ -311,8 +313,10 @@ export default function ServerCard({ server }: { server: ServerData }) {
<Info className="p-1" />
</IconButton>
</Tooltip>
Updated: {new Date(server.updated).toLocaleString()}
</Typography>
<Typography variant="caption">
Updated: {new Date(server.updated).toLocaleString()}
</Typography>
</Box>
</CardContent>
</Card>
);

View File

@ -0,0 +1,79 @@
import { Info } from '@mui/icons-material';
import { Card, IconButton, Tooltip, Typography } from '@mui/material';
import Modal from '@mui/material/Modal';
import { useState } from 'react';
import { fetchData } from '../apiUtil';
import ServerData from '../data/ServerData';
import ServerSettingsDataGrid from './ServerSettingsDataGrid';
export default function ServerDetailsModal({ id }: { id: number }) {
const [server, setServer] = useState<ServerData>();
const [error, setError] = useState<string>('');
const [open, setOpen] = useState(false);
const handleOpen = () => {
let data: ServerData;
const fetchServerData = async () => {
try {
data = await fetchData(`server/${id}`);
} catch (err) {
if (err instanceof Error) {
setError(err.message);
} else {
setError('An unknown error occurred.');
}
}
setServer(data);
};
fetchServerData();
setOpen(true);
};
const handleClose = () => setOpen(false);
return (
<div>
<Tooltip title="View full settings." arrow disableInteractive>
<IconButton className="p-0" disableRipple onClick={handleOpen}>
<Info className="p-1" />
</IconButton>
</Tooltip>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Card
sx={{
position: 'absolute' as const,
top: '10%',
left: '10%',
width: '80%',
height: '80%',
overflow: 'hidden',
overflowX: 'hidden',
boxShadow: 24,
}}
>
<Card
sx={{
position: 'absolute' as const,
width: '100%',
height: '100%',
overflow: 'scroll',
overflowX: 'hidden',
}}
>
{!server || !server.settings ? (
<Typography align="center" variant="subtitle1">
{error}
</Typography>
) : (
<ServerSettingsDataGrid serverSettings={server.settings} />
)}
</Card>
</Card>
</Modal>
</div>
);
}

View File

@ -0,0 +1,87 @@
import { Box } from '@mui/material';
import { DataGrid, GridColDef } from '@mui/x-data-grid';
import {
ServerSetting,
ServerSettings,
ServerSettingsInfo,
} from '../data/ServerData';
interface KeyValueRow {
id: number;
key: string;
rawValue: string | number | boolean;
name: string;
value: string | number | boolean;
description: string;
}
const columns: GridColDef[] = [
{ field: 'key', headerName: 'Key', flex: 4, align: 'right' },
{ field: 'rawValue', headerName: 'Raw Value', flex: 1, align: 'left' },
{ field: 'name', headerName: 'Name', flex: 3, align: 'right' },
{ field: 'value', headerName: 'Value', flex: 1, align: 'left' },
{ field: 'description', headerName: 'Description', flex: 6 },
];
export default function ServerSettingsDataGrid({
serverSettings,
}: {
serverSettings: ServerSettings;
}) {
const transformValue = (
v: boolean | string | number,
setting: ServerSetting
): string | number | boolean => {
return setting.transform?.(v) ?? v;
};
const rows: KeyValueRow[] = Object.entries(serverSettings).map(
([key, value], index) => ({
id: index + 1,
key,
rawValue: value,
name: ServerSettingsInfo[key]?.name || '',
value:
(ServerSettingsInfo[key] &&
transformValue(value, ServerSettingsInfo[key]).toString()) ||
'',
description: ServerSettingsInfo[key]?.description || '',
})
);
return (
<Box className="w-full">
<DataGrid
rows={rows}
columns={columns}
checkboxSelection={false}
autoHeight
density="compact"
hideFooterSelectedRowCount
showColumnVerticalBorder
getRowHeight={() => 'auto'}
initialState={{
sorting: {
sortModel: [{ field: 'name', sort: 'asc' }],
},
filter: {
filterModel: {
items: [{ field: 'name', operator: 'isNotEmpty' }],
},
},
columns: {
columnVisibilityModel: {
key: false,
rawValue: false,
},
},
}}
sx={{
'& .MuiDataGrid-cell': {
userSelect: 'text',
py: 1,
},
}}
/>
</Box>
);
}

View File

@ -15,99 +15,15 @@ import {
Typography,
alpha,
} from '@mui/material';
import { DataGrid, GridColDef } from '@mui/x-data-grid';
import { useEffect, useState } from 'react';
import { Link, useParams } from 'react-router-dom';
import { fetchData, fetchDemo } from '../apiUtil';
import ServerData, {
ServerSetting,
ServerSettings,
ServerSettingsInfo,
} from '../data/ServerData';
import { AlertResponse } from '../components/Alert';
import ErrorCard from '../components/ErrorCard';
import ExpansionBar from '../components/ExpansionsBar';
import ServerSettingsDataGrid from '../components/ServerSettingsDataGrid';
import ServerData from '../data/ServerData';
import CopyImageIcon from '../images/copy-image.png';
import { AlertResponse } from './Alert';
import ErrorCard from './ErrorCard';
import ExpansionBar from './ExpansionsBar';
interface KeyValueRow {
id: number;
key: string;
rawValue: string | number | boolean;
name: string;
value: string | number | boolean;
description: string;
}
const columns: GridColDef[] = [
{ field: 'key', headerName: 'Key', flex: 4, align: 'right' },
{ field: 'rawValue', headerName: 'Raw Value', flex: 1, align: 'left' },
{ field: 'name', headerName: 'Name', flex: 3, align: 'right' },
{ field: 'value', headerName: 'Value', flex: 1, align: 'left' },
{ field: 'description', headerName: 'Description', flex: 6 },
];
function ServerSettingsDataGrid({
serverSettings,
}: {
serverSettings: ServerSettings;
}) {
const transformValue = (
v: boolean | string | number,
setting: ServerSetting
): string | number | boolean => {
return setting.transform?.(v) ?? v;
};
const rows: KeyValueRow[] = Object.entries(serverSettings).map(
([key, value], index) => ({
id: index + 1,
key,
rawValue: value,
name: ServerSettingsInfo[key]?.name || '',
value:
(ServerSettingsInfo[key] &&
transformValue(value, ServerSettingsInfo[key]).toString()) ||
'',
description: ServerSettingsInfo[key]?.description || '',
})
);
return (
<Box className="w-full">
<DataGrid
rows={rows}
columns={columns}
checkboxSelection={false}
autoHeight
density="compact"
hideFooterSelectedRowCount
showColumnVerticalBorder
getRowHeight={() => 'auto'}
initialState={{
sorting: {
sortModel: [{ field: 'name', sort: 'asc' }],
},
filter: {
filterModel: {
items: [{ field: 'name', operator: 'isNotEmpty' }],
},
},
columns: {
columnVisibilityModel: {
key: false,
rawValue: false,
},
},
}}
sx={{
'& .MuiDataGrid-cell': {
userSelect: 'text',
py: 1,
},
}}
/>
</Box>
);
}
export default function ServerDetails({
setAlertInfo,