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
|
||||
language="bash"
|
||||
className="curl microlight"
|
||||
onWheel={this.preventYScrollingBeyondElement}
|
||||
style={getStyle(get(config, "syntaxHighlight.theme"))}
|
||||
>
|
||||
{curl}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import * as fn from "./fn"
|
||||
import * as selectors from "./selectors"
|
||||
import { RequestSnippets } from "./request-snippets"
|
||||
import RequestSnippets from "./request-snippets"
|
||||
export default () => {
|
||||
return {
|
||||
components: {
|
||||
|
||||
@@ -1,127 +1,160 @@
|
||||
import React from "react"
|
||||
import { CopyToClipboard } from "react-copy-to-clipboard"
|
||||
import React, { useRef, useEffect, useState } from "react"
|
||||
import PropTypes from "prop-types"
|
||||
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 {
|
||||
constructor() {
|
||||
super()
|
||||
this.state = {
|
||||
activeLanguage: this.props?.requestSnippetsSelectors?.getSnippetGenerators()?.keySeq().first(),
|
||||
expanded: this.props?.requestSnippetsSelectors?.getDefaultExpanded(),
|
||||
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 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 = {
|
||||
request: PropTypes.object.isRequired,
|
||||
requestSnippetsSelectors: PropTypes.object.isRequired,
|
||||
getConfigs: PropTypes.object.isRequired,
|
||||
requestSnippetsActions: PropTypes.object.isRequired,
|
||||
const handleSetIsExpanded = () => {
|
||||
setIsExpanded(!isExpanded)
|
||||
}
|
||||
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
|
||||
? <SyntaxHighlighter
|
||||
language={activeGenerator.get("syntax")}
|
||||
className="curl microlight"
|
||||
onWheel={function(e) {return this.preventYScrollingBeyondElement(e)}}
|
||||
style={getStyle(get(config, "syntaxHighlight.theme"))}
|
||||
const handleGetBtnStyle = (key) => {
|
||||
if (key === activeLanguage) {
|
||||
return activeStyle
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
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}
|
||||
</SyntaxHighlighter>
|
||||
:
|
||||
<textarea readOnly={true} className="curl" value={snippet}></textarea>
|
||||
|
||||
const expanded = this.state.expanded === undefined ? this.props?.requestSnippetsSelectors?.getDefaultExpanded() : this.state.expanded
|
||||
return (
|
||||
<div>
|
||||
<div style={{width: "100%", display: "flex", justifyContent: "flex-start", alignItems: "center", marginBottom: "15px"}}>
|
||||
<h4
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() => this.setState({expanded: !expanded})}
|
||||
>Snippets</h4>
|
||||
<button
|
||||
onClick={() => this.setState({expanded: !expanded})}
|
||||
style={{ border: "none", background: "none" }}
|
||||
title={expanded ? "Collapse operation": "Expand operation"}
|
||||
>
|
||||
<svg className="arrow" width="10" height="10">
|
||||
<use href={expanded ? "#large-arrow-down" : "#large-arrow"} xlinkHref={expanded ? "#large-arrow-down" : "#large-arrow"} />
|
||||
</svg>
|
||||
</button>
|
||||
<svg className="arrow" width="10" height="10">
|
||||
<use href={isExpanded ? "#large-arrow-down" : "#large-arrow"} xlinkHref={isExpanded ? "#large-arrow-down" : "#large-arrow"} />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
{
|
||||
isExpanded && <div className="curl-command">
|
||||
<div style={{ paddingLeft: "15px", paddingRight: "10px", width: "100%", display: "flex" }}>
|
||||
{
|
||||
snippetGenerators.entrySeq().map(([key, gen]) => {
|
||||
return (<div style={handleGetBtnStyle(key)} className="btn" key={key} onClick={() => handleGenChange(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>
|
||||
{
|
||||
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>
|
||||
)
|
||||
}
|
||||
|
||||
RequestSnippets.propTypes = {
|
||||
request: PropTypes.object.isRequired,
|
||||
requestSnippetsSelectors: PropTypes.object.isRequired,
|
||||
getConfigs: PropTypes.object.isRequired,
|
||||
requestSnippetsActions: PropTypes.object,
|
||||
}
|
||||
|
||||
export default RequestSnippets
|
||||
|
||||
Reference in New Issue
Block a user