Search full request details
Summary: Simple implementation of searching through request/response body on "network" tab Reviewed By: passy Differential Revision: D18268026 fbshipit-source-id: 39386d2d6ec50b47c3ca3dec976821282b51636f
This commit is contained in:
committed by
Facebook Github Bot
parent
691a4ee135
commit
faaf8c4f32
@@ -283,8 +283,11 @@ ${request.headers
|
||||
)
|
||||
.join('\n')}`;
|
||||
|
||||
if (request.data) {
|
||||
copyText += `\n\n${decodeBody(request)}`;
|
||||
const requestData = request.data ? decodeBody(request) : null;
|
||||
const responseData = response && response.data ? decodeBody(response) : null;
|
||||
|
||||
if (requestData) {
|
||||
copyText += `\n\n${requestData}`;
|
||||
}
|
||||
|
||||
if (response) {
|
||||
@@ -300,8 +303,8 @@ ${response.headers
|
||||
.join('\n')}`;
|
||||
}
|
||||
|
||||
if (response) {
|
||||
copyText += `\n\n${decodeBody(response)}`;
|
||||
if (responseData) {
|
||||
copyText += `\n\n${responseData}`;
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -346,6 +349,8 @@ ${response.headers
|
||||
sortKey: request.timestamp,
|
||||
copyText,
|
||||
highlightOnHover: true,
|
||||
requestBody: requestData,
|
||||
responseBody: responseData,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -471,6 +476,7 @@ class NetworkTable extends PureComponent<NetworkTableProps, NetworkTableState> {
|
||||
highlightedRows={this.props.highlightedRows}
|
||||
rowLineHeight={26}
|
||||
allowRegexSearch={true}
|
||||
allowBodySearch={true}
|
||||
zebra={false}
|
||||
actions={<Button onClick={this.props.clear}>Clear Table</Button>}
|
||||
/>
|
||||
|
||||
@@ -56,6 +56,7 @@ type Props = {
|
||||
toggled?: boolean;
|
||||
className?: string;
|
||||
label?: string;
|
||||
tooltip?: string;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -71,7 +72,7 @@ type Props = {
|
||||
export default class ToggleButton extends React.Component<Props> {
|
||||
render() {
|
||||
return (
|
||||
<Container onClick={this.props.onClick}>
|
||||
<Container onClick={this.props.onClick} title={this.props.tooltip}>
|
||||
<StyledButton
|
||||
className={this.props.className}
|
||||
toggled={this.props.toggled || false}
|
||||
|
||||
@@ -93,7 +93,9 @@ export type SearchableProps = {
|
||||
searchTerm: string;
|
||||
filters: Array<Filter>;
|
||||
allowRegexSearch?: boolean;
|
||||
allowBodySearch?: boolean;
|
||||
regexEnabled?: boolean;
|
||||
bodySearchEnabled?: boolean;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
@@ -104,6 +106,7 @@ type Props = {
|
||||
onFilterChange: (filters: Array<Filter>) => void;
|
||||
defaultFilters: Array<Filter>;
|
||||
allowRegexSearch: boolean;
|
||||
allowBodySearch: boolean;
|
||||
};
|
||||
|
||||
type State = {
|
||||
@@ -112,6 +115,7 @@ type State = {
|
||||
searchTerm: string;
|
||||
hasFocus: boolean;
|
||||
regexEnabled: boolean;
|
||||
bodySearchEnabled: boolean;
|
||||
compiledRegex: RegExp | null | undefined;
|
||||
};
|
||||
|
||||
@@ -137,6 +141,7 @@ const Searchable = (
|
||||
searchTerm: '',
|
||||
hasFocus: false,
|
||||
regexEnabled: false,
|
||||
bodySearchEnabled: false,
|
||||
compiledRegex: null,
|
||||
};
|
||||
|
||||
@@ -149,6 +154,7 @@ const Searchable = (
|
||||
| {
|
||||
filters: Array<Filter>;
|
||||
regexEnabled?: boolean;
|
||||
bodySearchEnabled?: boolean;
|
||||
searchTerm?: string;
|
||||
}
|
||||
| undefined;
|
||||
@@ -192,6 +198,8 @@ const Searchable = (
|
||||
searchTerm: searchTerm,
|
||||
filters: savedState.filters || this.state.filters,
|
||||
regexEnabled: savedState.regexEnabled || this.state.regexEnabled,
|
||||
bodySearchEnabled:
|
||||
savedState.bodySearchEnabled || this.state.bodySearchEnabled,
|
||||
compiledRegex: compileRegex(searchTerm),
|
||||
});
|
||||
}
|
||||
@@ -202,6 +210,7 @@ const Searchable = (
|
||||
this.getTableKey() &&
|
||||
(prevState.searchTerm !== this.state.searchTerm ||
|
||||
prevState.regexEnabled != this.state.regexEnabled ||
|
||||
prevState.bodySearchEnabled != this.state.bodySearchEnabled ||
|
||||
prevState.filters !== this.state.filters)
|
||||
) {
|
||||
window.localStorage.setItem(
|
||||
@@ -210,6 +219,7 @@ const Searchable = (
|
||||
searchTerm: this.state.searchTerm,
|
||||
filters: this.state.filters,
|
||||
regexEnabled: this.state.regexEnabled,
|
||||
bodySearchEnabled: this.state.bodySearchEnabled,
|
||||
}),
|
||||
);
|
||||
if (this.props.onFilterChange != null) {
|
||||
@@ -406,6 +416,12 @@ const Searchable = (
|
||||
});
|
||||
};
|
||||
|
||||
onBodySearchToggled = () => {
|
||||
this.setState({
|
||||
bodySearchEnabled: !this.state.bodySearchEnabled,
|
||||
});
|
||||
};
|
||||
|
||||
hasFocus = (): boolean => {
|
||||
return this.state.focusedToken !== -1 || this.state.hasFocus;
|
||||
};
|
||||
@@ -464,6 +480,16 @@ const Searchable = (
|
||||
label={'Regex'}
|
||||
/>
|
||||
) : null}
|
||||
{this.props.allowBodySearch ? (
|
||||
<ToggleButton
|
||||
toggled={this.state.bodySearchEnabled}
|
||||
onClick={this.onBodySearchToggled}
|
||||
label={'Body'}
|
||||
tooltip={
|
||||
'Search request and response bodies (warning: this can be quite slow)'
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
{(this.state.searchTerm || this.state.filters.length > 0) && (
|
||||
<Clear onClick={this.clear}>×</Clear>
|
||||
)}
|
||||
@@ -475,6 +501,7 @@ const Searchable = (
|
||||
addFilter={this.addFilter}
|
||||
searchTerm={this.state.searchTerm}
|
||||
regexEnabled={this.state.regexEnabled}
|
||||
bodySearchEnabled={this.state.bodySearchEnabled}
|
||||
filters={this.state.filters}
|
||||
/>,
|
||||
];
|
||||
|
||||
@@ -60,6 +60,7 @@ function rowMatchesRegex(values: Array<string>, regex: string): boolean {
|
||||
function rowMatchesSearchTerm(
|
||||
searchTerm: string,
|
||||
isRegex: boolean,
|
||||
isBodySearchEnabled: boolean,
|
||||
row: TableBodyRow,
|
||||
): boolean {
|
||||
if (searchTerm == null || searchTerm.length === 0) {
|
||||
@@ -68,6 +69,14 @@ function rowMatchesSearchTerm(
|
||||
const rowValues = Object.keys(row.columns).map(key =>
|
||||
textContent(row.columns[key].value),
|
||||
);
|
||||
if (isBodySearchEnabled) {
|
||||
if (row.requestBody) {
|
||||
rowValues.push(row.requestBody);
|
||||
}
|
||||
if (row.responseBody) {
|
||||
rowValues.push(row.responseBody);
|
||||
}
|
||||
}
|
||||
if (isRegex) {
|
||||
return rowMatchesRegex(rowValues, searchTerm);
|
||||
}
|
||||
@@ -80,9 +89,10 @@ const filterRowsFactory = (
|
||||
filters: Array<Filter>,
|
||||
searchTerm: string,
|
||||
regexSearch: boolean,
|
||||
bodySearch: boolean,
|
||||
) => (row: TableBodyRow): boolean =>
|
||||
rowMatchesFilters(filters, row) &&
|
||||
rowMatchesSearchTerm(searchTerm, regexSearch, row);
|
||||
rowMatchesSearchTerm(searchTerm, regexSearch, bodySearch, row);
|
||||
|
||||
class SearchableManagedTable extends PureComponent<Props, State> {
|
||||
static defaultProps = {
|
||||
@@ -94,6 +104,7 @@ class SearchableManagedTable extends PureComponent<Props, State> {
|
||||
this.props.filters,
|
||||
this.props.searchTerm,
|
||||
this.props.regexEnabled || false,
|
||||
this.props.bodySearchEnabled || false,
|
||||
),
|
||||
};
|
||||
|
||||
@@ -105,6 +116,7 @@ class SearchableManagedTable extends PureComponent<Props, State> {
|
||||
if (
|
||||
nextProps.searchTerm !== this.props.searchTerm ||
|
||||
nextProps.regexEnabled != this.props.regexEnabled ||
|
||||
nextProps.bodySearchEnabled != this.props.bodySearchEnabled ||
|
||||
!deepEqual(this.props.filters, nextProps.filters)
|
||||
) {
|
||||
this.setState({
|
||||
@@ -112,6 +124,7 @@ class SearchableManagedTable extends PureComponent<Props, State> {
|
||||
nextProps.filters,
|
||||
nextProps.searchTerm,
|
||||
nextProps.regexEnabled || false,
|
||||
nextProps.bodySearchEnabled || false,
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -55,6 +55,8 @@ export type TableBodyRow = {
|
||||
highlightedBackgroundColor?: BackgroundColorProperty | undefined;
|
||||
onDoubleClick?: (e: React.MouseEvent) => void;
|
||||
copyText?: string;
|
||||
requestBody?: string | null | undefined;
|
||||
responseBody?: string | null | undefined;
|
||||
highlightOnHover?: boolean;
|
||||
columns: {
|
||||
[key: string]: TableBodyColumn;
|
||||
|
||||
Reference in New Issue
Block a user