* Move next to download button and match styling Co-authored-by: Aldrin Abastillas <AAbastillas@rcanalytics.com> Co-authored-by: Tim Lai <timothy.lai@gmail.com>
This commit is contained in:
committed by
GitHub
parent
f8dd4e68ec
commit
973e1f7a9b
334
package-lock.json
generated
334
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -69,6 +69,7 @@
|
||||
"prop-types": "^15.7.2",
|
||||
"randombytes": "^2.1.0",
|
||||
"react": "^15.6.2",
|
||||
"react-copy-to-clipboard": "5.0.1",
|
||||
"react-debounce-input": "^3.2.0",
|
||||
"react-dom": "^15.6.2",
|
||||
"react-immutable-proptypes": "2.1.0",
|
||||
|
||||
@@ -2,13 +2,15 @@ import React, { Component } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
import { highlight } from "core/utils"
|
||||
import saveAs from "js-file-download"
|
||||
import { CopyToClipboard } from "react-copy-to-clipboard"
|
||||
|
||||
export default class HighlightCode extends Component {
|
||||
static propTypes = {
|
||||
value: PropTypes.string.isRequired,
|
||||
className: PropTypes.string,
|
||||
downloadable: PropTypes.bool,
|
||||
fileName: PropTypes.string
|
||||
fileName: PropTypes.string,
|
||||
canCopy: PropTypes.bool
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
@@ -47,7 +49,7 @@ export default class HighlightCode extends Component {
|
||||
}
|
||||
|
||||
render () {
|
||||
let { value, className, downloadable } = this.props
|
||||
let { value, className, downloadable, canCopy } = this.props
|
||||
className = className || ""
|
||||
|
||||
return (
|
||||
@@ -57,6 +59,13 @@ export default class HighlightCode extends Component {
|
||||
Download
|
||||
</div>
|
||||
}
|
||||
|
||||
{ !canCopy ? null :
|
||||
<div className="copy-to-clipboard">
|
||||
<CopyToClipboard text={value}><button/></CopyToClipboard>
|
||||
</div>
|
||||
}
|
||||
|
||||
<pre
|
||||
ref={this.initializeComponent}
|
||||
onWheel={this.preventYScrollingBeyondElement}
|
||||
|
||||
@@ -99,7 +99,7 @@ export default class ResponseBody extends React.PureComponent {
|
||||
body = "can't parse JSON. Raw result:\n\n" + content
|
||||
}
|
||||
|
||||
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.json`} value={ body } />
|
||||
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.json`} value={ body } canCopy />
|
||||
|
||||
// XML
|
||||
} else if (/xml/i.test(contentType)) {
|
||||
@@ -107,11 +107,11 @@ export default class ResponseBody extends React.PureComponent {
|
||||
textNodesOnSameLine: true,
|
||||
indentor: " "
|
||||
})
|
||||
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.xml`} value={ body } />
|
||||
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.xml`} value={ body } canCopy />
|
||||
|
||||
// HTML or Plain Text
|
||||
} else if (toLower(contentType) === "text/html" || /text\/plain/.test(contentType)) {
|
||||
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.html`} value={ content } />
|
||||
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.html`} value={ content } canCopy />
|
||||
|
||||
// Image
|
||||
} else if (/^image\//i.test(contentType)) {
|
||||
@@ -125,7 +125,7 @@ export default class ResponseBody extends React.PureComponent {
|
||||
} else if (/^audio\//i.test(contentType)) {
|
||||
bodyEl = <pre className="microlight"><audio controls><source src={ url } type={ contentType } /></audio></pre>
|
||||
} else if (typeof content === "string") {
|
||||
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.txt`} value={ content } />
|
||||
bodyEl = <HighlightCode downloadable fileName={`${downloadName}.txt`} value={ content } canCopy />
|
||||
} else if ( content.size > 0 ) {
|
||||
// We don't know the contentType, but there was some content returned
|
||||
if(parsedContent) {
|
||||
@@ -135,7 +135,7 @@ export default class ResponseBody extends React.PureComponent {
|
||||
<p className="i">
|
||||
Unrecognized response type; displaying content as text.
|
||||
</p>
|
||||
<HighlightCode downloadable fileName={`${downloadName}.txt`} value={ parsedContent } />
|
||||
<HighlightCode downloadable fileName={`${downloadName}.txt`} value={ parsedContent } canCopy />
|
||||
</div>
|
||||
|
||||
} else {
|
||||
|
||||
1
src/img/clipboard.svg
Normal file
1
src/img/clipboard.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' aria-hidden='true'><path fill='#ffffff' fill-rule='evenodd' d='M2 13h4v1H2v-1zm5-6H2v1h5V7zm2 3V8l-3 3 3 3v-2h5v-2H9zM4.5 9H2v1h2.5V9zM2 12h2.5v-1H2v1zm9 1h1v2c-.02.28-.11.52-.3.7-.19.18-.42.28-.7.3H1c-.55 0-1-.45-1-1V4c0-.55.45-1 1-1h3c0-1.11.89-2 2-2 1.11 0 2 .89 2 2h3c.55 0 1 .45 1 1v5h-1V6H1v9h10v-2zM2 5h8c0-.55-.45-1-1-1H8c-.55 0-1-.45-1-1s-.45-1-1-1-1 .45-1 1-.45 1-1 1H3c-.55 0-1 .45-1 1z'></path></svg>
|
||||
|
After Width: | Height: | Size: 476 B |
@@ -154,3 +154,23 @@ button
|
||||
@include invalidFormElement();
|
||||
}
|
||||
}
|
||||
|
||||
.copy-to-clipboard
|
||||
{
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
right: 100px;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
background: #7d8293;
|
||||
border-radius: 4px;
|
||||
border: none;
|
||||
|
||||
button
|
||||
{
|
||||
padding-left: 25px;
|
||||
border: none;
|
||||
height: 25px;
|
||||
background: url("../img/clipboard.svg") center center no-repeat;
|
||||
}
|
||||
}
|
||||
|
||||
28
test/components/highlight-code.jsx
Normal file
28
test/components/highlight-code.jsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import React from "react"
|
||||
import expect from "expect"
|
||||
import { shallow } from "enzyme"
|
||||
import HighlightCode from "components/highlight-code"
|
||||
|
||||
describe("<HighlightCode />", () => {
|
||||
it("should render a Download button if downloadable", () => {
|
||||
const props = {downloadable: true}
|
||||
const wrapper = shallow(<HighlightCode {...props} />)
|
||||
expect(wrapper.find(".download-contents").length).toEqual(1)
|
||||
})
|
||||
|
||||
it("should render a Copy To Clipboard button if copyable", () => {
|
||||
const props = {canCopy: true}
|
||||
const wrapper = shallow(<HighlightCode {...props} />)
|
||||
expect(wrapper.find("CopyToClipboard").length).toEqual(1)
|
||||
})
|
||||
|
||||
it("should render values in a preformatted element", () => {
|
||||
const value = "test text"
|
||||
const props = {value: value}
|
||||
const wrapper = shallow(<HighlightCode {...props} />)
|
||||
const preTag = wrapper.find("pre")
|
||||
|
||||
expect(preTag.length).toEqual(1)
|
||||
expect(preTag.contains(value)).toEqual(true)
|
||||
})
|
||||
})
|
||||
43
test/components/response-body.jsx
Normal file
43
test/components/response-body.jsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import React from "react"
|
||||
import expect from "expect"
|
||||
import { shallow } from "enzyme"
|
||||
import ResponseBody from "components/response-body"
|
||||
|
||||
describe("<ResponseBody />", function() {
|
||||
const highlightCodeComponent = () => null
|
||||
const components = {
|
||||
highlightCode: highlightCodeComponent
|
||||
}
|
||||
const props = {
|
||||
getComponent: c => components[c],
|
||||
}
|
||||
|
||||
it("renders ResponseBody as 'application/json'", function() {
|
||||
props.contentType = "application/json"
|
||||
props.content = "{\"key\": \"a test value\"}"
|
||||
const wrapper = shallow(<ResponseBody {...props}/>)
|
||||
expect(wrapper.find("highlightCodeComponent").length).toEqual(1)
|
||||
})
|
||||
|
||||
it("renders ResponseBody as 'text/html'", function() {
|
||||
props.contentType = "application/json"
|
||||
props.content = "<b>Result</b>"
|
||||
const wrapper = shallow(<ResponseBody {...props}/>)
|
||||
expect(wrapper.find("highlightCodeComponent").length).toEqual(1)
|
||||
})
|
||||
|
||||
it("renders ResponseBody as 'image/svg'", function() {
|
||||
props.contentType = "image/svg"
|
||||
const wrapper = shallow(<ResponseBody {...props}/>)
|
||||
console.warn(wrapper.debug())
|
||||
expect(wrapper.find("highlightCodeComponent").length).toEqual(0)
|
||||
})
|
||||
|
||||
it("should render a copyable highlightCodeComponent for text types", function() {
|
||||
props.contentType = "text/plain"
|
||||
props.content = "test text"
|
||||
const wrapper = shallow(<ResponseBody {...props}/>)
|
||||
console.warn(wrapper.debug())
|
||||
expect(wrapper.find("highlightCodeComponent[canCopy]").length).toEqual(1)
|
||||
})
|
||||
})
|
||||
@@ -2,7 +2,6 @@ import React from "react"
|
||||
import expect from "expect"
|
||||
import { shallow } from "enzyme"
|
||||
import ResponseBody from "components/response-body"
|
||||
import { inferSchema } from "corePlugins/samples/fn"
|
||||
|
||||
describe("<ResponseBody />", function() {
|
||||
const highlightCodeComponent = () => null
|
||||
@@ -33,4 +32,12 @@ describe("<ResponseBody />", function() {
|
||||
console.warn(wrapper.debug())
|
||||
expect(wrapper.find("highlightCodeComponent").length).toEqual(0)
|
||||
})
|
||||
|
||||
it("should render a copyable highlightCodeComponent for text types", function() {
|
||||
props.contentType = "text/plain"
|
||||
props.content = "test text"
|
||||
const wrapper = shallow(<ResponseBody {...props}/>)
|
||||
console.warn(wrapper.debug())
|
||||
expect(wrapper.find("highlightCodeComponent[canCopy]").length).toEqual(1)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user