Tidy up proxy logs, add copy action for headers

This commit is contained in:
David Stotijn
2020-09-27 18:59:38 +02:00
parent 854839daf8
commit ab90bfe4e9
11 changed files with 140 additions and 78 deletions

View File

@ -7,7 +7,10 @@ import {
TableCell,
TableContainer,
TableRow,
Snackbar,
} from "@material-ui/core";
import { Alert } from "@material-ui/lab";
import React, { useState } from "react";
const useStyles = makeStyles((theme: Theme) => {
const paddingX = 0;
@ -19,23 +22,35 @@ const useStyles = makeStyles((theme: Theme) => {
paddingBottom: paddingY,
verticalAlign: "top",
border: "none",
whiteSpace: "nowrap" as any,
overflow: "hidden",
textOverflow: "ellipsis",
"&:hover": {
color: theme.palette.secondary.main,
whiteSpace: "inherit" as any,
overflow: "inherit",
textOverflow: "inherit",
cursor: "copy",
},
};
return createStyles({
root: {},
table: {
tableLayout: "fixed",
width: "100%",
},
keyCell: {
...tableCell,
paddingRight: theme.spacing(1),
width: "40%",
fontWeight: "bold",
fontSize: ".75rem",
},
valueCell: {
...tableCell,
width: "60%",
border: "none",
wordBreak: "break-all",
whiteSpace: "pre-wrap",
fontSize: ".75rem",
},
});
});
@ -46,23 +61,59 @@ interface Props {
function HttpHeadersTable({ headers }: Props): JSX.Element {
const classes = useStyles();
const [open, setOpen] = useState(false);
const handleClick = (e: React.MouseEvent) => {
e.preventDefault();
const r = document.createRange();
r.selectNode(e.currentTarget);
window.getSelection().removeAllRanges();
window.getSelection().addRange(r);
document.execCommand("copy");
window.getSelection().removeAllRanges();
setOpen(true);
};
const handleClose = (event?: React.SyntheticEvent, reason?: string) => {
if (reason === "clickaway") {
return;
}
setOpen(false);
};
return (
<TableContainer>
<Table className={classes.table} size="small">
<TableBody>
{headers.map(({ key, value }, index) => (
<TableRow key={index}>
<TableCell component="th" scope="row" className={classes.keyCell}>
<code>{key}:</code>
</TableCell>
<TableCell className={classes.valueCell}>
<code>{value}</code>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
<div>
<Snackbar open={open} autoHideDuration={3000} onClose={handleClose}>
<Alert onClose={handleClose} severity="info">
Copied to clipboard.
</Alert>
</Snackbar>
<TableContainer className={classes.root}>
<Table className={classes.table} size="small">
<TableBody>
{headers.map(({ key, value }, index) => (
<TableRow key={index}>
<TableCell
component="th"
scope="row"
className={classes.keyCell}
onClick={handleClick}
>
<code>{key}:</code>
</TableCell>
<TableCell className={classes.valueCell} onClick={handleClick}>
<code>{value}</code>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</div>
);
}

View File

@ -1,19 +1,31 @@
import { green, orange, red } from "@material-ui/core/colors";
import { Theme, withTheme } from "@material-ui/core";
import { orange, red } from "@material-ui/core/colors";
import FiberManualRecordIcon from "@material-ui/icons/FiberManualRecord";
function HttpStatusIcon({ status }: { status: number }): JSX.Element {
interface Props {
status: number;
theme: Theme;
}
function HttpStatusIcon({ status, theme }: Props): JSX.Element {
const style = { marginTop: "-.25rem", verticalAlign: "middle" };
switch (Math.floor(status / 100)) {
case 2:
case 3:
return <FiberManualRecordIcon style={{ ...style, color: green[400] }} />;
return (
<FiberManualRecordIcon
style={{ ...style, color: theme.palette.secondary.main }}
/>
);
case 4:
return <FiberManualRecordIcon style={{ ...style, color: orange[400] }} />;
return (
<FiberManualRecordIcon style={{ ...style, color: orange["A400"] }} />
);
case 5:
return <FiberManualRecordIcon style={{ ...style, color: red[400] }} />;
return <FiberManualRecordIcon style={{ ...style, color: red["A400"] }} />;
default:
return <FiberManualRecordIcon style={style} />;
}
}
export default HttpStatusIcon;
export default withTheme(HttpStatusIcon);

View File

@ -65,13 +65,13 @@ function LogDetail({ requestId: id }: Props): JSX.Element {
<div>
<Grid container item spacing={2}>
<Grid item xs={6}>
<Box component={Paper} maxHeight="62vh" overflow="scroll">
<Box component={Paper}>
<RequestDetail request={{ method, url, proto, headers, body }} />
</Box>
</Grid>
<Grid item xs={6}>
{response && (
<Box component={Paper} maxHeight="62vh" overflow="scroll">
<Box component={Paper}>
<ResponseDetail response={response} />
</Box>
)}

View File

@ -57,7 +57,7 @@ function RequestDetail({ request }: Props): JSX.Element {
return (
<div>
<Box mx={2} my={2}>
<Box p={2}>
<Typography
variant="overline"
color="textSecondary"
@ -79,7 +79,7 @@ function RequestDetail({ request }: Props): JSX.Element {
<Divider />
<Box m={2}>
<Box p={2}>
<HttpHeadersTable headers={headers} />
</Box>

View File

@ -19,27 +19,13 @@ 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",
row: {
"&:hover": {
cursor: "pointer",
},
},
/* Pseudo-class applied to the root element if `hover={true}`. */
hover: {},
})
);
@ -88,6 +74,7 @@ function RequestListTable({
onLogClick,
theme,
}: RequestListTableProps): JSX.Element {
const classes = useStyles();
return (
<TableContainer
component={Paper}
@ -117,15 +104,15 @@ function RequestListTable({
const rowStyle = {
backgroundColor:
id === selectedReqLogId
? theme.palette.action.selected
: "inherit",
id === selectedReqLogId && theme.palette.action.selected,
};
return (
<TableRow
key={id}
className={classes.row}
style={rowStyle}
hover
onClick={() => onLogClick(id)}
>
<TableCell style={{ ...cellStyle, width: "100px" }}>

View File

@ -20,7 +20,7 @@ function ResponseDetail({ response }: Props): JSX.Element {
)?.value;
return (
<div>
<Box mx={2} my={2}>
<Box p={2}>
<Typography
variant="overline"
color="textSecondary"
@ -48,7 +48,7 @@ function ResponseDetail({ response }: Props): JSX.Element {
<Divider />
<Box m={2}>
<Box p={2}>
<HttpHeadersTable headers={response.headers} />
</Box>