Skip to content

Commit c7baafb

Browse files
Adam Erbsvc-squareup-copybara
authored andcommitted
Adds copy buttons to misk web-actions
GitOrigin-RevId: 7398506888d08f2324bfbd1b98766f776db82763
1 parent 7476767 commit c7baafb

File tree

2 files changed

+57
-8
lines changed

2 files changed

+57
-8
lines changed

misk-admin/web-actions/src/web-actions/ui/RequestEditor.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import ace from 'ace-builds/src-noconflict/ace';
44
import 'ace-builds/src-noconflict/ext-language_tools';
55
import { ContextAwareCompleter } from '@web-actions/ui/ContextAwareCompleter';
66
import { Box, IconButton, Spinner } from '@chakra-ui/react';
7-
import { ArrowForwardIcon } from '@chakra-ui/icons';
7+
import { ArrowForwardIcon, CopyIcon } from '@chakra-ui/icons';
88
import { CommandParser } from '@web-actions/parsing/CommandParser';
99
import { MiskWebActionDefinition } from '@web-actions/api/responseTypes';
1010
import { EndpointSelectionCallbacks } from '@web-actions/ui/EndpointSelection';
@@ -32,6 +32,7 @@ export default class RequestEditor extends React.Component<Props, State> {
3232
super(props);
3333
this.state = { loading: false };
3434
this.submitRequest = this.submitRequest.bind(this);
35+
this.copyToClipboard = this.copyToClipboard.bind(this);
3536

3637
this.completer = new ContextAwareCompleter();
3738
}
@@ -109,6 +110,16 @@ export default class RequestEditor extends React.Component<Props, State> {
109110
}
110111
}
111112

113+
async copyToClipboard() {
114+
try {
115+
const content = this.editor!.getValue();
116+
const normalizedJson = new CommandParser(content).parse()?.render();
117+
await navigator.clipboard.writeText(normalizedJson);
118+
} catch (err) {
119+
console.error('Failed to copy with error:', err);
120+
}
121+
}
122+
112123
public render() {
113124
return (
114125
<Box position="relative" width="100%" height="100%">
@@ -138,6 +149,16 @@ export default class RequestEditor extends React.Component<Props, State> {
138149
backgroundColor="green.200"
139150
onClick={this.submitRequest}
140151
/>
152+
<IconButton
153+
aria-label="Copy"
154+
icon={<CopyIcon />}
155+
zIndex="100"
156+
position="absolute"
157+
top="14"
158+
right="2"
159+
backgroundColor="grey"
160+
onClick={this.copyToClipboard}
161+
/>
141162
<Box
142163
width="100%"
143164
height="100%"

misk-admin/web-actions/src/web-actions/ui/ResponseViewer.tsx

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@ import React, { Dispatch, SetStateAction } from 'react';
22
import { Ace } from 'ace-builds';
33
import ace from 'ace-builds/src-noconflict/ace';
44
import 'ace-builds/src-noconflict/ext-language_tools';
5-
import { Box } from '@chakra-ui/react';
5+
import { Box, IconButton } from '@chakra-ui/react';
66
import { ViewState } from 'src/viewState';
7+
import { CopyIcon } from '@chakra-ui/icons';
8+
import { CommandParser } from '@web-actions/parsing/CommandParser';
79

810
interface Props {
911
viewState: ViewState;
@@ -14,6 +16,11 @@ export default class ResponseViewer extends React.Component<Props> {
1416
public refEditor: HTMLElement | null = null;
1517
public editor: Ace.Editor | null = null;
1618

19+
constructor(props: Props) {
20+
super(props);
21+
this.copyToClipboard = this.copyToClipboard.bind(this);
22+
}
23+
1724
componentDidMount() {
1825
this.editor = ace.edit(this.refEditor, {
1926
theme: 'ace/theme/textmate',
@@ -33,16 +40,37 @@ export default class ResponseViewer extends React.Component<Props> {
3340
this.refEditor = item;
3441
}
3542

43+
async copyToClipboard() {
44+
try {
45+
const content = this.editor!.getValue();
46+
await navigator.clipboard.writeText(content);
47+
} catch (err) {
48+
console.error('Failed to copy with error:', err);
49+
}
50+
}
51+
3652
public render() {
3753
this.editor?.setValue(this.props.viewState.response || '', -1);
3854

3955
return (
40-
<Box
41-
id={'response-viewer'}
42-
width="100%"
43-
height="100%"
44-
ref={(it) => this.updateRef(it)}
45-
/>
56+
<>
57+
<IconButton
58+
aria-label="Copy"
59+
icon={<CopyIcon />}
60+
zIndex="100"
61+
position="absolute"
62+
top="14"
63+
right="2"
64+
backgroundColor="grey"
65+
onClick={this.copyToClipboard}
66+
/>
67+
<Box
68+
id={'response-viewer'}
69+
width="100%"
70+
height="100%"
71+
ref={(it) => this.updateRef(it)}
72+
/>
73+
</>
4674
);
4775
}
4876
}

0 commit comments

Comments
 (0)