diff --git a/www/docs/docusaurus.config.js b/www/docs/docusaurus.config.js index b0b0704c2a..3fd94dbece 100644 --- a/www/docs/docusaurus.config.js +++ b/www/docs/docusaurus.config.js @@ -83,7 +83,8 @@ module.exports = { items: [ { label: "Stack Overflow", - href: "https://stackoverflow.com/questions/tagged/medusa-commerce", + href: + "https://stackoverflow.com/questions/tagged/medusa-commerce", }, { label: "Discord", diff --git a/www/docs/src/theme/SearchBar/index.js b/www/docs/src/theme/SearchBar/index.js index 058c6afd02..80b95c845e 100644 --- a/www/docs/src/theme/SearchBar/index.js +++ b/www/docs/src/theme/SearchBar/index.js @@ -20,8 +20,33 @@ import styles from "./styles.module.css" let DocSearchModal = null +const convertToKebabCase = (string) => { + return string + .replace(/\s+/g, "-") + .replace("'", "") + .replace(".", "") + .replace('"', "") + .toLowerCase() +} + +const replaceUrl = (item) => { + let { url, hierarchy } = item + if (url.includes("api/store") || url.includes("/api/admin")) { + url = url.replace("#", "/") + if (hierarchy.lvl2) { + const index = url.lastIndexOf("/") + url = + url.substring(0, index) + + `/${convertToKebabCase(hierarchy.lvl1)}` + + url.substring(index) + } + } + return url +} + function Hit({ hit, children }) { - return {children} + let url = replaceUrl(hit) + return {children} } function ResultsFooter({ state, onClose }) { @@ -101,8 +126,22 @@ function DocSearch({ contextualSearch, ...props }) { ) const navigator = useRef({ - navigate({ itemUrl }) { - history.push(itemUrl) + navigate({ item }) { + let url = replaceUrl(item) + history.push(url) + }, + navigateNewTab({ item }) { + let url = replaceUrl(item) + const windowReference = window.open(url, "_blank", "noopener") + + if (windowReference) { + windowReference.focus() + } + }, + navigateNewWindow({ item }) { + const url = replaceUrl(item) + + window.open(url, "_blank", "noopener") }, }).current diff --git a/www/reference/src/components/content/index.js b/www/reference/src/components/content/index.js index 1df622a02a..ccb8f39ff2 100644 --- a/www/reference/src/components/content/index.js +++ b/www/reference/src/components/content/index.js @@ -20,9 +20,11 @@ const Content = ({ data, api }) => { }, }} > - {data.sections.map((s, i) => { - return
- })} +
+ {data.sections.map((s, i) => { + return
+ })} +
) diff --git a/www/reference/src/components/content/section.js b/www/reference/src/components/content/section.js index d06f8338b4..770300f97a 100644 --- a/www/reference/src/components/content/section.js +++ b/www/reference/src/components/content/section.js @@ -14,7 +14,7 @@ import useInView from "../../hooks/use-in-view" const Section = ({ data }) => { const { section } = data - const [isExpanded, setIsExpanded] = useState(true) + const [isExpanded, setIsExpanded] = useState(false) const { openSections, updateSection, updateMetadata } = useContext( NavigationContext ) @@ -51,10 +51,6 @@ const Section = ({ data }) => { scrollIntoView() } - useEffect(() => { - setIsExpanded(false) - }, []) - useEffect(() => { const shouldOpen = openSections.includes( convertToKebabCase(section.section_name) @@ -82,11 +78,7 @@ const Section = ({ data }) => { }, [isInView]) return ( -
+
{ ) : null} - {!isExpanded ? ( + {!isExpanded && ( { SHOW - ) : ( - - {section.paths.map((p, i) => { - return ( - - {p.methods.map((m, i) => { - return ( - - ) - })} - - ) - })} - )} + + {section.paths.map((p, i) => { + return ( + + {p.methods.map((m, i) => { + return ( + + ) + })} + + ) + })} + -
+
) } diff --git a/www/reference/src/components/search/hit-component.js b/www/reference/src/components/search/hit-component.js new file mode 100644 index 0000000000..250d872206 --- /dev/null +++ b/www/reference/src/components/search/hit-component.js @@ -0,0 +1,96 @@ +import React, { useContext } from "react" +import { convertToKebabCase } from "../../utils/convert-to-kebab-case" +import NavigationContext from "../../context/navigation-context" +import { navigate } from "gatsby" + +const HitComponent = ({ hit, children }) => { + const { goTo, api } = useContext(NavigationContext) + let { url, type, hierarchy } = hit + + /** Get the API that is not currenty being viewed, so we can create + * an URL that goes to the other API. + */ + const getOtherAPI = () => { + if (api === "store") return "admin" + if (api === "admin") return "store" + } + + /** If result is part of currently viewed API then we scroll to the + * concept/method, and update the pages metadata. + */ + const goToHierarchy = e => { + e.preventDefault() + if (hierarchy.lvl2) { + goTo({ + section: convertToKebabCase(hierarchy.lvl1), + method: convertToKebabCase(hierarchy.lvl2), + }) + } else { + goTo({ section: convertToKebabCase(hierarchy.lvl1) }) + } + } + + /** If result is NOT part of currently viewed API, but still a part of + * the Gatsby site, then we use Gatsby's navigate function for improved + * linking. + */ + const navigateHierarchy = e => { + e.preventDefault() + if (hierarchy.lvl2) { + navigate( + `/api/${getOtherAPI()}/${convertToKebabCase( + hierarchy.lvl1 + )}/${convertToKebabCase(hierarchy.lvl2)}` + ) + } else { + navigate(`/api/${getOtherAPI()}/${convertToKebabCase(hierarchy.lvl1)}`) + } + } + + /** + * If result is part of the API reference then we want to strip + * the #'s from the URL's. If the result is of LVL2 then we want + * to add the LVL1 to the URL: '/store/#create-cart' -> '/store/cart/create-cart' + */ + const formatURL = () => { + url = url.replace("#", "/") + if (type === "lvl2") { + const index = url.lastIndexOf("/") + url = + url.substring(0, index) + + `/${convertToKebabCase(hierarchy.lvl1)}` + + url.substring(index) + } + } + + /** + * If the result is part of the currently viewed API + */ + if (url.includes(`api/${api}`)) { + formatURL() + return ( + + {children} + + ) + } + + /** + * If the result is NOT part of the currently viewed API + */ + if (url.includes(`api/${getOtherAPI()}`)) { + formatURL() + return ( + + {children} + + ) + } + + /** + * If the result is part of the Docasaurus docs + */ + return {children} +} + +export default HitComponent diff --git a/www/reference/src/components/search/index.js b/www/reference/src/components/search/index.js index 78d969a3ce..8af62c0057 100644 --- a/www/reference/src/components/search/index.js +++ b/www/reference/src/components/search/index.js @@ -1,11 +1,102 @@ -import React from "react" +import React, { useContext } from "react" import { DocSearch } from "@docsearch/react" import "../../medusa-plugin-themes/docsearch/theme.css" +import HitComponent from "./hit-component" +import NavigationContext from "../../context/navigation-context" +import { convertToKebabCase } from "../../utils/convert-to-kebab-case" +import { navigate } from "gatsby-link" const algoliaApiKey = process.env.ALGOLIA_API_KEY || "temp" const Search = () => { - return + const { goTo, api } = useContext(NavigationContext) + + const getOtherAPI = () => { + if (api === "store") return "admin" + if (api === "admin") return "store" + } + + const replaceUrl = item => { + let { url, hierarchy } = item + if (url.includes("api/store") || url.includes("/api/admin")) { + url = url.replace("#", "/") + if (hierarchy.lvl2) { + const index = url.lastIndexOf("/") + url = + url.substring(0, index) + + `/${convertToKebabCase(hierarchy.lvl1)}` + + url.substring(index) + } + } + return url + } + + /** If result is part of currently viewed API then we scroll to the + * concept/method, and update the pages metadata. + */ + const goToHierarchy = item => { + const { hierarchy } = item + if (hierarchy.lvl2) { + goTo({ + section: convertToKebabCase(hierarchy.lvl1), + method: convertToKebabCase(hierarchy.lvl2), + }) + } else { + goTo({ section: convertToKebabCase(hierarchy.lvl1) }) + } + } + + /** If result is NOT part of currently viewed API, but still a part of + * the Gatsby site, then we use Gatsby's navigate function for improved + * linking. + */ + const navigateHierarchy = item => { + const { hierarchy } = item + if (hierarchy.lvl2) { + navigate( + `/api/${getOtherAPI()}/${convertToKebabCase( + hierarchy.lvl1 + )}/${convertToKebabCase(hierarchy.lvl2)}` + ) + } else { + navigate(`/api/${getOtherAPI()}/${convertToKebabCase(hierarchy.lvl1)}`) + } + } + + return ( + + ) } export default Search diff --git a/www/reference/src/context/navigation-context.js b/www/reference/src/context/navigation-context.js index a25f1200bf..93a8c3e404 100644 --- a/www/reference/src/context/navigation-context.js +++ b/www/reference/src/context/navigation-context.js @@ -1,4 +1,5 @@ import React, { useReducer } from "react" +import { checkDisplay } from "../utils/check-display" import scrollParent from "../utils/scroll-parent" import types from "./types" @@ -79,10 +80,16 @@ const scrollNav = id => { const scrollToElement = async id => { const element = document.querySelector(`#${id}`) if (element) { - element.scrollIntoView({ - block: "start", - inline: "nearest", - }) + if (checkDisplay(element)) { + element.scrollIntoView({ + block: "start", + inline: "nearest", + }) + } else { + setTimeout(() => { + scrollToElement(id) + }, 100) + } } else { setTimeout(() => { scrollToElement(id) diff --git a/www/reference/src/utils/check-display.js b/www/reference/src/utils/check-display.js new file mode 100644 index 0000000000..e0b2113359 --- /dev/null +++ b/www/reference/src/utils/check-display.js @@ -0,0 +1,13 @@ +export const checkDisplay = element => { + const mc = element.closest("#method-container") + + //if no closest method container exists then it is a section and we can scroll + if (!mc) return true + + const style = getComputedStyle(mc) + if (style.display === "none") { + return false + } else { + return true + } +}