Add Sender module

This commit is contained in:
David Stotijn
2022-02-22 14:10:39 +01:00
parent afa211d0ec
commit efc20564c1
58 changed files with 9131 additions and 282 deletions

View File

@ -1,46 +0,0 @@
import MonacoEditor from "@monaco-editor/react";
import monaco from "monaco-editor/esm/vs/editor/editor.api";
const monacoOptions: monaco.editor.IEditorOptions = {
readOnly: true,
wordWrap: "on",
minimap: {
enabled: false,
},
};
type language = "html" | "typescript" | "json";
function languageForContentType(contentType?: string): language | undefined {
switch (contentType) {
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;
}
}
interface Props {
content: string;
contentType?: string;
}
function Editor({ content, contentType }: Props): JSX.Element {
return (
<MonacoEditor
height={"600px"}
language={languageForContentType(contentType)}
theme="vs-dark"
options={monacoOptions}
value={content}
/>
);
}
export default Editor;

View File

@ -1,25 +0,0 @@
import { SvgIconTypeMap } from "@mui/material";
import FiberManualRecordIcon from "@mui/icons-material/FiberManualRecord";
interface Props {
status: number;
}
export default function HttpStatusIcon({ status }: Props): JSX.Element {
let color: SvgIconTypeMap["props"]["color"] = "inherit";
switch (Math.floor(status / 100)) {
case 2:
case 3:
color = "primary";
break;
case 4:
color = "warning";
break;
case 5:
color = "error";
break;
}
return <FiberManualRecordIcon sx={{ marginTop: "-.25rem", verticalAlign: "middle" }} color={color} />;
}

View File

