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:
Tim Lai
2022-03-24 11:23:42 -07:00
committed by GitHub
parent cd2f434438
commit 9250e209d4
4 changed files with 150 additions and 118 deletions

View File

@@ -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}

View File

@@ -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: {

View File

@@ -1,39 +1,11 @@
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(),
}
}
static propTypes = {
request: PropTypes.object.isRequired,
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 = {
const style = {
cursor: "pointer",
lineHeight: 1,
display: "inline-flex",
@@ -44,8 +16,9 @@ export class RequestSnippets extends React.Component {
borderRadius: "4px 4px 0 0",
boxShadow: "none",
borderBottom: "none"
}
const activeStyle = {
}
const activeStyle = {
cursor: "pointer",
lineHeight: 1,
display: "inline-flex",
@@ -60,20 +33,73 @@ export class RequestSnippets extends React.Component {
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 = () => {
}
const getBtnStyle = (key) => {
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)
}
}
const handleSetIsExpanded = () => {
setIsExpanded(!isExpanded)
}
const handleGetBtnStyle = (key) => {
if (key === activeLanguage) {
return activeStyle
}
return style
}
const config = getConfigs()
const SnippetComponent = config?.syntaxHighlight?.activated
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"
onWheel={function(e) {return this.preventYScrollingBeyondElement(e)}}
style={getStyle(get(config, "syntaxHighlight.theme"))}
>
{snippet}
@@ -81,31 +107,31 @@ export class RequestSnippets extends React.Component {
:
<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"}}>
<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" }}
onClick={() => this.setState({expanded: !expanded})}
>Snippets</h4>
<button
onClick={() => this.setState({expanded: !expanded})}
onClick={() => handleSetIsExpanded()}
style={{ border: "none", background: "none" }}
title={expanded ? "Collapse operation": "Expand operation"}
title={isExpanded ? "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"} />
<use href={isExpanded ? "#large-arrow-down" : "#large-arrow"} xlinkHref={isExpanded ? "#large-arrow-down" : "#large-arrow"} />
</svg>
</button>
</div>
{
expanded && <div className="curl-command">
<div style={{paddingLeft: "15px", paddingRight: "10px", width: "100%", display: "flex"}}>
isExpanded && <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>
return (<div style={handleGetBtnStyle(key)} className="btn" key={key} onClick={() => handleGenChange(key)}>
<h4 style={key === activeLanguage ? { color: "white", } : {}}>{gen.get("title")}</h4>
</div>)
})
}
@@ -121,7 +147,14 @@ export class RequestSnippets extends React.Component {
</div>
}
</div>
)
}
}
RequestSnippets.propTypes = {
request: PropTypes.object.isRequired,
requestSnippetsSelectors: PropTypes.object.isRequired,
getConfigs: PropTypes.object.isRequired,
requestSnippetsActions: PropTypes.object,
}
export default RequestSnippets

View File

@@ -6,7 +6,7 @@ import expect from "expect"
import { shallow } from "enzyme"
import LiveResponse from "components/live-response"
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 () {
let request = fromJSOrdered({