Skip to content

Commit 8456eec

Browse files
committed
Reuse the editor across response bodies via portals
1 parent 1c496d2 commit 8456eec

File tree

6 files changed

+49
-10
lines changed

6 files changed

+49
-10
lines changed

package-lock.json

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@
8787
"react-dom": "^16.6.3",
8888
"react-ga": "^2.5.6",
8989
"react-monaco-editor": "^0.22.0",
90+
"react-reverse-portal": "^1.0.1",
9091
"react-sortable-hoc": "^1.10.1",
9192
"react-split-pane": "^0.1.84",
9293
"react-virtualized": "^9.20.1",

src/components/editor/content-editor.tsx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ export const Formatters: { [key in HtkContentType]?: Formatter } = {
107107
};
108108

109109
interface ContentEditorProps {
110-
children: Buffer;
110+
children: Buffer | string;
111111
schema?: SchemaObject;
112-
rawContentType: string | undefined;
112+
rawContentType?: string;
113113
contentType: HtkContentType;
114114
contentObservable?: IObservableValue<string | undefined>;
115115
}
@@ -130,10 +130,17 @@ export class ContentEditor extends React.Component<ContentEditorProps> {
130130
return Formatters[this.props.contentType] || Formatters.text!;
131131
}
132132

133+
@computed
134+
private get contentBuffer() {
135+
return _.isString(this.props.children)
136+
? Buffer.from(this.props.children)
137+
: this.props.children;
138+
}
139+
133140
@computed
134141
private get renderedContent() {
135142
if (isEditorFormatter(this.formatter)) {
136-
return this.formatter.render(this.props.children);
143+
return this.formatter.render(this.contentBuffer);
137144
}
138145
}
139146

@@ -167,7 +174,7 @@ export class ContentEditor extends React.Component<ContentEditorProps> {
167174
}
168175
} else {
169176
const Viewer = this.formatter;
170-
return <Viewer content={this.props.children} rawContentType={this.props.rawContentType} />;
177+
return <Viewer content={this.contentBuffer} rawContentType={this.props.rawContentType} />;
171178
}
172179
}
173180
}

src/components/view/exchange-body-card.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as React from 'react';
33
import { observable, autorun, action } from 'mobx';
44
import { disposeOnUnmount, observer, inject } from 'mobx-react';
55
import { SchemaObject } from 'openapi-directory';
6+
import * as portals from 'react-reverse-portal';
67

78
import { ExchangeMessage } from '../../types';
89
import { styled } from '../../styles';
@@ -39,6 +40,7 @@ export class ExchangeBodyCard extends React.Component<{
3940
direction: 'left' | 'right',
4041
collapsed: boolean,
4142
onCollapseToggled: () => void,
43+
editorNode: portals.PortalNode
4244
}> {
4345

4446
@observable
@@ -112,14 +114,15 @@ export class ExchangeBodyCard extends React.Component<{
112114
<h1>{ title }</h1>
113115
</header>
114116
<EditorCardContent>
115-
<ContentEditor
117+
<portals.OutPortal<ContentEditor>
118+
node={this.props.editorNode}
116119
rawContentType={message.headers['content-type']}
117120
contentType={contentType}
118121
contentObservable={this.currentContent}
119122
schema={apiBodySchema}
120123
>
121124
{decodedBody}
122-
</ContentEditor>
125+
</portals.OutPortal>
123126
</EditorCardContent>
124127
</ExchangeCard>
125128
:

src/components/view/exchange-details-pane.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import * as React from 'react';
33
import { get } from 'typesafe-get';
44
import { action, observable } from 'mobx';
55
import { observer, inject } from 'mobx-react';
6+
import * as portals from 'react-reverse-portal';
67

78
import { HtkResponse, Omit } from '../../types';
89
import { styled } from '../../styles';
@@ -54,7 +55,9 @@ export class ExchangeDetailsPane extends React.Component<{
5455
exchange: HttpExchange,
5556
// Injected:
5657
uiStore?: UiStore,
57-
accountStore?: AccountStore
58+
accountStore?: AccountStore,
59+
requestEditor: portals.PortalNode,
60+
responseEditor: portals.PortalNode
5861
}> {
5962

6063
@observable
@@ -92,6 +95,7 @@ export class ExchangeDetailsPane extends React.Component<{
9295
title='Request Body'
9396
direction='right'
9497
message={request}
98+
editorNode={this.props.requestEditor}
9599
apiBodySchema={get(apiExchange, 'request', 'bodySchema')}
96100
{...this.cardProps.requestBody}
97101
/>);
@@ -121,6 +125,7 @@ export class ExchangeDetailsPane extends React.Component<{
121125
title='Response Body'
122126
direction='left'
123127
message={response}
128+
editorNode={this.props.responseEditor}
124129
apiBodySchema={get(apiExchange, 'response', 'bodySchema')}
125130
{...this.cardProps.responseBody}
126131
/>);

src/components/view/view-page.tsx

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as React from 'react';
22
import * as _ from 'lodash';
3-
4-
import { observable, autorun, action, runInAction } from 'mobx';
3+
import { autorun, action, observable, runInAction } from 'mobx';
54
import { observer, disposeOnUnmount, inject } from 'mobx-react';
5+
import * as portals from 'react-reverse-portal';
66

77
import { WithInjected } from '../../types';
88
import { styled } from '../../styles';
@@ -15,6 +15,7 @@ import { EmptyState } from '../common/empty-state';
1515
import { ViewEventList, CollectedEvent } from './view-event-list';
1616
import { ExchangeDetailsPane } from './exchange-details-pane';
1717
import { TlsFailureDetailsPane } from './tls-failure-details-pane';
18+
import { ContentEditor } from '../editor/content-editor';
1819

1920
interface ViewPageProps {
2021
className?: string,
@@ -27,6 +28,9 @@ class ViewPage extends React.Component<ViewPageProps> {
2728

2829
@observable.ref selectedEvent: CollectedEvent | undefined = undefined;
2930

31+
requestEditor = portals.createPortalNode<ContentEditor>();
32+
responseEditor = portals.createPortalNode<ContentEditor>();
33+
3034
componentDidMount() {
3135
disposeOnUnmount(this, autorun(() => {
3236
if (!_.includes(this.props.interceptionStore.events, this.selectedEvent)) {
@@ -49,7 +53,11 @@ class ViewPage extends React.Component<ViewPageProps> {
4953
Select an exchange to see the full details.
5054
</EmptyState>;
5155
} else if ('request' in this.selectedEvent) {
52-
rightPane = <ExchangeDetailsPane exchange={this.selectedEvent} />;
56+
rightPane = <ExchangeDetailsPane
57+
exchange={this.selectedEvent}
58+
requestEditor={this.requestEditor}
59+
responseEditor={this.responseEditor}
60+
/>;
5361
} else {
5462
rightPane = <TlsFailureDetailsPane failure={this.selectedEvent} certPath={certPath} />;
5563
}
@@ -70,6 +78,16 @@ class ViewPage extends React.Component<ViewPageProps> {
7078
/>
7179
{ rightPane }
7280
</SplitPane>
81+
82+
{[this.requestEditor, this.responseEditor].map((editorNode, i) =>
83+
<portals.InPortal key={i} node={editorNode}>
84+
<ContentEditor
85+
contentType='text'
86+
rawContentType=''
87+
children=''
88+
/>
89+
</portals.InPortal>
90+
)}
7391
</div>;
7492
}
7593

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy