fix(request-snippets): prevent scrolling errors from missing function (#7941)
* fix(request-snippets): prevent scrolling errors from missing function * refactor(request-snippets): migrate to functional component * fix(curl): remove undefined prop and function * test(live-response): fix import of RequestSnippets
This commit is contained in:
@@ -21,7 +21,6 @@ export default class Curl extends React.Component {
|
|||||||
? <SyntaxHighlighter
|
? <SyntaxHighlighter
|
||||||
language="bash"
|
language="bash"
|
||||||
className="curl microlight"
|
className="curl microlight"
|
||||||
onWheel={this.preventYScrollingBeyondElement}
|
|
||||||
style={getStyle(get(config, "syntaxHighlight.theme"))}
|
style={getStyle(get(config, "syntaxHighlight.theme"))}
|
||||||
>
|
>
|
||||||
{curl}
|
{curl}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import * as fn from "./fn"
|
import * as fn from "./fn"
|
||||||
import * as selectors from "./selectors"
|
import * as selectors from "./selectors"
|
||||||
import { RequestSnippets } from "./request-snippets"
|
import RequestSnippets from "./request-snippets"
|
||||||
export default () => {
|
export default () => {
|
||||||
return {
|
return {
|
||||||
components: {
|
components: {
|
||||||
|
|||||||
@@ -1,127 +1,160 @@
|
|||||||
import React from "react"
|
import React, { useRef, useEffect, useState } from "react"
|
||||||
import { CopyToClipboard } from "react-copy-to-clipboard"
|
|
||||||
import PropTypes from "prop-types"
|
import PropTypes from "prop-types"
|
||||||
import get from "lodash/get"
|
import get from "lodash/get"
|
||||||
import {SyntaxHighlighter, getStyle} from "core/syntax-highlighting"
|
import isFunction from "lodash/isFunction"
|
||||||
|
import { CopyToClipboard } from "react-copy-to-clipboard"
|
||||||
|
import { SyntaxHighlighter, getStyle } from "core/syntax-highlighting"
|
||||||
|
|
||||||
export class RequestSnippets extends React.Component {
|
const style = {
|
||||||
constructor() {
|
cursor: "pointer",
|
||||||
super()
|
lineHeight: 1,
|
||||||
this.state = {
|
display: "inline-flex",
|
||||||
activeLanguage: this.props?.requestSnippetsSelectors?.getSnippetGenerators()?.keySeq().first(),
|
backgroundColor: "rgb(250, 250, 250)",
|
||||||
expanded: this.props?.requestSnippetsSelectors?.getDefaultExpanded(),
|
paddingBottom: "0",
|
||||||
|
paddingTop: "0",
|
||||||
|
border: "1px solid rgb(51, 51, 51)",
|
||||||
|
borderRadius: "4px 4px 0 0",
|
||||||
|
boxShadow: "none",
|
||||||
|
borderBottom: "none"
|
||||||
|
}
|
||||||
|
|
||||||
|
const activeStyle = {
|
||||||
|
cursor: "pointer",
|
||||||
|
lineHeight: 1,
|
||||||
|
display: "inline-flex",
|
||||||
|
backgroundColor: "rgb(51, 51, 51)",
|
||||||
|
boxShadow: "none",
|
||||||
|
border: "1px solid rgb(51, 51, 51)",
|
||||||
|
paddingBottom: "0",
|
||||||
|
paddingTop: "0",
|
||||||
|
borderRadius: "4px 4px 0 0",
|
||||||
|
marginTop: "-5px",
|
||||||
|
marginRight: "-5px",
|
||||||
|
marginLeft: "-5px",
|
||||||
|
zIndex: "9999",
|
||||||
|
borderBottom: "none"
|
||||||
|
}
|
||||||
|
|
||||||
|
const RequestSnippets = ({ request, requestSnippetsSelectors, getConfigs }) => {
|
||||||
|
const config = isFunction(getConfigs) ? getConfigs() : null
|
||||||
|
const canSyntaxHighlight = get(config, "syntaxHighlight") !== false && get(config, "syntaxHighlight.activated", true)
|
||||||
|
const rootRef = useRef(null)
|
||||||
|
|
||||||
|
const [activeLanguage, setActiveLanguage] = useState(requestSnippetsSelectors.getSnippetGenerators()?.keySeq().first())
|
||||||
|
const [isExpanded, setIsExpanded] = useState(requestSnippetsSelectors?.getDefaultExpanded())
|
||||||
|
useEffect(() => {
|
||||||
|
const doIt = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
doIt()
|
||||||
|
}, [])
|
||||||
|
useEffect(() => {
|
||||||
|
const childNodes = Array
|
||||||
|
.from(rootRef.current.childNodes)
|
||||||
|
.filter(node => !!node.nodeType && node.classList?.contains("curl-command"))
|
||||||
|
// eslint-disable-next-line no-use-before-define
|
||||||
|
childNodes.forEach(node => node.addEventListener("mousewheel", handlePreventYScrollingBeyondElement, { passive: false }))
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
// eslint-disable-next-line no-use-before-define
|
||||||
|
childNodes.forEach(node => node.removeEventListener("mousewheel", handlePreventYScrollingBeyondElement))
|
||||||
|
}
|
||||||
|
}, [request])
|
||||||
|
|
||||||
|
const snippetGenerators = requestSnippetsSelectors.getSnippetGenerators()
|
||||||
|
const activeGenerator = snippetGenerators.get(activeLanguage)
|
||||||
|
const snippet = activeGenerator.get("fn")(request)
|
||||||
|
|
||||||
|
const handleGenChange = (key) => {
|
||||||
|
const needsChange = activeLanguage !== key
|
||||||
|
if (needsChange) {
|
||||||
|
setActiveLanguage(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static propTypes = {
|
const handleSetIsExpanded = () => {
|
||||||
request: PropTypes.object.isRequired,
|
setIsExpanded(!isExpanded)
|
||||||
requestSnippetsSelectors: PropTypes.object.isRequired,
|
|
||||||
getConfigs: PropTypes.object.isRequired,
|
|
||||||
requestSnippetsActions: PropTypes.object.isRequired,
|
|
||||||
}
|
}
|
||||||
render() {
|
|
||||||
const {request, getConfigs, requestSnippetsSelectors } = this.props
|
|
||||||
const snippetGenerators = requestSnippetsSelectors.getSnippetGenerators()
|
|
||||||
const activeLanguage = this.state.activeLanguage || snippetGenerators.keySeq().first()
|
|
||||||
const activeGenerator = snippetGenerators.get(activeLanguage)
|
|
||||||
const snippet = activeGenerator.get("fn")(request)
|
|
||||||
const onGenChange = (key) => {
|
|
||||||
const needsChange = activeLanguage !== key
|
|
||||||
if(needsChange) {
|
|
||||||
this.setState({
|
|
||||||
activeLanguage: key
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const style = {
|
|
||||||
cursor: "pointer",
|
|
||||||
lineHeight: 1,
|
|
||||||
display: "inline-flex",
|
|
||||||
backgroundColor: "rgb(250, 250, 250)",
|
|
||||||
paddingBottom: "0",
|
|
||||||
paddingTop: "0",
|
|
||||||
border: "1px solid rgb(51, 51, 51)",
|
|
||||||
borderRadius: "4px 4px 0 0",
|
|
||||||
boxShadow: "none",
|
|
||||||
borderBottom: "none"
|
|
||||||
}
|
|
||||||
const activeStyle = {
|
|
||||||
cursor: "pointer",
|
|
||||||
lineHeight: 1,
|
|
||||||
display: "inline-flex",
|
|
||||||
backgroundColor: "rgb(51, 51, 51)",
|
|
||||||
boxShadow: "none",
|
|
||||||
border: "1px solid rgb(51, 51, 51)",
|
|
||||||
paddingBottom: "0",
|
|
||||||
paddingTop: "0",
|
|
||||||
borderRadius: "4px 4px 0 0",
|
|
||||||
marginTop: "-5px",
|
|
||||||
marginRight: "-5px",
|
|
||||||
marginLeft: "-5px",
|
|
||||||
zIndex: "9999",
|
|
||||||
borderBottom: "none"
|
|
||||||
}
|
|
||||||
const getBtnStyle = (key) => {
|
|
||||||
if (key === activeLanguage) {
|
|
||||||
return activeStyle
|
|
||||||
}
|
|
||||||
return style
|
|
||||||
}
|
|
||||||
const config = getConfigs()
|
|
||||||
|
|
||||||
const SnippetComponent = config?.syntaxHighlight?.activated
|
const handleGetBtnStyle = (key) => {
|
||||||
? <SyntaxHighlighter
|
if (key === activeLanguage) {
|
||||||
language={activeGenerator.get("syntax")}
|
return activeStyle
|
||||||
className="curl microlight"
|
}
|
||||||
onWheel={function(e) {return this.preventYScrollingBeyondElement(e)}}
|
return style
|
||||||
style={getStyle(get(config, "syntaxHighlight.theme"))}
|
}
|
||||||
|
|
||||||
|
const handlePreventYScrollingBeyondElement = (e) => {
|
||||||
|
const { target, deltaY } = e
|
||||||
|
const { scrollHeight: contentHeight, offsetHeight: visibleHeight, scrollTop } = target
|
||||||
|
const scrollOffset = visibleHeight + scrollTop
|
||||||
|
const isElementScrollable = contentHeight > visibleHeight
|
||||||
|
const isScrollingPastTop = scrollTop === 0 && deltaY < 0
|
||||||
|
const isScrollingPastBottom = scrollOffset >= contentHeight && deltaY > 0
|
||||||
|
|
||||||
|
if (isElementScrollable && (isScrollingPastTop || isScrollingPastBottom)) {
|
||||||
|
e.preventDefault()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const SnippetComponent = canSyntaxHighlight
|
||||||
|
? <SyntaxHighlighter
|
||||||
|
language={activeGenerator.get("syntax")}
|
||||||
|
className="curl microlight"
|
||||||
|
style={getStyle(get(config, "syntaxHighlight.theme"))}
|
||||||
|
>
|
||||||
|
{snippet}
|
||||||
|
</SyntaxHighlighter>
|
||||||
|
:
|
||||||
|
<textarea readOnly={true} className="curl" value={snippet}></textarea>
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="request-snippets" ref={rootRef}>
|
||||||
|
Just a test
|
||||||
|
<div style={{ width: "100%", display: "flex", justifyContent: "flex-start", alignItems: "center", marginBottom: "15px" }}>
|
||||||
|
<h4
|
||||||
|
onClick={() => handleSetIsExpanded()}
|
||||||
|
style={{ cursor: "pointer" }}
|
||||||
|
>Snippets</h4>
|
||||||
|
<button
|
||||||
|
onClick={() => handleSetIsExpanded()}
|
||||||
|
style={{ border: "none", background: "none" }}
|
||||||
|
title={isExpanded ? "Collapse operation" : "Expand operation"}
|
||||||
>
|
>
|
||||||
{snippet}
|
<svg className="arrow" width="10" height="10">
|
||||||
</SyntaxHighlighter>
|
<use href={isExpanded ? "#large-arrow-down" : "#large-arrow"} xlinkHref={isExpanded ? "#large-arrow-down" : "#large-arrow"} />
|
||||||
:
|
</svg>
|
||||||
<textarea readOnly={true} className="curl" value={snippet}></textarea>
|
</button>
|
||||||
|
</div>
|
||||||
const expanded = this.state.expanded === undefined ? this.props?.requestSnippetsSelectors?.getDefaultExpanded() : this.state.expanded
|
{
|
||||||
return (
|
isExpanded && <div className="curl-command">
|
||||||
<div>
|
<div style={{ paddingLeft: "15px", paddingRight: "10px", width: "100%", display: "flex" }}>
|
||||||
<div style={{width: "100%", display: "flex", justifyContent: "flex-start", alignItems: "center", marginBottom: "15px"}}>
|
{
|
||||||
<h4
|
snippetGenerators.entrySeq().map(([key, gen]) => {
|
||||||
style={{ cursor: "pointer" }}
|
return (<div style={handleGetBtnStyle(key)} className="btn" key={key} onClick={() => handleGenChange(key)}>
|
||||||
onClick={() => this.setState({expanded: !expanded})}
|
<h4 style={key === activeLanguage ? { color: "white", } : {}}>{gen.get("title")}</h4>
|
||||||
>Snippets</h4>
|
</div>)
|
||||||
<button
|
})
|
||||||
onClick={() => this.setState({expanded: !expanded})}
|
}
|
||||||
style={{ border: "none", background: "none" }}
|
</div>
|
||||||
title={expanded ? "Collapse operation": "Expand operation"}
|
<div className="copy-to-clipboard">
|
||||||
>
|
<CopyToClipboard text={snippet}>
|
||||||
<svg className="arrow" width="10" height="10">
|
<button />
|
||||||
<use href={expanded ? "#large-arrow-down" : "#large-arrow"} xlinkHref={expanded ? "#large-arrow-down" : "#large-arrow"} />
|
</CopyToClipboard>
|
||||||
</svg>
|
</div>
|
||||||
</button>
|
<div>
|
||||||
|
{SnippetComponent}
|
||||||
</div>
|
</div>
|
||||||
{
|
|
||||||
expanded && <div className="curl-command">
|
|
||||||
<div style={{paddingLeft: "15px", paddingRight: "10px", width: "100%", display: "flex"}}>
|
|
||||||
{
|
|
||||||
snippetGenerators.entrySeq().map(([key, gen]) => {
|
|
||||||
return (<div style={getBtnStyle(key)} className="btn" key={key} onClick={() => onGenChange(key)}>
|
|
||||||
<h4 style={key === activeLanguage ? {color: "white",} : {}}>{gen.get("title")}</h4>
|
|
||||||
</div>)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div className="copy-to-clipboard">
|
|
||||||
<CopyToClipboard text={snippet}>
|
|
||||||
<button />
|
|
||||||
</CopyToClipboard>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{SnippetComponent}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
|
}
|
||||||
)
|
</div>
|
||||||
}
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RequestSnippets.propTypes = {
|
||||||
|
request: PropTypes.object.isRequired,
|
||||||
|
requestSnippetsSelectors: PropTypes.object.isRequired,
|
||||||
|
getConfigs: PropTypes.object.isRequired,
|
||||||
|
requestSnippetsActions: PropTypes.object,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RequestSnippets
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import expect from "expect"
|
|||||||
import { shallow } from "enzyme"
|
import { shallow } from "enzyme"
|
||||||
import LiveResponse from "components/live-response"
|
import LiveResponse from "components/live-response"
|
||||||
import ResponseBody from "components/response-body"
|
import ResponseBody from "components/response-body"
|
||||||
import { RequestSnippets } from "core/plugins/request-snippets/request-snippets"
|
import RequestSnippets from "core/plugins/request-snippets/request-snippets"
|
||||||
|
|
||||||
describe("<LiveResponse/>", function () {
|
describe("<LiveResponse/>", function () {
|
||||||
let request = fromJSOrdered({
|
let request = fromJSOrdered({
|
||||||
|
|||||||
Reference in New Issue
Block a user