Polish admin styles

This commit is contained in:
David Stotijn
2020-09-23 18:10:32 +02:00
parent a3c22b7f1f
commit e9367f7186
16 changed files with 178 additions and 97 deletions

View File

@ -12,6 +12,7 @@
"@apollo/client": "^3.2.0",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^4.0.0-alpha.56",
"graphql": "^15.3.0",
"next": "^9.5.3",
"react": "^16.13.1",

View File

@ -0,0 +1,25 @@
import { Paper } from "@material-ui/core";
function CenteredPaper({
children,
}: {
children: React.ReactNode;
}): JSX.Element {
return (
<div>
<Paper
elevation={0}
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
padding: 36,
}}
>
{children}
</Paper>
</div>
);
}
export default CenteredPaper;

View File

@ -86,7 +86,7 @@ const useStyles = makeStyles((theme: Theme) =>
},
content: {
flexGrow: 1,
padding: theme.spacing(2),
padding: theme.spacing(3),
},
listItem: {
paddingLeft: 16,
@ -136,7 +136,7 @@ export function Layout(props: { children: React.ReactNode }): JSX.Element {
<MenuIcon />
</IconButton>
<Typography variant="h5" noWrap>
Hetty
<span style={{ marginRight: 12 }}>🧑🔧</span>Hetty
</Typography>
</Toolbar>
</AppBar>

View File

@ -1,4 +1,4 @@
import { teal, orange, red } from "@material-ui/core/colors";
import { green, orange, red } from "@material-ui/core/colors";
import FiberManualRecordIcon from "@material-ui/icons/FiberManualRecord";
function HttpStatusIcon({ status }: { status: number }): JSX.Element {
@ -6,7 +6,7 @@ function HttpStatusIcon({ status }: { status: number }): JSX.Element {
switch (Math.floor(status / 100)) {
case 2:
case 3:
return <FiberManualRecordIcon style={{ ...style, color: teal[400] }} />;
return <FiberManualRecordIcon style={{ ...style, color: green[600] }} />;
case 4:
return <FiberManualRecordIcon style={{ ...style, color: orange[400] }} />;
case 5:

View File

@ -1,8 +1,9 @@
import { gql, useQuery } from "@apollo/client";
import { Box, Grid, Paper } from "@material-ui/core";
import { Box, Grid, Paper, CircularProgress } from "@material-ui/core";
import ResponseDetail from "./ResponseDetail";
import RequestDetail from "./RequestDetail";
import Alert from "@material-ui/lab/Alert";
const HTTP_REQUEST_LOG = gql`
query HttpRequestLog($id: ID!) {
@ -31,8 +32,16 @@ function LogDetail({ requestId: id }: Props): JSX.Element {
variables: { id },
});
if (loading) return <div>"Loading..."</div>;
if (error) return <div>`Error: ${error.message}`</div>;
if (loading) {
return <CircularProgress />;
}
if (error) {
return (
<Alert severity="error">
Error fetching logs details: {error.message}
</Alert>
);
}
const { method, url, proto, body, response } = data.httpRequestLog;
@ -40,13 +49,13 @@ function LogDetail({ requestId: id }: Props): JSX.Element {
<div>
<Grid container item spacing={2}>
<Grid item xs={6}>
<Box component={Paper} maxHeight="60vh" overflow="scroll">
<Box component={Paper} maxHeight="62vh" overflow="scroll">
<RequestDetail request={{ method, url, proto, body }} />
</Box>
</Grid>
<Grid item xs={6}>
{response && (
<Box component={Paper} maxHeight="65vh" overflow="scroll">
<Box component={Paper} maxHeight="62vh" overflow="scroll">
<ResponseDetail response={response} />
</Box>
)}

View File

@ -1,37 +1,56 @@
import { gql, useQuery } from "@apollo/client";
import { useState } from "react";
import { Box, Paper, Container, Typography } from "@material-ui/core";
import { Box, Typography, CircularProgress } from "@material-ui/core";
import Alert from "@material-ui/lab/Alert";
import RequestList from "./RequestList";
import LogDetail from "./LogDetail";
import CenteredPaper from "../CenteredPaper";
const HTTP_REQUEST_LOGS = gql`
query HttpRequestLogs {
httpRequestLogs {
id
method
url
timestamp
response {
status
statusCode
}
}
}
`;
function LogsOverview(): JSX.Element {
const [detailReqLogId, setDetailReqLogId] = useState<string | null>(null);
const { loading, error, data } = useQuery(HTTP_REQUEST_LOGS);
const [detailReqLogId, setDetailReqLogId] = useState<string | null>(null);
const handleLogClick = (reqId: string) => setDetailReqLogId(reqId);
if (loading) {
return <CircularProgress />;
}
if (error) {
return <Alert severity="error">Error fetching logs: {error.message}</Alert>;
}
const { httpRequestLogs: logs } = data;
return (
<Box style={{ padding: 8 }}>
<div>
<Box mb={2}>
<RequestList onLogClick={handleLogClick} />
<RequestList logs={logs} onLogClick={handleLogClick} />
</Box>
<Box>
{detailReqLogId ? (
<LogDetail requestId={detailReqLogId} />
) : (
<Paper
elevation={0}
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "60vh",
}}
>
{detailReqLogId && <LogDetail requestId={detailReqLogId} />}
{logs.length !== 0 && !detailReqLogId && (
<CenteredPaper>
<Typography>Select a log entry</Typography>
</Paper>
</CenteredPaper>
)}
</Box>
</Box>
</div>
);
}

View File

@ -1,6 +1,6 @@
import { Typography, Box } from "@material-ui/core";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { materialLight } from "react-syntax-highlighter/dist/cjs/styles/prism";
import { vscDarkPlus } from "react-syntax-highlighter/dist/cjs/styles/prism";
interface Props {
request: {
@ -15,7 +15,6 @@ function RequestDetail({ request }: Props): JSX.Element {
const { method, url, proto, body } = request;
const parsedUrl = new URL(url);
console.log(parsedUrl);
return (
<div>
@ -24,18 +23,18 @@ function RequestDetail({ request }: Props): JSX.Element {
variant="h6"
style={{ fontSize: "1rem", whiteSpace: "nowrap" }}
>
{request.method}{" "}
{decodeURIComponent(parsedUrl.pathname + parsedUrl.search)} {proto}
{method} {decodeURIComponent(parsedUrl.pathname + parsedUrl.search)}{" "}
{proto}
</Typography>
</Box>
<Box>
{request.body && (
{body && (
<SyntaxHighlighter
language="markup"
showLineNumbers={true}
style={materialLight}
style={vscDarkPlus}
>
{request.body}
{body}
</SyntaxHighlighter>
)}
</Box>

View File

@ -1,4 +1,3 @@
import { gql, useQuery } from "@apollo/client";
import {
TableContainer,
Paper,
@ -7,42 +6,50 @@ import {
TableRow,
TableCell,
TableBody,
CircularProgress,
Typography,
Box,
} from "@material-ui/core";
import HttpStatusIcon from "./HttpStatusCode";
const HTTP_REQUEST_LOGS = gql`
query HttpRequestLogs {
httpRequestLogs {
id
method
url
timestamp
response {
status
statusCode
}
}
}
`;
import CenteredPaper from "../CenteredPaper";
interface Props {
logs: Array<any>;
onLogClick(requestId: string): void;
}
function RequestList({ onLogClick }: Props): JSX.Element {
const { loading, error, data } = useQuery(HTTP_REQUEST_LOGS);
function RequestList({ logs, onLogClick }: Props): JSX.Element {
return (
<div>
<RequestListTable onLogClick={onLogClick} logs={logs} />
{logs.length === 0 && (
<Box my={1}>
<CenteredPaper>
<Typography>No logs found.</Typography>
</CenteredPaper>
</Box>
)}
</div>
);
}
if (loading) return <div>"Loading..."</div>;
if (error) return <div>`Error: ${error.message}`</div>;
const { httpRequestLogs: logs } = data;
interface RequestListTableProps {
logs?: any;
onLogClick(requestId: string): void;
}
function RequestListTable({
logs,
onLogClick,
}: RequestListTableProps): JSX.Element {
return (
<TableContainer
component={Paper}
style={{ minHeight: 200, height: "24vh" }}
style={{
minHeight: logs.length ? 200 : 0,
height: logs.length ? "24vh" : "inherit",
}}
>
<Table stickyHeader size="small">
<TableHead>

View File

@ -1,6 +1,6 @@
import { Typography, Box } from "@material-ui/core";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { materialLight } from "react-syntax-highlighter/dist/cjs/styles/prism";
import { vscDarkPlus } from "react-syntax-highlighter/dist/cjs/styles/prism";
import HttpStatusIcon from "./HttpStatusCode";
@ -26,22 +26,24 @@ function ResponseDetail({ response }: Props): JSX.Element {
</Typography>
</Box>
<Box>
<SyntaxHighlighter
language="markup"
showLineNumbers={true}
showInlineLineNumbers={true}
style={materialLight}
lineProps={{
style: {
display: "block",
wordBreak: "break-all",
whiteSpace: "pre-wrap",
},
}}
wrapLines={true}
>
{response.body}
</SyntaxHighlighter>
{response.body && (
<SyntaxHighlighter
language="markup"
showLineNumbers={true}
showInlineLineNumbers={true}
style={vscDarkPlus}
lineProps={{
style: {
display: "block",
wordBreak: "break-all",
whiteSpace: "pre-wrap",
},
}}
wrapLines={true}
>
{response.body}
</SyntaxHighlighter>
)}
</Box>
</div>
);

View File

@ -8,7 +8,7 @@ function createApolloClient() {
return new ApolloClient({
ssrMode: typeof window === "undefined",
link: new HttpLink({
uri: "http://localhost:3000/api/graphql",
uri: "/api/graphql",
}),
cache: new InMemoryCache({
typePolicies: {

View File

@ -1,11 +1,12 @@
import { createMuiTheme } from "@material-ui/core/styles";
import teal from "@material-ui/core/colors/teal";
import grey from "@material-ui/core/colors/grey";
import green from "@material-ui/core/colors/green";
const theme = createMuiTheme({
palette: {
type: "dark",
primary: {
main: teal[500],
main: grey[900],
},
secondary: {
main: green[500],

View File

@ -1,9 +1,7 @@
import RequestList from "../components/reqlog/RequestList";
function Index(): JSX.Element {
return (
<div>
<h1>Hetty</h1>
<h1>Hetty123</h1>
</div>
);
}

View File

@ -0,0 +1,9 @@
function Index(): JSX.Element {
return (
<div>
<h1>Proxy123</h1>
</div>
);
}
export default Index;

View File

@ -1,17 +0,0 @@
import { useState } from "react";
import { Box } from "@material-ui/core";
import RequestList from "../../components/reqlog/RequestList";
import LogDetail from "../../components/reqlog/LogDetail";
import LogsOverview from "../../components/reqlog/LogsOverview";
import Layout from "../../components/Layout";
function Logs(): JSX.Element {
return (
<Layout>
<LogsOverview />
</Layout>
);
}
export default Logs;

View File

@ -0,0 +1,17 @@
import { Typography, Box } from "@material-ui/core";
import LogsOverview from "../../../components/reqlog/LogsOverview";
import Layout from "../../../components/Layout";
function ProxyLogs(): JSX.Element {
return (
<Layout>
<Box mb={2}>
<Typography variant="h5">Proxy logs</Typography>
</Box>
<LogsOverview />
</Layout>
);
}
export default ProxyLogs;

View File

@ -1085,6 +1085,17 @@
dependencies:
"@babel/runtime" "^7.4.4"
"@material-ui/lab@^4.0.0-alpha.56":
version "4.0.0-alpha.56"
resolved "https://registry.yarnpkg.com/@material-ui/lab/-/lab-4.0.0-alpha.56.tgz#ff63080949b55b40625e056bbda05e130d216d34"
integrity sha512-xPlkK+z/6y/24ka4gVJgwPfoCF4RCh8dXb1BNE7MtF9bXEBLN/lBxNTK8VAa0qm3V2oinA6xtUIdcRh0aeRtVw==
dependencies:
"@babel/runtime" "^7.4.4"
"@material-ui/utils" "^4.10.2"
clsx "^1.0.4"
prop-types "^15.7.2"
react-is "^16.8.0"
"@material-ui/styles@^4.10.0":
version "4.10.0"
resolved "https://registry.yarnpkg.com/@material-ui/styles/-/styles-4.10.0.tgz#2406dc23aa358217aa8cc772e6237bd7f0544071"