Merge pull request #186 from openreplay/fetch-headers

Fetch headers
This commit is contained in:
Shekar Siri 2021-10-02 02:08:37 +05:30 committed by GitHub
commit c0841bc08e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 160 additions and 64 deletions

View file

@ -1,14 +1,14 @@
import { JSONTree, Label, Button, Tabs } from 'UI'
import { JSONTree, NoContent, Button, Tabs } from 'UI'
import cn from 'classnames';
import copy from 'copy-to-clipboard';
import stl from './fetchDetails.css';
import ResultTimings from '../../shared/ResultTimings/ResultTimings';
import Headers from './components/Headers'
const HEADERS = 'HEADERS';
const REQUEST = 'REQUEST';
const RESPONSE = 'RESPONSE';
const TIMINGS = 'TIMINGS';
const TABS = [ REQUEST, RESPONSE, TIMINGS ].map(tab => ({ text: tab, key: tab }));
const TABS = [ HEADERS, REQUEST, RESPONSE ].map(tab => ({ text: tab, key: tab }));
export default class FetchDetails extends React.PureComponent {
state = { activeTab: REQUEST, tabs: [] };
@ -20,53 +20,62 @@ export default class FetchDetails extends React.PureComponent {
}
renderActiveTab = tab => {
const { resource: { duration, timings }, isResult } = this.props;
const { resource: { payload, response = this.props.resource.body} } = this.props;
let jsonPayload, jsonResponse, requestHeaders, responseHeaders = undefined;
try {
jsonPayload = typeof payload === 'string' ? JSON.parse(payload) : payload
requestHeaders = jsonPayload.headers
delete jsonPayload.headers
} catch (e) {}
try {
jsonResponse = typeof response === 'string' ? JSON.parse(response) : response;
responseHeaders = jsonResponse.headers
delete jsonResponse.headers
} catch (e) {}
switch(tab) {
case REQUEST:
const { resource: { payload } } = this.props;
let jsonPayload = undefined;
try {
jsonPayload = typeof payload === 'string' ? JSON.parse(payload) : payload
} catch (e) {}
return !!payload ? (
<div>
<div className="mt-6">
{/* <h5>{ 'Payload '}</h5> */}
{ jsonPayload === undefined
? <div className="ml-3 break-words my-3"> { payload } </div>
: <JSONTree src={ jsonPayload } collapsed={ false } enableClipboard />
}
</div>
<div className="divider"/>
</div>
) : ''
break;
return (
<NoContent
title="Body is Empty."
size="small"
show={ !payload }
icon="exclamation-circle"
>
<div>
<div className="mt-6">
{ jsonPayload === undefined
? <div className="ml-3 break-words my-3"> { payload } </div>
: <JSONTree src={ jsonPayload } collapsed={ false } enableClipboard />
}
</div>
<div className="divider"/>
</div>
</NoContent>
)
case RESPONSE:
const { resource: { response = this.props.resource.body } } = this.props; // for IOS compat.
let jsonResponse = undefined;
try {
jsonResponse = JSON.parse(response);
} catch (e) {}
return !!response ? (
<div>
<div className="mt-6">
{/* <h5>{ 'Response '}</h5> */}
{ jsonResponse === undefined
? <div className="ml-3 break-words my-3"> { response } </div>
: <JSONTree src={ jsonResponse } collapsed={ false } enableClipboard />
}
</div>
<div className="divider"/>
</div>
// jsonResponse === undefined
// ? <div className="ml-3 break-words my-3"> { response } </div>
// : <JSONTree src={ jsonResponse } collapsed={ false } enableClipboard />
) : ''
break;
case TIMINGS:
return <ResultTimings duration={duration} timing={timings} />
return (
<NoContent
title="Body is Empty."
size="small"
show={ !response }
icon="exclamation-circle"
>
<div>
<div className="mt-6">
{ jsonResponse === undefined
? <div className="ml-3 break-words my-3"> { response } </div>
: <JSONTree src={ jsonResponse } collapsed={ false } enableClipboard />
}
</div>
<div className="divider"/>
</div>
</NoContent>
)
case HEADERS:
return <Headers requestHeaders={requestHeaders} responseHeaders={responseHeaders} />
}
}
@ -78,21 +87,18 @@ export default class FetchDetails extends React.PureComponent {
checkTabs() {
const { resource: { payload, response, body }, isResult } = this.props;
const _tabs = TABS.filter(t => {
if (t.key == REQUEST && !!payload) {
return true
}
const _tabs = TABS
// const _tabs = TABS.filter(t => {
// if (t.key == REQUEST && !!payload) {
// return true
// }
if (t.key == RESPONSE && !!response) {
return true;
}
// if (t.key == RESPONSE && !!response) {
// return true;
// }
if (t.key == TIMINGS && isResult) {
return true;
}
return false;
})
// return false;
// })
this.setState({ tabs: _tabs, activeTab: _tabs.length > 0 ? _tabs[0].key : null })
}

View file

@ -0,0 +1,49 @@
import React from 'react'
import { NoContent } from 'UI'
import stl from './headers.css'
function Headers(props) {
return (
<div>
<NoContent
title="No data available."
size="small"
show={ !props.requestHeaders && !props.responseHeaders }
icon="exclamation-circle"
>
{ props.requestHeaders && (
<>
<div className="mb-4 mt-4">
<div className="my-2 font-medium">Request Headers</div>
{
Object.keys(props.requestHeaders).map(h => (
<div className={stl.row}>
<div className="mr-2 font-medium">{h}:</div>
<div>{props.requestHeaders[h]}</div>
</div>
))
}
</div>
<hr />
</>
)}
{ props.responseHeaders && (
<div className="mt-4">
<div className="my-2 font-medium">Response Headers</div>
{
Object.keys(props.responseHeaders).map(h => (
<div className={stl.row}>
<div className="mr-2 font-medium">{h}:</div>
<div>{props.responseHeaders[h]}</div>
</div>
))
}
</div>
)}
</NoContent>
</div>
);
}
export default Headers;

View file

@ -0,0 +1,9 @@
.row {
display: flex;
padding: 5px 0px;
font-size: 13px;
/* padding-left: 20px; */
&:hover {
background-color: $active-blue;
}
}

View file

@ -0,0 +1 @@
export { default } from './Headers'

View file

@ -3,6 +3,7 @@ import { NoContent } from 'UI'
import { connectPlayer } from 'Player/store';
import SelectorCard from '../SelectorCard/SelectorCard';
import type { MarkedTarget } from 'Player/MessageDistributor/StatedScreen/StatedScreen';
import stl from './selectorList.css'
interface Props {
targets: Array<MarkedTarget>,
@ -16,9 +17,11 @@ function SelectorsList({ targets, activeTargetIndex }: Props) {
size="small"
show={ targets && targets.length === 0 }
>
{ targets && targets.map((target, index) => (
<SelectorCard target={target} index={index} showContent={activeTargetIndex === index} />
))}
<div className={stl.wrapper}>
{ targets && targets.map((target, index) => (
<SelectorCard target={target} index={index} showContent={activeTargetIndex === index} />
))}
</div>
</NoContent>
)
}

View file

@ -0,0 +1,28 @@
.wrapper {
height: calc(100vh - 190px);
overflow-y: auto;
&::-webkit-scrollbar {
width: 2px;
background: transparent !important;
background: rgba(0,0,0,0);
}
&::-webkit-scrollbar-thumb {
background: transparent !important;
}
&::-webkit-scrollbar-track {
background: transparent !important;
}
&:hover {
&::-webkit-scrollbar {
width: 2px;
background: rgba(0,0,0,0.1)
}
&::-webkit-scrollbar-track {
background: rgba(0,0,0,0.1)
}
&::-webkit-scrollbar-thumb {
background: rgba(0,0,0,0.1)
}
}
}