Fixes #3596 - Deep linking issue with spacesbubble
@@ -41,6 +41,7 @@ | |||||
"dependencies": { | "dependencies": { | ||||
"base64-js": "^1.2.0", | "base64-js": "^1.2.0", | ||||
"brace": "0.7.0", | "brace": "0.7.0", | ||||
"css.escape": "1.5.1", | |||||
"deep-extend": "0.4.1", | "deep-extend": "0.4.1", | ||||
"expect": "1.20.2", | "expect": "1.20.2", | ||||
"getbase": "^2.8.2", | "getbase": "^2.8.2", | ||||
@@ -1,7 +1,7 @@ | |||||
import React from "react" | import React from "react" | ||||
import PropTypes from "prop-types" | import PropTypes from "prop-types" | ||||
import { helpers } from "swagger-client" | import { helpers } from "swagger-client" | ||||
import { createDeepLinkPath } from "core/utils" | |||||
const { opId } = helpers | const { opId } = helpers | ||||
export default class Operations extends React.Component { | export default class Operations extends React.Component { | ||||
@@ -69,7 +69,7 @@ export default class Operations extends React.Component { | |||||
let tagExternalDocsDescription = tagObj.getIn(["tagDetails", "externalDocs", "description"]) | let tagExternalDocsDescription = tagObj.getIn(["tagDetails", "externalDocs", "description"]) | ||||
let tagExternalDocsUrl = tagObj.getIn(["tagDetails", "externalDocs", "url"]) | let tagExternalDocsUrl = tagObj.getIn(["tagDetails", "externalDocs", "url"]) | ||||
let isShownKey = ["operations-tag", tag] | |||||
let isShownKey = ["operations-tag", createDeepLinkPath(tag)] | |||||
let showTag = layoutSelectors.isShown(isShownKey, docExpansion === "full" || docExpansion === "list") | let showTag = layoutSelectors.isShown(isShownKey, docExpansion === "full" || docExpansion === "list") | ||||
return ( | return ( | ||||
@@ -124,7 +124,7 @@ export default class Operations extends React.Component { | |||||
const operationId = | const operationId = | ||||
op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), path, method) || op.get("id") | op.getIn(["operation", "operationId"]) || op.getIn(["operation", "__originalOperationId"]) || opId(op.get("operation"), path, method) || op.get("id") | ||||
const isShownKey = ["operations", tag, operationId] | |||||
const isShownKey = ["operations", createDeepLinkPath(tag), createDeepLinkPath(operationId)] | |||||
const allowTryItOut = specSelectors.allowTryItOutFor(op.get("path"), op.get("method")) | const allowTryItOut = specSelectors.allowTryItOutFor(op.get("path"), op.get("method")) | ||||
const response = specSelectors.responseFor(op.get("path"), op.get("method")) | const response = specSelectors.responseFor(op.get("path"), op.get("method")) | ||||
@@ -1,4 +1,5 @@ | |||||
import { setHash } from "./helpers" | import { setHash } from "./helpers" | ||||
import { createDeepLinkPath } from "core/utils" | |||||
export const show = (ori, { getConfigs }) => (...args) => { | export const show = (ori, { getConfigs }) => (...args) => { | ||||
ori(...args) | ori(...args) | ||||
@@ -19,12 +20,12 @@ export const show = (ori, { getConfigs }) => (...args) => { | |||||
if(type === "operations") { | if(type === "operations") { | ||||
let [, tag, operationId] = thing | let [, tag, operationId] = thing | ||||
setHash(`/${tag}/${operationId}`) | |||||
setHash(`/${createDeepLinkPath(tag)}/${createDeepLinkPath(operationId)}`) | |||||
} | } | ||||
if(type === "operations-tag") { | if(type === "operations-tag") { | ||||
let [, tag] = thing | let [, tag] = thing | ||||
setHash(`/${tag}`) | |||||
setHash(`/${createDeepLinkPath(tag)}`) | |||||
} | } | ||||
} | } | ||||
@@ -1,4 +1,5 @@ | |||||
import scrollTo from "scroll-to-element" | import scrollTo from "scroll-to-element" | ||||
import { escapeDeepLinkPath } from "core/utils" | |||||
const SCROLL_OFFSET = -5 | const SCROLL_OFFSET = -5 | ||||
let hasHashBeenParsed = false | let hasHashBeenParsed = false | ||||
@@ -34,14 +35,14 @@ export const updateResolved = (ori, { layoutActions, getConfigs }) => (...args) | |||||
layoutActions.show(["operations-tag", tag], true) | layoutActions.show(["operations-tag", tag], true) | ||||
layoutActions.show(["operations", tag, operationId], true) | layoutActions.show(["operations", tag, operationId], true) | ||||
scrollTo(`#operations-${tag}-${operationId}`, { | |||||
scrollTo(`#operations-${escapeDeepLinkPath(tag)}-${escapeDeepLinkPath(operationId)}`, { | |||||
offset: SCROLL_OFFSET | offset: SCROLL_OFFSET | ||||
}) | }) | ||||
} else if(tag) { | } else if(tag) { | ||||
// Pre-expand and scroll to the tag | // Pre-expand and scroll to the tag | ||||
layoutActions.show(["operations-tag", tag], true) | layoutActions.show(["operations-tag", tag], true) | ||||
scrollTo(`#operations-tag-${tag}`, { | |||||
scrollTo(`#operations-tag-${escapeDeepLinkPath(tag)}`, { | |||||
offset: SCROLL_OFFSET | offset: SCROLL_OFFSET | ||||
}) | }) | ||||
} | } | ||||
@@ -8,6 +8,7 @@ import some from "lodash/some" | |||||
import eq from "lodash/eq" | import eq from "lodash/eq" | ||||
import { memoizedSampleFromSchema, memoizedCreateXMLExample } from "core/plugins/samples/fn" | import { memoizedSampleFromSchema, memoizedCreateXMLExample } from "core/plugins/samples/fn" | ||||
import win from "./window" | import win from "./window" | ||||
import cssEscape from "css.escape" | |||||
const DEFAULT_REPONSE_KEY = "default" | const DEFAULT_REPONSE_KEY = "default" | ||||
@@ -650,3 +651,6 @@ export const shallowEqualKeys = (a,b, keys) => { | |||||
return eq(a[key], b[key]) | return eq(a[key], b[key]) | ||||
}) | }) | ||||
} | } | ||||
export const createDeepLinkPath = (str) => str ? str.replace(/\s/g, "_") : "" | |||||
export const escapeDeepLinkPath = (str) => cssEscape( createDeepLinkPath(str) ) |