Scaffold homepage, small style tweaks

This commit is contained in:
David Stotijn
2020-09-23 23:43:20 +02:00
parent 71de41e6e6
commit 8828a586a1
22 changed files with 1041 additions and 55 deletions

View File

@ -12,7 +12,10 @@ const monacoOptions = {
type language = "html" | "typescript" | "json";
function editorDidMount() {
return (window.MonacoEnvironment.getWorkerUrl = (moduleId, label) => {
return ((window as any).MonacoEnvironment.getWorkerUrl = (
moduleId,
label
) => {
if (label === "json") return "/_next/static/json.worker.js";
if (label === "html") return "/_next/static/html.worker.js";
if (label === "javascript") return "/_next/static/ts.worker.js";
@ -26,8 +29,10 @@ function languageForContentType(contentType: string): language {
case "text/html":
return "html";
case "application/json":
case "application/json; charset=utf-8":
return "json";
case "application/javascript":
case "application/javascript; charset=utf-8":
return "typescript";
default:
return;

View File

@ -9,25 +9,36 @@ import {
TableRow,
} from "@material-ui/core";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
const useStyles = makeStyles((theme: Theme) => {
const paddingX = 0;
const paddingY = theme.spacing(1) / 3;
const tableCell = {
paddingLeft: paddingX,
paddingRight: paddingX,
paddingTop: paddingY,
paddingBottom: paddingY,
verticalAlign: "top",
border: "none",
};
return createStyles({
table: {
tableLayout: "fixed",
width: "100%",
},
keyCell: {
verticalAlign: "top",
width: "30%",
...tableCell,
width: "40%",
fontWeight: "bold",
},
valueCell: {
width: "70%",
verticalAlign: "top",
...tableCell,
width: "60%",
border: "none",
wordBreak: "break-all",
whiteSpace: "pre-wrap",
},
})
);
});
});
interface Props {
headers: Array<{ key: string; value: string }>;
@ -42,7 +53,7 @@ function HttpHeadersTable({ headers }: Props): JSX.Element {
{headers.map(({ key, value }, index) => (
<TableRow key={index}>
<TableCell component="th" scope="row" className={classes.keyCell}>
<code>{key}</code>
<code>{key}:</code>
</TableCell>
<TableCell className={classes.valueCell}>
<code>{value}</code>

View File

@ -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: green[600] }} />;
return <FiberManualRecordIcon style={{ ...style, color: green[400] }} />;
case 4:
return <FiberManualRecordIcon style={{ ...style, color: orange[400] }} />;
case 5:

View File

@ -51,6 +51,14 @@ function LogDetail({ requestId: id }: Props): JSX.Element {
);
}
if (!data.httpRequestLog) {
return (
<Alert severity="warning">
Request <strong>{id}</strong> was not found.
</Alert>
);
}
const { method, url, proto, headers, body, response } = data.httpRequestLog;
return (

View File

@ -1,3 +1,4 @@
import { useRouter } from "next/router";
import { gql, useQuery } from "@apollo/client";
import { useState } from "react";
import { Box, Typography, CircularProgress } from "@material-ui/core";
@ -23,10 +24,17 @@ const HTTP_REQUEST_LOGS = gql`
`;
function LogsOverview(): JSX.Element {
const router = useRouter();
const detailReqLogId = router.query.id as string;
console.log(detailReqLogId);
const { loading, error, data } = useQuery(HTTP_REQUEST_LOGS);
const [detailReqLogId, setDetailReqLogId] = useState<string | null>(null);
const handleLogClick = (reqId: string) => setDetailReqLogId(reqId);
const handleLogClick = (reqId: string) => {
router.push("/proxy/logs?id=" + reqId, undefined, {
shallow: false,
});
};
if (loading) {
return <CircularProgress />;
@ -40,7 +48,11 @@ function LogsOverview(): JSX.Element {
return (
<div>
<Box mb={2}>
<RequestList logs={logs} onLogClick={handleLogClick} />
<RequestList
logs={logs}
selectedReqLogId={detailReqLogId}
onLogClick={handleLogClick}
/>
</Box>
<Box>
{detailReqLogId && <LogDetail requestId={detailReqLogId} />}

View File

@ -67,7 +67,11 @@ function RequestDetail({ request }: Props): JSX.Element {
</Typography>
<Typography className={classes.requestTitle} variant="h6">
{method} {decodeURIComponent(parsedUrl.pathname + parsedUrl.search)}{" "}
<Typography component="span" color="textSecondary">
<Typography
component="span"
color="textSecondary"
style={{ fontFamily: "'JetBrains Mono', monospace" }}
>
{proto}
</Typography>
</Typography>
@ -75,7 +79,9 @@ function RequestDetail({ request }: Props): JSX.Element {
<Divider />
<HttpHeadersTable headers={headers} />
<Box m={2}>
<HttpHeadersTable headers={headers} />
</Box>
{body && <Editor content={body} contentType={contentType} />}
</div>

View File

@ -6,23 +6,64 @@ import {
TableRow,
TableCell,
TableBody,
CircularProgress,
Typography,
Box,
createStyles,
makeStyles,
Theme,
withTheme,
} from "@material-ui/core";
import HttpStatusIcon from "./HttpStatusCode";
import CenteredPaper from "../CenteredPaper";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
requestTitle: {
width: "calc(100% - 80px)",
fontSize: "1rem",
wordBreak: "break-all",
whiteSpace: "pre-wrap",
},
headersTable: {
tableLayout: "fixed",
width: "100%",
},
headerKeyCell: {
verticalAlign: "top",
width: "30%",
fontWeight: "bold",
},
headerValueCell: {
width: "70%",
verticalAlign: "top",
wordBreak: "break-all",
whiteSpace: "pre-wrap",
},
})
);
interface Props {
logs: Array<any>;
selectedReqLogId?: string;
onLogClick(requestId: string): void;
theme: Theme;
}
function RequestList({ logs, onLogClick }: Props): JSX.Element {
function RequestList({
logs,
onLogClick,
selectedReqLogId,
theme,
}: Props): JSX.Element {
return (
<div>
<RequestListTable onLogClick={onLogClick} logs={logs} />
<RequestListTable
onLogClick={onLogClick}
logs={logs}
selectedReqLogId={selectedReqLogId}
theme={theme}
/>
{logs.length === 0 && (
<Box my={1}>
<CenteredPaper>
@ -36,12 +77,16 @@ function RequestList({ logs, onLogClick }: Props): JSX.Element {
interface RequestListTableProps {
logs?: any;
selectedReqLogId?: string;
onLogClick(requestId: string): void;
theme: Theme;
}
function RequestListTable({
logs,
selectedReqLogId,
onLogClick,
theme,
}: RequestListTableProps): JSX.Element {
return (
<TableContainer
@ -70,10 +115,21 @@ function RequestListTable({
textOverflow: "ellipsis",
} as any;
const rowStyle = {
backgroundColor:
id === selectedReqLogId
? theme.palette.action.selected
: "inherit",
};
return (
<TableRow key={id} onClick={() => onLogClick(id)}>
<TableRow
key={id}
style={rowStyle}
onClick={() => onLogClick(id)}
>
<TableCell style={{ ...cellStyle, width: "100px" }}>
{method}
<code>{method}</code>
</TableCell>
<TableCell style={{ ...cellStyle, maxWidth: "100px" }}>
{origin}
@ -85,7 +141,7 @@ function RequestListTable({
{response && (
<div>
<HttpStatusIcon status={response.statusCode} />{" "}
{response.status}
<code>{response.status}</code>
</div>
)}
</TableCell>
@ -98,4 +154,4 @@ function RequestListTable({
);
}
export default RequestList;
export default withTheme(RequestList);

View File

@ -34,7 +34,13 @@ function ResponseDetail({ response }: Props): JSX.Element {
>
<HttpStatusIcon status={response.statusCode} />{" "}
<Typography component="span" color="textSecondary">
{response.proto}
<Typography
component="span"
color="textSecondary"
style={{ fontFamily: "'JetBrains Mono', monospace" }}
>
{response.proto}
</Typography>
</Typography>{" "}
{response.status}
</Typography>
@ -42,7 +48,9 @@ function ResponseDetail({ response }: Props): JSX.Element {
<Divider />
<HttpHeadersTable headers={response.headers} />
<Box m={2}>
<HttpHeadersTable headers={response.headers} />
</Box>
{response.body && (
<Editor content={response.body} contentType={contentType} />