diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/App/App.module.scss | 35 | ||||
| -rw-r--r-- | src/components/App/App.tsx | 127 | ||||
| -rw-r--r-- | src/components/Content/Content.module.scss | 29 | ||||
| -rw-r--r-- | src/components/Content/Content.tsx | 50 | ||||
| -rw-r--r-- | src/components/Details/Details.module.scss | 66 | ||||
| -rw-r--r-- | src/components/Details/Details.tsx | 237 | ||||
| -rw-r--r-- | src/components/RequestSummary/RequestSummary.module.scss | 24 | ||||
| -rw-r--r-- | src/components/RequestSummary/RequestSummary.tsx | 1 | ||||
| -rw-r--r-- | src/hooks/useRequests.tsx | 12 | ||||
| -rw-r--r-- | src/index.scss | 10 |
10 files changed, 185 insertions, 406 deletions
diff --git a/src/components/App/App.module.scss b/src/components/App/App.module.scss index 9837cdf..088a4f6 100644 --- a/src/components/App/App.module.scss +++ b/src/components/App/App.module.scss | |||
| @@ -1,3 +1,34 @@ | |||
| 1 | .content { | 1 | .app { |
| 2 | flex: 1 0 auto; | 2 | display: flex; |
| 3 | flex-flow: column nowrap; | ||
| 4 | grid-template-rows: auto 1fr; | ||
| 5 | height: 100vh; | ||
| 6 | overflow: hidden; | ||
| 7 | } | ||
| 8 | |||
| 9 | .main { | ||
| 10 | display: flex; | ||
| 11 | flex-flow: row nowrap; | ||
| 12 | flex-grow: 1; | ||
| 13 | overflow: hidden; | ||
| 14 | } | ||
| 15 | |||
| 16 | .sidebar { | ||
| 17 | width: calc((6 / 16) * 100%); | ||
| 18 | height: 100%; | ||
| 19 | overflow-y: auto; | ||
| 20 | } | ||
| 21 | |||
| 22 | .details { | ||
| 23 | width: calc((10 / 16) * 100%); | ||
| 24 | overflow: hidden; | ||
| 25 | height: 100%; | ||
| 26 | } | ||
| 27 | |||
| 28 | .noRequest, .noRequestSelected { | ||
| 29 | width: 100%; | ||
| 30 | height: 100%; | ||
| 31 | display: flex; | ||
| 32 | justify-content: center; | ||
| 33 | align-items: center; | ||
| 3 | } | 34 | } |
diff --git a/src/components/App/App.tsx b/src/components/App/App.tsx index 61f88f6..cb82abc 100644 --- a/src/components/App/App.tsx +++ b/src/components/App/App.tsx | |||
| @@ -1,12 +1,15 @@ | |||
| 1 | import * as React from "react"; | 1 | import * as React from "react"; |
| 2 | import useRequests, {RequestResponse, ReadyState} from "../../hooks/useRequests"; | ||
| 3 | import {useEffect, useMemo, useState} from "react"; | 2 | import {useEffect, useMemo, useState} from "react"; |
| 3 | import useRequests, { | ||
| 4 | ReadyState, | ||
| 5 | RequestResponse | ||
| 6 | } from "../../hooks/useRequests"; | ||
| 4 | 7 | ||
| 5 | import styles from './App.module.scss'; | 8 | import styles from './App.module.scss'; |
| 6 | import Details from "../Details/Details"; | 9 | import Details from "../Details/Details"; |
| 7 | import RequestSummary from "../RequestSummary/RequestSummary"; | 10 | import RequestSummary from "../RequestSummary/RequestSummary"; |
| 8 | import {getHost} from "../../utils"; | 11 | import {getHost} from "../../utils"; |
| 9 | import {Container, Navbar, Col, Row, Nav, ListGroup} from "react-bootstrap"; | 12 | import {Container, ListGroup, Navbar} from "react-bootstrap"; |
| 10 | import classNames from "classnames"; | 13 | import classNames from "classnames"; |
| 11 | 14 | ||
| 12 | interface Config { | 15 | interface Config { |
| @@ -52,11 +55,12 @@ export default function App() { | |||
| 52 | ), [selectedRequestIndex, calls]); | 55 | ), [selectedRequestIndex, calls]); |
| 53 | 56 | ||
| 54 | return config && ( | 57 | return config && ( |
| 55 | <> | 58 | <div className={styles.app}> |
| 56 | <Navbar | 59 | <Navbar |
| 57 | bg="dark" | 60 | bg="dark" |
| 58 | variant="dark" | 61 | variant="dark" |
| 59 | expand | 62 | expand |
| 63 | as="header" | ||
| 60 | > | 64 | > |
| 61 | <Container fluid> | 65 | <Container fluid> |
| 62 | <Navbar.Brand> | 66 | <Navbar.Brand> |
| @@ -67,44 +71,45 @@ export default function App() { | |||
| 67 | </Navbar.Text> | 71 | </Navbar.Text> |
| 68 | </Container> | 72 | </Container> |
| 69 | </Navbar> | 73 | </Navbar> |
| 70 | <Container> | ||
| 71 | 74 | ||
| 72 | </Container> | 75 | <main className={styles.main}> |
| 73 | <Row className={classNames(styles.content, 'gx-0', 'overflow-hidden')}> | 76 | <ListGroup |
| 74 | <Col className='border-end overflow-auto' xs={4}> | 77 | variant='flush' |
| 75 | <ListGroup variant='flush'> | 78 | as="ul" |
| 76 | { | 79 | className={classNames("border-end", styles.sidebar)} |
| 77 | calls.length > 0 | 80 | > |
| 78 | ? ( | 81 | { |
| 79 | calls.slice(0).reverse().map((requestResponse, index) => { | 82 | calls.length > 0 |
| 80 | const selected = selectedRequestIndex === calls.length - index - 1; | 83 | ? ( |
| 81 | return ( | 84 | calls.slice(0).reverse().map((requestResponse, index) => { |
| 82 | <ListGroup.Item | 85 | const selected = selectedRequestIndex === calls.length - index - 1; |
| 83 | onClick={() => setSelectedRequestIndex(calls.length - index - 1)} | 86 | return ( |
| 84 | key={`request-${index}`} | 87 | <ListGroup.Item |
| 85 | className={classNames({ | 88 | as="li" |
| 86 | 'bg-primary': selected, | 89 | onClick={() => setSelectedRequestIndex(calls.length - index - 1)} |
| 87 | 'text-light': selected, | 90 | key={`request-${index}`} |
| 88 | 'border-bottom': true | 91 | className={classNames({ |
| 89 | })} | 92 | 'bg-primary': selected, |
| 90 | > | 93 | 'text-light': selected, |
| 91 | <RequestSummary | 94 | 'border-bottom': true |
| 92 | requestResponse={requestResponse} | 95 | })} |
| 93 | selected={selected} | 96 | > |
| 94 | /> | 97 | <RequestSummary |
| 95 | </ListGroup.Item> | 98 | requestResponse={requestResponse} |
| 96 | ) | 99 | selected={selected} |
| 97 | }) | 100 | /> |
| 98 | ) | 101 | </ListGroup.Item> |
| 99 | : ( | 102 | ) |
| 100 | <div className={styles.noRequest}> | 103 | }) |
| 101 | <p>No requests</p> | 104 | ) |
| 102 | </div> | 105 | : ( |
| 103 | ) | 106 | <div className={styles.noRequest}> |
| 104 | } | 107 | <p>No requests</p> |
| 105 | </ListGroup> | 108 | </div> |
| 106 | </Col> | 109 | ) |
| 107 | <Col xs={8} className=''> | 110 | } |
| 111 | </ListGroup> | ||
| 112 | <div className={styles.details}> | ||
| 108 | { | 113 | { |
| 109 | selectedRequest !== null | 114 | selectedRequest !== null |
| 110 | ? ( | 115 | ? ( |
| @@ -115,44 +120,8 @@ export default function App() { | |||
| 115 | </div> | 120 | </div> |
| 116 | ) | 121 | ) |
| 117 | } | 122 | } |
| 118 | </Col> | 123 | </div> |
| 119 | </Row> | 124 | </main> |
| 120 | </> | 125 | </div> |
| 121 | // <div className={styles.app}> | ||
| 122 | // <header className={styles.header}> | ||
| 123 | // {statusMap[readyState]} TTUN | ||
| 124 | // <a href={config.url} target="_blank">{config.url}</a> | ||
| 125 | // </header> | ||
| 126 | // <main className={styles.main}> | ||
| 127 | // <ul className={styles.sidebar}> | ||
| 128 | // { | ||
| 129 | // calls.length > 0 | ||
| 130 | // ? calls.slice(0).reverse().map((requestResponse, index) => ( | ||
| 131 | // <li onClick={() => setSelectedRequestIndex(calls.length - index - 1)} key={`request-${index}`}> | ||
| 132 | // <RequestSummary requestResponse={requestResponse} /> | ||
| 133 | // </li> | ||
| 134 | // )) | ||
| 135 | // : ( | ||
| 136 | // <div className={styles.noRequest}> | ||
| 137 | // <p>No requests</p> | ||
| 138 | // </div> | ||
| 139 | // ) | ||
| 140 | // } | ||
| 141 | // </ul> | ||
| 142 | // | ||
| 143 | // <div className={styles.details}> | ||
| 144 | // { | ||
| 145 | // selectedRequest !== null | ||
| 146 | // ? ( | ||
| 147 | // <Details requestResponse={selectedRequest} /> | ||
| 148 | // ) : ( | ||
| 149 | // <div className={styles.noRequestSelected}> | ||
| 150 | // <p>Select a request to inspect it</p> | ||
| 151 | // </div> | ||
| 152 | // ) | ||
| 153 | // } | ||
| 154 | // </div> | ||
| 155 | // </main> | ||
| 156 | // </div> | ||
| 157 | ); | 126 | ); |
| 158 | } | 127 | } |
diff --git a/src/components/Content/Content.module.scss b/src/components/Content/Content.module.scss index 8908516..4720afd 100644 --- a/src/components/Content/Content.module.scss +++ b/src/components/Content/Content.module.scss | |||
| @@ -6,33 +6,10 @@ | |||
| 6 | overflow: hidden; | 6 | overflow: hidden; |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | .header { | ||
| 10 | flex-shrink: 0; | ||
| 11 | flex-grow: 0; | ||
| 12 | width: 100%; | ||
| 13 | display: flex; | ||
| 14 | padding: 0.5em; | ||
| 15 | background-color: black; | ||
| 16 | color: white; | ||
| 17 | } | ||
| 18 | |||
| 19 | .body { | 9 | .body { |
| 20 | flex-grow: 1; | 10 | flex-grow: 1; |
| 21 | flex-shrink: 1; | 11 | flex-shrink: 1; |
| 22 | overflow-y: auto; | 12 | overflow-y: auto; |
| 23 | |||
| 24 | pre { | ||
| 25 | width: 100%; | ||
| 26 | height: 100%; | ||
| 27 | padding: 1em; | ||
| 28 | font-family: monospace; | ||
| 29 | overflow: auto; | ||
| 30 | } | ||
| 31 | |||
| 32 | iframe { | ||
| 33 | height: 100%; | ||
| 34 | width: 100%; | ||
| 35 | } | ||
| 36 | } | 13 | } |
| 37 | 14 | ||
| 38 | .renderError { | 15 | .renderError { |
| @@ -42,10 +19,4 @@ | |||
| 42 | flex-flow: column nowrap; | 19 | flex-flow: column nowrap; |
| 43 | justify-content: center; | 20 | justify-content: center; |
| 44 | align-items: center; | 21 | align-items: center; |
| 45 | |||
| 46 | a { | ||
| 47 | margin-top: 1em; | ||
| 48 | text-decoration: underline; | ||
| 49 | color: blue; | ||
| 50 | } | ||
| 51 | } | 22 | } |
diff --git a/src/components/Content/Content.tsx b/src/components/Content/Content.tsx index cb5e6bc..0e63f30 100644 --- a/src/components/Content/Content.tsx +++ b/src/components/Content/Content.tsx | |||
| @@ -1,19 +1,9 @@ | |||
| 1 | import styles from "~components/Details/Details.module.scss"; | ||
| 2 | import * as React from "react"; | 1 | import * as React from "react"; |
| 3 | import classNames from "classnames"; | 2 | import {Dispatch, SetStateAction, useMemo} from "react"; |
| 4 | import {RequestPayload, ResponsePayload} from "~hooks/useRequests"; | 3 | import {RequestPayload, ResponsePayload} from "~hooks/useRequests"; |
| 5 | import { | ||
| 6 | Dispatch, | ||
| 7 | forwardRef, SetStateAction, | ||
| 8 | useEffect, | ||
| 9 | useImperativeHandle, | ||
| 10 | useMemo, | ||
| 11 | useRef, | ||
| 12 | useState | ||
| 13 | } from "react"; | ||
| 14 | import ReactJson from 'react-json-view'; | 4 | import ReactJson from 'react-json-view'; |
| 15 | import styles from './Content.module.scss'; | 5 | import styles from './Content.module.scss'; |
| 16 | import {Col, Container, Row} from "react-bootstrap"; | 6 | import {Button, Col, Container, Row} from "react-bootstrap"; |
| 17 | 7 | ||
| 18 | function getHeader(headers: { [key: string]: string }, key: string, unit?: string): string | null { | 8 | function getHeader(headers: { [key: string]: string }, key: string, unit?: string): string | null { |
| 19 | console.log(headers, key) | 9 | console.log(headers, key) |
| @@ -37,7 +27,7 @@ interface ContentProps { | |||
| 37 | 27 | ||
| 38 | export default function Content({ raw, setRaw, data }: ContentProps): JSX.Element { | 28 | export default function Content({ raw, setRaw, data }: ContentProps): JSX.Element { |
| 39 | return ( | 29 | return ( |
| 40 | <> | 30 | <div className={styles.content}> |
| 41 | <Container fluid className="border-bottom"> | 31 | <Container fluid className="border-bottom"> |
| 42 | <Row className="py-3"> | 32 | <Row className="py-3"> |
| 43 | <Col> | 33 | <Col> |
| @@ -54,7 +44,7 @@ export default function Content({ raw, setRaw, data }: ContentProps): JSX.Elemen | |||
| 54 | </Col> | 44 | </Col> |
| 55 | </Row> | 45 | </Row> |
| 56 | </Container> | 46 | </Container> |
| 57 | <Row> | 47 | <Row className={styles.body}> |
| 58 | {(() => { | 48 | {(() => { |
| 59 | try { | 49 | try { |
| 60 | return ContentBody({ data, raw }) | 50 | return ContentBody({ data, raw }) |
| @@ -62,33 +52,13 @@ export default function Content({ raw, setRaw, data }: ContentProps): JSX.Elemen | |||
| 62 | return ( | 52 | return ( |
| 63 | <div className={styles.renderError}> | 53 | <div className={styles.renderError}> |
| 64 | <p>Body could not be rendered</p> | 54 | <p>Body could not be rendered</p> |
| 65 | <a onClick={() => setRaw(true)}>View raw</a> | 55 | <Button variant="link" onClick={() => setRaw(true)}>View raw</Button> |
| 66 | </div> | 56 | </div> |
| 67 | ) | 57 | ) |
| 68 | } | 58 | } |
| 69 | })()} | 59 | })()} |
| 70 | </Row> | 60 | </Row> |
| 71 | </> | 61 | </div > |
| 72 | // <div className={styles.content}> | ||
| 73 | // <div className={styles.header}> | ||
| 74 | // <input id='raw' type='checkbox' checked={raw} onChange={() => setRaw(!raw)}/> | ||
| 75 | // <label htmlFor='raw'>Raw</label> | ||
| 76 | // </div> | ||
| 77 | // <div className={styles.body}> | ||
| 78 | // {(() => { | ||
| 79 | // try { | ||
| 80 | // return ContentBody({ ...props, raw }) | ||
| 81 | // } catch { | ||
| 82 | // return ( | ||
| 83 | // <div className={styles.renderError}> | ||
| 84 | // <p>Body could not be rendered</p> | ||
| 85 | // <a onClick={() => setRaw(true)}>View raw</a> | ||
| 86 | // </div> | ||
| 87 | // ) | ||
| 88 | // } | ||
| 89 | // })()} | ||
| 90 | // </div> | ||
| 91 | // </div> | ||
| 92 | ) | 62 | ) |
| 93 | }; | 63 | }; |
| 94 | 64 | ||
| @@ -103,7 +73,13 @@ function ContentBody({ data, raw = false }: Omit<ContentProps, 'setRaw'>) { | |||
| 103 | }, [data, raw]); | 73 | }, [data, raw]); |
| 104 | 74 | ||
| 105 | if (raw) { | 75 | if (raw) { |
| 106 | return <pre>{atob(data.body)}</pre> | 76 | return ( |
| 77 | <pre className="mb-0"> | ||
| 78 | <code> | ||
| 79 | {atob(data.body)} | ||
| 80 | </code> | ||
| 81 | </pre> | ||
| 82 | ) | ||
| 107 | } | 83 | } |
| 108 | 84 | ||
| 109 | if (['application/pdf', 'text/html'].includes(contentType)) { | 85 | if (['application/pdf', 'text/html'].includes(contentType)) { |
diff --git a/src/components/Details/Details.module.scss b/src/components/Details/Details.module.scss index 32197f0..146b5d8 100644 --- a/src/components/Details/Details.module.scss +++ b/src/components/Details/Details.module.scss | |||
| @@ -16,69 +16,3 @@ | |||
| 16 | flex-shrink: 1; | 16 | flex-shrink: 1; |
| 17 | overflow-y: auto; | 17 | overflow-y: auto; |
| 18 | } | 18 | } |
| 19 | |||
| 20 | .summary { | ||
| 21 | font-size: 2em; | ||
| 22 | } | ||
| 23 | |||
| 24 | .tabs { | ||
| 25 | display: flex; | ||
| 26 | border-bottom: 1px solid black; | ||
| 27 | |||
| 28 | &:last-child { | ||
| 29 | flex-grow: 1; | ||
| 30 | } | ||
| 31 | } | ||
| 32 | |||
| 33 | .tab { | ||
| 34 | background-color: white; | ||
| 35 | border: none; | ||
| 36 | border-top: 1px solid black; | ||
| 37 | border-right: 1px solid black; | ||
| 38 | border-radius: 0; | ||
| 39 | color: black; | ||
| 40 | font-size: 1.2em; | ||
| 41 | padding: 0.5em; | ||
| 42 | |||
| 43 | &.selected { | ||
| 44 | background-color: black; | ||
| 45 | color: white; | ||
| 46 | } | ||
| 47 | } | ||
| 48 | |||
| 49 | .emptySpace { | ||
| 50 | flex-grow: 1; | ||
| 51 | display: flex; | ||
| 52 | justify-content: flex-end; | ||
| 53 | align-items: center; | ||
| 54 | font-size: 1.2em; | ||
| 55 | padding: 0.5em; | ||
| 56 | } | ||
| 57 | |||
| 58 | .resend { | ||
| 59 | margin-left: 1em; | ||
| 60 | } | ||
| 61 | |||
| 62 | .headers { | ||
| 63 | display: grid; | ||
| 64 | grid-template-columns: auto 1fr; | ||
| 65 | border: 1px solid black; | ||
| 66 | margin: 1em; | ||
| 67 | overflow-x: auto; | ||
| 68 | |||
| 69 | h2 { | ||
| 70 | grid-column: 1/ span 2; | ||
| 71 | background-color: black; | ||
| 72 | color: white; | ||
| 73 | padding: 0.5em; | ||
| 74 | } | ||
| 75 | |||
| 76 | > div { | ||
| 77 | line-break: auto; | ||
| 78 | padding: 0.5em; | ||
| 79 | |||
| 80 | &:nth-of-type(4n), &:nth-of-type(4n - 1) { | ||
| 81 | background-color: lightgray; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
diff --git a/src/components/Details/Details.tsx b/src/components/Details/Details.tsx index c96aa7b..d4bb07a 100644 --- a/src/components/Details/Details.tsx +++ b/src/components/Details/Details.tsx | |||
| @@ -1,25 +1,11 @@ | |||
| 1 | import * as React from "react"; | 1 | import * as React from "react"; |
| 2 | import { | 2 | import {useCallback, useMemo, useState} from "react"; |
| 3 | RequestPayload, | 3 | import {RequestResponse} from "~hooks/useRequests"; |
| 4 | RequestResponse, | ||
| 5 | ResponsePayload | ||
| 6 | } from "~hooks/useRequests"; | ||
| 7 | import {useCallback, useEffect, useMemo, useState} from "react"; | ||
| 8 | import styles from "./Details.module.scss"; | 4 | import styles from "./Details.module.scss"; |
| 9 | import RequestSummary from "../RequestSummary/RequestSummary"; | 5 | import RequestSummary from "../RequestSummary/RequestSummary"; |
| 10 | import classNames from 'classnames'; | ||
| 11 | import Content from "../Content/Content"; | 6 | import Content from "../Content/Content"; |
| 12 | import {getHost} from "../../utils"; | 7 | import {getHost} from "../../utils"; |
| 13 | import { | 8 | import {Button, Card, Col, Container, Nav, Row, Table} from "react-bootstrap"; |
| 14 | Button, | ||
| 15 | Card, | ||
| 16 | Col, | ||
| 17 | Container, | ||
| 18 | Nav, | ||
| 19 | NavItem, | ||
| 20 | Row, | ||
| 21 | Table | ||
| 22 | } from "react-bootstrap"; | ||
| 23 | 9 | ||
| 24 | 10 | ||
| 25 | interface TimingProps { | 11 | interface TimingProps { |
| @@ -99,147 +85,80 @@ export default function Details({ requestResponse }: DetailsProps) { | |||
| 99 | ), [requestResponse]); | 85 | ), [requestResponse]); |
| 100 | 86 | ||
| 101 | return ( | 87 | return ( |
| 102 | <> | 88 | <div className={styles.details}> |
| 103 | <Row> | 89 | <div className={styles.header}> |
| 104 | <Col> | 90 | <Row> |
| 105 | <Container fluid style={{ fontSize: '1.5em' }} className="py-3"> | 91 | <Col> |
| 106 | <RequestSummary requestResponse={requestResponse} className={styles.summary}/> | 92 | <Container fluid style={{ fontSize: '1.5em' }} className="py-3"> |
| 107 | </Container> | 93 | <RequestSummary requestResponse={requestResponse} className={styles.summary}/> |
| 108 | </Col> | 94 | </Container> |
| 109 | </Row> | 95 | </Col> |
| 110 | <Row className="gx-0 d-flex"> | 96 | </Row> |
| 111 | <Col> | 97 | <Row className="gx-0 d-flex"> |
| 112 | <Nav | 98 | <Col> |
| 113 | variant="tabs" | 99 | <Nav |
| 114 | activeKey={tab} | 100 | variant="tabs" |
| 115 | onSelect={(tab) => selectTab(tab as Tab)} | 101 | activeKey={tab} |
| 116 | > | 102 | onSelect={(tab) => selectTab(tab as Tab)} |
| 117 | <Nav.Item> | 103 | > |
| 118 | <Nav.Link eventKey="headers"> | 104 | <Nav.Item> |
| 119 | Headers | 105 | <Nav.Link eventKey="headers"> |
| 120 | </Nav.Link > | 106 | Headers |
| 121 | </Nav.Item> | 107 | </Nav.Link > |
| 122 | <Nav.Item> | 108 | </Nav.Item> |
| 123 | <Nav.Link eventKey="request"> | 109 | <Nav.Item> |
| 124 | Request | 110 | <Nav.Link eventKey="request"> |
| 125 | </Nav.Link> | 111 | Request |
| 126 | </Nav.Item> | 112 | </Nav.Link> |
| 127 | <Nav.Item> | 113 | </Nav.Item> |
| 128 | <Nav.Link | 114 | <Nav.Item> |
| 129 | eventKey="response" | 115 | <Nav.Link |
| 130 | disabled={requestResponse.response === undefined} | 116 | eventKey="response" |
| 131 | > | 117 | disabled={requestResponse.response === undefined} |
| 132 | Response | 118 | > |
| 133 | </Nav.Link> | 119 | Response |
| 134 | </Nav.Item> | 120 | </Nav.Link> |
| 135 | </Nav> | 121 | </Nav.Item> |
| 136 | </Col> | 122 | </Nav> |
| 137 | <Col className="border-bottom px-3 " xs="auto"> | 123 | </Col> |
| 138 | <Timing timing={requestResponse.response?.timing ?? NaN} /> | 124 | <Col className="border-bottom px-3 " xs="auto"> |
| 139 | <Button variant="outline-primary" onClick={() => resend()} className="ms-3"> | 125 | <Timing timing={requestResponse.response?.timing ?? NaN} /> |
| 140 | Resend | 126 | <Button variant="outline-primary" onClick={() => resend()} className="ms-3"> |
| 141 | </Button> | 127 | Resend |
| 142 | </Col> | 128 | </Button> |
| 143 | </Row> | 129 | </Col> |
| 144 | <Row> | 130 | </Row> |
| 145 | <Col> | 131 | </div> |
| 146 | { | 132 | <div className={styles.content}> |
| 147 | tab === 'headers' && ( | 133 | { |
| 148 | <> | 134 | tab === 'headers' && ( |
| 149 | <Headers | 135 | <> |
| 150 | title="Request Headers" | 136 | <Headers |
| 151 | headers={requestResponse.request.headers} | 137 | title="request headers" |
| 152 | /> | 138 | headers={requestResponse.request.headers} |
| 153 | { | 139 | /> |
| 154 | requestResponse.response && ( | 140 | { |
| 155 | <Headers | 141 | requestResponse.response && ( |
| 156 | title="Response Headers" | 142 | <Headers |
| 157 | headers={requestResponse.response.headers} | 143 | title="response headers" |
| 158 | /> | 144 | headers={requestResponse.response.headers} |
| 159 | ) | 145 | /> |
| 160 | } | 146 | ) |
| 161 | </> | 147 | } |
| 162 | ) | 148 | </> |
| 163 | } | 149 | ) |
| 164 | { | 150 | } |
| 165 | tab === 'request' && ( | 151 | { |
| 166 | <Content data={requestResponse.request} raw={raw} setRaw={setRaw}/> | 152 | tab === 'request' && ( |
| 167 | ) | 153 | <Content data={requestResponse.request} raw={raw} setRaw={setRaw}/> |
| 168 | } | 154 | ) |
| 169 | { | 155 | } |
| 170 | tab === 'response' && requestResponse.response !== undefined && ( | 156 | { |
| 171 | <Content data={requestResponse.response} raw={raw} setRaw={setRaw}/> | 157 | tab === 'response' && requestResponse.response !== undefined && ( |
| 172 | ) | 158 | <Content data={requestResponse.response} raw={raw} setRaw={setRaw}/> |
| 173 | } | 159 | ) |
| 174 | </Col> | 160 | } |
| 175 | </Row> | 161 | </div> |
| 176 | </> | 162 | </div> |
| 177 | // <div className={styles.details}> | ||
| 178 | // <div className={styles.header}> | ||
| 179 | // | ||
| 180 | // <div className={styles.tabs}> | ||
| 181 | // <button | ||
| 182 | // onClick={() => selectTab('headers')} | ||
| 183 | // className={classNames(styles.tab, { | ||
| 184 | // [styles.selected]: tab === 'headers' | ||
| 185 | // })} | ||
| 186 | // > | ||
| 187 | // Headers | ||
| 188 | // </button> | ||
| 189 | // <button | ||
| 190 | // onClick={() => selectTab('request')} | ||
| 191 | // className={classNames(styles.tab, { | ||
| 192 | // [styles.selected]: tab === 'request' | ||
| 193 | // })} | ||
| 194 | // > | ||
| 195 | // Request | ||
| 196 | // </button> | ||
| 197 | // <button | ||
| 198 | // onClick={() => selectTab('response')} | ||
| 199 | // className={classNames(styles.tab, { | ||
| 200 | // [styles.selected]: tab === 'response' | ||
| 201 | // })} | ||
| 202 | // disabled={requestResponse.response === undefined} | ||
| 203 | // > | ||
| 204 | // Response | ||
| 205 | // </button> | ||
| 206 | // | ||
| 207 | // <div className={styles.emptySpace}> | ||
| 208 | // <Timing timing={requestResponse.response?.timing ?? NaN} /> | ||
| 209 | // <button className={styles.resend} onClick={() => resend()}>Resend</button> | ||
| 210 | // </div> | ||
| 211 | // </div> | ||
| 212 | // </div> | ||
| 213 | // <div className={styles.content}> | ||
| 214 | // { | ||
| 215 | // tab === 'headers' && ( | ||
| 216 | // <> | ||
| 217 | // <Headers | ||
| 218 | // title="Request Headers" | ||
| 219 | // headers={requestResponse.request.headers} | ||
| 220 | // /> | ||
| 221 | // { | ||
| 222 | // requestResponse.response && ( | ||
| 223 | // <Headers | ||
| 224 | // title="Response Headers" | ||
| 225 | // headers={requestResponse.response.headers} | ||
| 226 | // /> | ||
| 227 | // ) | ||
| 228 | // } | ||
| 229 | // </> | ||
| 230 | // ) | ||
| 231 | // } | ||
| 232 | // { | ||
| 233 | // tab === 'request' && ( | ||
| 234 | // <Content data={requestResponse.request} raw={raw} setRaw={setRaw}/> | ||
| 235 | // ) | ||
| 236 | // } | ||
| 237 | // { | ||
| 238 | // tab === 'response' && requestResponse.response !== undefined && ( | ||
| 239 | // <Content data={requestResponse.response} raw={raw} setRaw={setRaw}/> | ||
| 240 | // ) | ||
| 241 | // } | ||
| 242 | // </div> | ||
| 243 | // </div> | ||
| 244 | ) | 163 | ) |
| 245 | } | 164 | } |
diff --git a/src/components/RequestSummary/RequestSummary.module.scss b/src/components/RequestSummary/RequestSummary.module.scss deleted file mode 100644 index e1752b3..0000000 --- a/src/components/RequestSummary/RequestSummary.module.scss +++ /dev/null | |||
| @@ -1,24 +0,0 @@ | |||
| 1 | .requestSummary { | ||
| 2 | display: grid; | ||
| 3 | grid-template-columns: auto 1fr auto; | ||
| 4 | padding: 1em; | ||
| 5 | grid-gap: 1em; | ||
| 6 | align-items: center; | ||
| 7 | } | ||
| 8 | |||
| 9 | .method { | ||
| 10 | } | ||
| 11 | |||
| 12 | .statusCode { | ||
| 13 | padding: 0.2em; | ||
| 14 | border-radius: 0.4em; | ||
| 15 | background-color: darkgray; | ||
| 16 | |||
| 17 | &.info, &.success, &.redirect { | ||
| 18 | background-color: forestgreen; | ||
| 19 | } | ||
| 20 | |||
| 21 | &.clientError, &.serverError { | ||
| 22 | background-color: red; | ||
| 23 | } | ||
| 24 | } | ||
diff --git a/src/components/RequestSummary/RequestSummary.tsx b/src/components/RequestSummary/RequestSummary.tsx index ea28f3e..b3e7ddc 100644 --- a/src/components/RequestSummary/RequestSummary.tsx +++ b/src/components/RequestSummary/RequestSummary.tsx | |||
| @@ -2,7 +2,6 @@ import {RequestResponse} from "~hooks/useRequests"; | |||
| 2 | import * as React from "react"; | 2 | import * as React from "react"; |
| 3 | import classNames from "classnames"; | 3 | import classNames from "classnames"; |
| 4 | 4 | ||
| 5 | import styles from './RequestSummary.module.scss'; | ||
| 6 | import {Badge, Card, Col, Row} from "react-bootstrap"; | 5 | import {Badge, Card, Col, Row} from "react-bootstrap"; |
| 7 | 6 | ||
| 8 | interface RequestSummaryProps { | 7 | interface RequestSummaryProps { |
diff --git a/src/hooks/useRequests.tsx b/src/hooks/useRequests.tsx index 2b8393e..5ac70a4 100644 --- a/src/hooks/useRequests.tsx +++ b/src/hooks/useRequests.tsx | |||
| @@ -62,6 +62,7 @@ export interface UseRequests { | |||
| 62 | export default function useRequests({ onConnect }: useRequestsProps): UseRequests { | 62 | export default function useRequests({ onConnect }: useRequestsProps): UseRequests { |
| 63 | const wsHost = useMemo(getHost, []); | 63 | const wsHost = useMemo(getHost, []); |
| 64 | 64 | ||
| 65 | const [initialConnection, setInitialConnection] = useState(true); | ||
| 65 | const [requests, setRequests] = useState<RequestPayload[]>([]); | 66 | const [requests, setRequests] = useState<RequestPayload[]>([]); |
| 66 | const [responses, setResponses] = useState<ResponsePayload[]>([]); | 67 | const [responses, setResponses] = useState<ResponsePayload[]>([]); |
| 67 | 68 | ||
| @@ -82,6 +83,7 @@ export default function useRequests({ onConnect }: useRequestsProps): UseRequest | |||
| 82 | } | 83 | } |
| 83 | const onOpen = () => { | 84 | const onOpen = () => { |
| 84 | onConnect(); | 85 | onConnect(); |
| 86 | setInitialConnection(false); | ||
| 85 | setReadyState(ws.readyState); | 87 | setReadyState(ws.readyState); |
| 86 | } | 88 | } |
| 87 | const onMessage = ({ data }) => { | 89 | const onMessage = ({ data }) => { |
| @@ -89,10 +91,12 @@ export default function useRequests({ onConnect }: useRequestsProps): UseRequest | |||
| 89 | 91 | ||
| 90 | switch (type) { | 92 | switch (type) { |
| 91 | case 'historic': | 93 | case 'historic': |
| 92 | const requests = (payload as (Request | Response)[]).filter(({ type }) => type === 'request'); | 94 | if (initialConnection) { |
| 93 | const responses = (payload as (Request | Response)[]).filter(({ type }) => type === 'response'); | 95 | const requests = (payload as (Request | Response)[]).filter(({ type }) => type === 'request'); |
| 94 | setRequests((rqs) => [...rqs, ...requests.map(({ payload }) => payload as RequestPayload)]); | 96 | const responses = (payload as (Request | Response)[]).filter(({ type }) => type === 'response'); |
| 95 | setResponses((rps) => [...rps, ...responses.map(({ payload }) => payload as ResponsePayload)]); | 97 | setRequests((rqs) => [...rqs, ...requests.map(({ payload }) => payload as RequestPayload)]); |
| 98 | setResponses((rps) => [...rps, ...responses.map(({ payload }) => payload as ResponsePayload)]); | ||
| 99 | } | ||
| 96 | break | 100 | break |
| 97 | case 'request': | 101 | case 'request': |
| 98 | setRequests((rqs) => [...rqs, payload as RequestPayload]) | 102 | setRequests((rqs) => [...rqs, payload as RequestPayload]) |
diff --git a/src/index.scss b/src/index.scss index 3d8dd7a..13d82ca 100644 --- a/src/index.scss +++ b/src/index.scss | |||
| @@ -3,12 +3,12 @@ | |||
| 3 | } | 3 | } |
| 4 | 4 | ||
| 5 | html, body, #root { | 5 | html, body, #root { |
| 6 | margin: 0; | ||
| 7 | padding: 0; | ||
| 8 | |||
| 6 | height: 100vh; | 9 | height: 100vh; |
| 7 | width: 100vw; | 10 | width: 100vw; |
| 8 | 11 | ||
| 9 | } | 12 | font-family: sans-serif; |
| 10 | 13 | overflow: hidden; | |
| 11 | #root { | ||
| 12 | display: flex; | ||
| 13 | flex-flow: column nowrap; | ||
| 14 | } | 14 | } |