@ -5,7 +5,7 @@ import Alert from "@mui/lab/Alert";
import RequestList from "./RequestList";
import LogDetail from "./LogDetail";
import CenteredPaper from "../CenteredPaper";
import CenteredPaper from "../common/CenteredPaper";
import { useHttpRequestLogs } from "./hooks/useHttpRequestLogs";
function LogsOverview(): JSX.Element {

View File

@ -2,7 +2,7 @@ import React from "react";
import { Typography, Box, Divider } from "@mui/material";
import HttpHeadersTable from "./HttpHeadersTable";
import Editor from "./Editor";
import Editor from "../common/Editor";
interface Props {
request: {

View File

@ -9,11 +9,18 @@ import {
Typography,
Box,
useTheme,
MenuItem,
Snackbar,
Alert,
Link,
} from "@mui/material";
import HttpStatusIcon from "./HttpStatusCode";
import CenteredPaper from "../CenteredPaper";
import HttpStatusIcon from "../common/HttpStatusIcon";
import CenteredPaper from "../common/CenteredPaper";
import { RequestLog } from "../../lib/requestLogs";
import useContextMenu from "../common/useContextMenu";
import React, { useState } from "react";
import { useCreateSenderRequestFromHttpRequestLogMutation } from "../../generated/graphql";
interface Props {
logs: RequestLog[];
@ -45,69 +52,117 @@ interface RequestListTableProps {
function RequestListTable({ logs, selectedReqLogId, onLogClick }: RequestListTableProps): JSX.Element {
const theme = useTheme();
const [createSenderReqFromLog] = useCreateSenderRequestFromHttpRequestLogMutation({});
const [copyToSenderId, setCopyToSenderId] = useState("");
const [Menu, handleContextMenu, handleContextMenuClose] = useContextMenu();
const handleCopyToSenderClick = () => {
createSenderReqFromLog({
variables: {
id: copyToSenderId,
},
onCompleted({ createSenderRequestFromHttpRequestLog }) {
const { id } = createSenderRequestFromHttpRequestLog;
setNewSenderReqId(id);
setCopiedReqNotifOpen(true);
},
});
handleContextMenuClose();
};
const [newSenderReqId, setNewSenderReqId] = React.useState("");
const [copiedReqNotifOpen, setCopiedReqNotifOpen] = React.useState(false);
const handleCloseCopiedNotif = (_: Event | React.SyntheticEvent, reason?: string) => {
if (reason === "clickaway") {
return;
}
setCopiedReqNotifOpen(false);
};
return (
<TableContainer
component={Paper}
style={{
minHeight: logs.length ? 200 : 0,
height: logs.length ? "24vh" : "inherit",
}}
>
<Table stickyHeader size="small">
<TableHead>
<TableRow>
<TableCell>Method</TableCell>
<TableCell>Origin</TableCell>
<TableCell>Path</TableCell>
<TableCell>Status</TableCell>
</TableRow>
</TableHead>
<TableBody>
{logs.map(({ id, method, url, response }) => {
const { origin, pathname, search, hash } = new URL(url);
<div>
<Menu>
<MenuItem onClick={handleCopyToSenderClick}>Copy request to Sender</MenuItem>
</Menu>
<Snackbar
open={copiedReqNotifOpen}
autoHideDuration={3000}
onClose={handleCloseCopiedNotif}
anchorOrigin={{ horizontal: "center", vertical: "bottom" }}
>
<Alert onClose={handleCloseCopiedNotif} severity="info">
Request was copied. <Link href={`/sender?id=${newSenderReqId}`}>Edit in Sender.</Link>
</Alert>
</Snackbar>
const cellStyle = {
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
} as any;
<TableContainer
component={Paper}
style={{
minHeight: logs.length ? 200 : 0,
height: logs.length ? "24vh" : "inherit",
}}
>
<Table stickyHeader size="small">
<TableHead>
<TableRow>
<TableCell>Method</TableCell>
<TableCell>Origin</TableCell>
<TableCell>Path</TableCell>
<TableCell>Status</TableCell>
</TableRow>
</TableHead>
<TableBody>
{logs.map(({ id, method, url, response }) => {
const { origin, pathname, search, hash } = new URL(url);
return (
<TableRow
key={id}
sx={{
"&:hover": {
cursor: "pointer",
},
...(id === selectedReqLogId && {
bgcolor: theme.palette.action.selected,
}),
}}
hover
onClick={() => onLogClick(id)}
>
<TableCell style={{ ...cellStyle, width: "100px" }}>
<code>{method}</code>
</TableCell>
<TableCell sx={{ ...cellStyle, maxWidth: "100px" }}>{origin}</TableCell>
<TableCell sx={{ ...cellStyle, maxWidth: "200px" }}>
{decodeURIComponent(pathname + search + hash)}
</TableCell>
<TableCell style={{ maxWidth: "100px" }}>
{response && (
<div>
<HttpStatusIcon status={response.statusCode} />{" "}
<code>
{response.statusCode} {response.statusReason}
</code>
</div>
)}
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
const cellStyle = {
whiteSpace: "nowrap",
overflow: "hidden",
textOverflow: "ellipsis",
} as any;
return (
<TableRow
key={id}
sx={{
"&:hover": {
cursor: "pointer",
},
...(id === selectedReqLogId && {
bgcolor: theme.palette.action.selected,
}),
}}
hover
onClick={() => onLogClick(id)}
onContextMenu={(e) => {
setCopyToSenderId(id);
handleContextMenu(e);
}}
>
<TableCell style={{ ...cellStyle, width: "100px" }}>
<code>{method}</code>
</TableCell>
<TableCell sx={{ ...cellStyle, maxWidth: "100px" }}>{origin}</TableCell>
<TableCell sx={{ ...cellStyle, maxWidth: "200px" }}>
{decodeURIComponent(pathname + search + hash)}
</TableCell>
<TableCell style={{ maxWidth: "100px" }}>
{response && (
<div>
<HttpStatusIcon status={response.statusCode} />{" "}
<code>
{response.statusCode} {response.statusReason}
</code>
</div>
)}
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
</div>
);
}

View File

@ -1,7 +1,7 @@
import { Typography, Box, Divider } from "@mui/material";
import HttpStatusIcon from "./HttpStatusCode";
import Editor from "./Editor";
import HttpStatusIcon from "../common/HttpStatusIcon";
import Editor from "../common/Editor";
import HttpHeadersTable from "./HttpHeadersTable";
interface Props {

View File

@ -0,0 +1,13 @@
import { gql, useMutation } from "@apollo/client";
const CREATE_SENDER_REQUEST = gql`
mutation CreateSenderRequest($request: SenderRequestInput!) {
createSenderRequest(request: $request) {
id
}
}
`;
export default function useCreateSenderRequest() {
return useMutation(CREATE_SENDER_REQUEST);
}