Merge branch 'master' of https://github.com/medusajs/medusa into docs/shipping-overview
This commit is contained in:
commit
e2568cb3c9
30 files changed
+5972
-3298
No files matched your search
@@ -1,3 +1,11 @@
|
||||
# Website
|
||||
|
||||
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
|
||||
|
||||
## Note Before Development
|
||||
|
||||
If you have installed the dependencies in the root of this repository (i.e., if you have a `node_modules` directory at the root of this repository), this will cause an error when running this documentation website. This is because the content resides in `docs/content` and when that content is being imported from there, a mix up can happen between the dependencies which will cause an `invalid hook call` error.
|
||||
|
||||
For that reason, we added a `clean-node-modules` script that deletes the `node_modules` directory, and we call that script before the `start` and `build` scripts are ran.
|
||||
|
||||
So, everytime you run these 2 scripts, the `node_modules` directory at the root will be deleted.
|
||||
@@ -6,7 +6,7 @@ const algoliaApiKey = process.env.ALGOLIA_API_KEY || "temp"
|
||||
|
||||
/** @type {import('@docusaurus/types').DocusaurusConfig} */
|
||||
module.exports = {
|
||||
title: "Medusa Commerce",
|
||||
title: "Medusa",
|
||||
tagline: "Explore and learn how to use Medusa",
|
||||
url: "https://docs.medusajs.com",
|
||||
baseUrl: "/",
|
||||
@@ -25,18 +25,22 @@ module.exports = {
|
||||
],
|
||||
],
|
||||
themeConfig: {
|
||||
disableSwitch: true,
|
||||
colorMode: {
|
||||
defaultMode: 'light',
|
||||
disableSwitch: true,
|
||||
},
|
||||
algolia: {
|
||||
apiKey: algoliaApiKey,
|
||||
indexName: "medusa-commerce",
|
||||
placeholder: "Search docs...",
|
||||
appId: algoliaAppId,
|
||||
contextualSearch: false,
|
||||
},
|
||||
prism: {
|
||||
defaultLanguage: "js",
|
||||
plugins: ["line-numbers", "show-language"],
|
||||
theme: require("@kiwicopple/prism-react-renderer/themes/vsDark"),
|
||||
darkTheme: require("@kiwicopple/prism-react-renderer/themes/vsDark"),
|
||||
theme: require("prism-react-renderer/themes/vsDark"),
|
||||
darkTheme: require("prism-react-renderer/themes/vsDark"),
|
||||
},
|
||||
navbar: {
|
||||
hideOnScroll: true,
|
||||
@@ -44,6 +48,7 @@ module.exports = {
|
||||
alt: "Medusa Commerce",
|
||||
src: "img/logo.svg",
|
||||
srcDark: "img/logo.svg",
|
||||
width: 100
|
||||
},
|
||||
items: [
|
||||
{
|
||||
@@ -98,12 +103,12 @@ module.exports = {
|
||||
title: "More",
|
||||
items: [
|
||||
{
|
||||
label: "Contact",
|
||||
href: "https://medusa-commere.com",
|
||||
label: "Medusa Home",
|
||||
href: "https://medusajs.com",
|
||||
},
|
||||
{
|
||||
label: "Privacy & Terms",
|
||||
href: "https://medusa-commere.com",
|
||||
label: "Contact",
|
||||
href: "https://ky5eo2x1u81.typeform.com/get-in-touch",
|
||||
},
|
||||
{
|
||||
label: "GitHub",
|
||||
@@ -112,7 +117,7 @@ module.exports = {
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `© ${new Date().getFullYear()} Medusa Commerce`,
|
||||
copyright: `© ${new Date().getFullYear()} Medusa`,
|
||||
},
|
||||
},
|
||||
presets: [
|
||||
|
||||
@@ -4,7 +4,10 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"clean-node-modules": "rm -rf ../../node_modules",
|
||||
"prestart": "yarn clean-node-modules",
|
||||
"start": "docusaurus clear && docusaurus start",
|
||||
"prebuild": "yarn clean-node-modules",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
@@ -14,17 +17,14 @@
|
||||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "2.0.0-beta.3",
|
||||
"@docusaurus/preset-classic": "2.0.0-beta.3",
|
||||
"@docusaurus/theme-search-algolia": "^2.0.0-beta.3",
|
||||
"@kiwicopple/prism-react-renderer": "github:kiwicopple/prism-react-renderer",
|
||||
"@mdx-js/react": "^1.6.21",
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"@docusaurus/core": "2.0.0-beta.17",
|
||||
"@docusaurus/preset-classic": "2.0.0-beta.17",
|
||||
"@svgr/webpack": "6.2.1",
|
||||
"clsx": "^1.1.1",
|
||||
"docusaurus2-dotenv": "^1.4.0",
|
||||
"file-loader": "^6.2.0",
|
||||
"lodash": "^4.17.21",
|
||||
"prism-react-renderer": "^1.2.1",
|
||||
"prism-react-renderer": "^1.3.1",
|
||||
"react": "^17.0.1",
|
||||
"react-dom": "^17.0.1",
|
||||
"url-loader": "^4.1.1"
|
||||
@@ -44,4 +44,4 @@
|
||||
"devDependencies": {
|
||||
"prettier": "^2.3.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
+123
-60
@@ -63,6 +63,10 @@ module.exports = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "admin/quickstart",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "how-to/create-medusa-app",
|
||||
@@ -130,7 +134,7 @@ module.exports = {
|
||||
{
|
||||
type: "category",
|
||||
label: 'Services',
|
||||
collapsed: true,
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
@@ -139,6 +143,18 @@ module.exports = {
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: 'Subscribers',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "advanced/backend/subscribers/create-subscriber",
|
||||
label: "Create a Subscriber"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: 'Shipping',
|
||||
@@ -187,82 +203,124 @@ module.exports = {
|
||||
items: [
|
||||
{
|
||||
type: "category",
|
||||
label: "Gatsby + Contentful + Medusa",
|
||||
label: "Analytics",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "how-to/headless-ecommerce-store-with-gatsby-contentful-medusa",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "how-to/making-your-store-more-powerful-with-contentful",
|
||||
id: "add-plugins/segment",
|
||||
label: "Segment",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/contentful",
|
||||
label: "CMS: Contentful",
|
||||
type: "category",
|
||||
label: "Bot",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/slack",
|
||||
label: "Slack",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/strapi",
|
||||
label: "CMS: Strapi",
|
||||
type: "category",
|
||||
label: "CMS",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/contentful",
|
||||
label: "Contentful",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/strapi",
|
||||
label: "Strapi",
|
||||
},
|
||||
{
|
||||
type: "category",
|
||||
label: "Gatsby + Contentful + Medusa",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "how-to/headless-ecommerce-store-with-gatsby-contentful-medusa",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "how-to/making-your-store-more-powerful-with-contentful",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/segment",
|
||||
label: "Analytics: Segment",
|
||||
type: "category",
|
||||
label: "Notifications",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/sendgrid",
|
||||
label: "SendGrid",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/meilisearch",
|
||||
label: "Search: MeiliSearch",
|
||||
type: "category",
|
||||
label: "Payment",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/klarna",
|
||||
label: "Klarna",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/paypal",
|
||||
label: "PayPal",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/stripe",
|
||||
label: "Stripe",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/algolia",
|
||||
label: "Search: Algolia",
|
||||
type: "category",
|
||||
label: "Search",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/algolia",
|
||||
label: "Algolia",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/meilisearch",
|
||||
label: "MeiliSearch",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/spaces",
|
||||
label: "File: Spaces",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/s3",
|
||||
label: "File: S3",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/minio",
|
||||
label: "File: MinIO",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/stripe",
|
||||
label: "Payment: Stripe",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/klarna",
|
||||
label: "Payment: Klarna",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/paypal",
|
||||
label: "Payment: PayPal",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/sendgrid",
|
||||
label: "Notification: SendGrid",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/slack",
|
||||
label: "Bot: Slack",
|
||||
type: "category",
|
||||
label: "Storage",
|
||||
items: [
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/minio",
|
||||
label: "MinIO",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/s3",
|
||||
label: "S3",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "add-plugins/spaces",
|
||||
label: "Spaces",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -295,6 +353,11 @@ module.exports = {
|
||||
id: "troubleshooting/signing-in-to-admin",
|
||||
label: "Signing in to Medusa Admin",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "troubleshooting/documentation-error",
|
||||
label: "Documentation Error",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
import React, { useEffect, useState } from "react"
|
||||
|
||||
import CloseIcon from "../close-icon"
|
||||
import styles from "./banner.module.css"
|
||||
import clsx from "clsx"
|
||||
import useThemeContext from "@theme/hooks/useThemeContext"
|
||||
import ConfLogo from "../../../static/img/logo.svg"
|
||||
import clsx from "clsx"
|
||||
import styles from "./banner.module.css"
|
||||
import {useColorMode} from '@docusaurus/theme-common';
|
||||
|
||||
const Banner = (props) => {
|
||||
const [isBannerVisible, setIsBannerVisible] = useState(true)
|
||||
const { isDarkTheme } = useThemeContext()
|
||||
const { isDarkTheme } = useColorMode()
|
||||
|
||||
const handleDismissBanner = () => {
|
||||
setIsBannerVisible(false)
|
||||
|
||||
+12
-10
@@ -62,12 +62,19 @@ p {
|
||||
|
||||
/* DocSearch */
|
||||
|
||||
html[data-theme="light"] .DocSearch-Button {
|
||||
/* html[data-theme="light"] .DocSearch-Button {
|
||||
--docsearch-searchbox-background: #fff;
|
||||
}
|
||||
|
||||
html[data-theme="dark"] .DocSearch-Button {
|
||||
--docsearch-searchbox-background: #1f1f1f;
|
||||
} */
|
||||
|
||||
.DocSearch-Button {
|
||||
width: 100%;
|
||||
max-width: 175px;
|
||||
border-radius: 8px !important;
|
||||
--docsearch-container-background: #f5f6f7;
|
||||
}
|
||||
|
||||
span.DocSearch-Button-Key {
|
||||
@@ -90,11 +97,6 @@ html[data-theme="dark"] .docusaurus-highlight-code-line {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
/* Medusa logo */
|
||||
.navbar__brand {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.navbar-github-link:before {
|
||||
content: "";
|
||||
width: 24px;
|
||||
@@ -203,10 +205,6 @@ footer .footer__items svg {
|
||||
display: none;
|
||||
}
|
||||
|
||||
footer .footer__item a:hover {
|
||||
color: white;
|
||||
}
|
||||
|
||||
@media screen and (min-width: 966px) {
|
||||
footer .footer__col {
|
||||
display: flex;
|
||||
@@ -255,3 +253,7 @@ footer {
|
||||
.prism-code div:active {
|
||||
outline: none !important;
|
||||
}
|
||||
|
||||
details summary {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -1,249 +1,10 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
import { DocSearchButton, useDocSearchKeyboardEvents } from "@docsearch/react"
|
||||
import Head from "@docusaurus/Head"
|
||||
import Link from "@docusaurus/Link"
|
||||
import { useHistory } from "@docusaurus/router"
|
||||
import { translate } from "@docusaurus/Translate"
|
||||
import { useBaseUrlUtils } from "@docusaurus/useBaseUrl"
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext"
|
||||
import useAlgoliaContextualFacetFilters from "@theme/hooks/useAlgoliaContextualFacetFilters"
|
||||
import useSearchQuery from "@theme/hooks/useSearchQuery"
|
||||
import React, { useCallback, useMemo, useRef, useState } from "react"
|
||||
import { createPortal } from "react-dom"
|
||||
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 }) {
|
||||
if (hit.url.includes("/api/store") || hit.url.includes("/api/admin")) {
|
||||
const url = replaceUrl(hit)
|
||||
return <a href={url}>{children}</a>
|
||||
}
|
||||
|
||||
return <Link to={hit.url}>{children}</Link>
|
||||
}
|
||||
|
||||
function ResultsFooter({ state, onClose }) {
|
||||
const { generateSearchPageLink } = useSearchQuery()
|
||||
|
||||
return (
|
||||
<Link to={generateSearchPageLink(state.query)} onClick={onClose}>
|
||||
See all {state.context.nbHits} results
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
function DocSearch({ contextualSearch, ...props }) {
|
||||
const { siteMetadata } = useDocusaurusContext()
|
||||
|
||||
const contextualSearchFacetFilters = useAlgoliaContextualFacetFilters()
|
||||
|
||||
const configFacetFilters = props.searchParameters?.facetFilters ?? []
|
||||
|
||||
const facetFilters = contextualSearch
|
||||
? // Merge contextual search filters with config filters
|
||||
[...contextualSearchFacetFilters, ...configFacetFilters]
|
||||
: // ... or use config facetFilters
|
||||
configFacetFilters
|
||||
|
||||
// we let user override default searchParameters if he wants to
|
||||
const searchParameters = {
|
||||
...props.searchParameters,
|
||||
facetFilters,
|
||||
}
|
||||
|
||||
const { withBaseUrl } = useBaseUrlUtils()
|
||||
const history = useHistory()
|
||||
const searchContainer = useRef(null)
|
||||
const searchButtonRef = useRef(null)
|
||||
const [isOpen, setIsOpen] = useState(false)
|
||||
const [initialQuery, setInitialQuery] = useState(null)
|
||||
|
||||
const importDocSearchModalIfNeeded = useCallback(() => {
|
||||
if (DocSearchModal) {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
return Promise.all([
|
||||
import("@docsearch/react/modal"),
|
||||
import("@docsearch/react/style"),
|
||||
import("./styles.css"),
|
||||
]).then(([{ DocSearchModal: Modal }]) => {
|
||||
DocSearchModal = Modal
|
||||
})
|
||||
}, [])
|
||||
|
||||
const onOpen = useCallback(() => {
|
||||
importDocSearchModalIfNeeded().then(() => {
|
||||
searchContainer.current = document.createElement("div")
|
||||
document.body.insertBefore(
|
||||
searchContainer.current,
|
||||
document.body.firstChild
|
||||
)
|
||||
setIsOpen(true)
|
||||
})
|
||||
}, [importDocSearchModalIfNeeded, setIsOpen])
|
||||
|
||||
const onClose = useCallback(() => {
|
||||
setIsOpen(false)
|
||||
searchContainer.current.remove()
|
||||
}, [setIsOpen])
|
||||
|
||||
const onInput = useCallback(
|
||||
(event) => {
|
||||
importDocSearchModalIfNeeded().then(() => {
|
||||
setIsOpen(true)
|
||||
setInitialQuery(event.key)
|
||||
})
|
||||
},
|
||||
[importDocSearchModalIfNeeded, setIsOpen, setInitialQuery]
|
||||
)
|
||||
|
||||
const navigator = useRef({
|
||||
navigate({ item }) {
|
||||
const url = replaceUrl(item)
|
||||
// Need to type out the entire URL to prevent it from attempting to open the page
|
||||
// as part of the docusaurus project. Which will fail.
|
||||
window.location = `https://docs.medusajs.com${url}`
|
||||
},
|
||||
navigateNewTab({ item }) {
|
||||
const 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
|
||||
|
||||
const transformItems = useRef((items) => {
|
||||
return items.map((item) => {
|
||||
// We transform the absolute URL into a relative URL.
|
||||
// Alternatively, we can use `new URL(item.url)` but it's not
|
||||
// supported in IE.
|
||||
const a = document.createElement("a")
|
||||
a.href = item.url
|
||||
|
||||
return {
|
||||
...item,
|
||||
url: withBaseUrl(`${a.pathname}${a.hash}`),
|
||||
}
|
||||
})
|
||||
}).current
|
||||
|
||||
const resultsFooterComponent = useMemo(
|
||||
() => (footerProps) => <ResultsFooter {...footerProps} onClose={onClose} />,
|
||||
[onClose]
|
||||
)
|
||||
|
||||
const transformSearchClient = useCallback(
|
||||
(searchClient) => {
|
||||
searchClient.addAlgoliaAgent("docusaurus", siteMetadata.docusaurusVersion)
|
||||
|
||||
return searchClient
|
||||
},
|
||||
[siteMetadata.docusaurusVersion]
|
||||
)
|
||||
|
||||
useDocSearchKeyboardEvents({
|
||||
isOpen,
|
||||
onOpen,
|
||||
onClose,
|
||||
onInput,
|
||||
searchButtonRef,
|
||||
})
|
||||
|
||||
const translatedSearchLabel = translate({
|
||||
id: "theme.SearchBar.label",
|
||||
message: "Search",
|
||||
description: "The ARIA label and placeholder for search button",
|
||||
})
|
||||
import React from 'react';
|
||||
import SearchBar from '@theme-original/SearchBar';
|
||||
|
||||
export default function SearchBarWrapper(props) {
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
{/* This hints the browser that the website will load data from Algolia,
|
||||
and allows it to preconnect to the DocSearch cluster. It makes the first
|
||||
query faster, especially on mobile. */}
|
||||
<link
|
||||
rel="preconnect"
|
||||
href={`https://${props.appId}-dsn.algolia.net`}
|
||||
crossOrigin="anonymous"
|
||||
/>
|
||||
</Head>
|
||||
|
||||
<div className={styles.searchBox}>
|
||||
<DocSearchButton
|
||||
onTouchStart={importDocSearchModalIfNeeded}
|
||||
onFocus={importDocSearchModalIfNeeded}
|
||||
onMouseOver={importDocSearchModalIfNeeded}
|
||||
onClick={onOpen}
|
||||
ref={searchButtonRef}
|
||||
translations={{
|
||||
buttonText: translatedSearchLabel,
|
||||
buttonAriaLabel: translatedSearchLabel,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{isOpen &&
|
||||
createPortal(
|
||||
<DocSearchModal
|
||||
onClose={onClose}
|
||||
initialScrollY={window.scrollY}
|
||||
initialQuery={initialQuery}
|
||||
navigator={navigator}
|
||||
transformItems={transformItems}
|
||||
hitComponent={Hit}
|
||||
resultsFooterComponent={resultsFooterComponent}
|
||||
transformSearchClient={transformSearchClient}
|
||||
{...props}
|
||||
searchParameters={searchParameters}
|
||||
/>,
|
||||
searchContainer.current
|
||||
)}
|
||||
<SearchBar {...props} />
|
||||
</>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function SearchBar() {
|
||||
const { siteConfig } = useDocusaurusContext()
|
||||
return <DocSearch {...siteConfig.themeConfig.algolia} />
|
||||
}
|
||||
|
||||
export default SearchBar
|
||||
+1092
-2783
File diff suppressed because it is too large.
Load diff
@@ -331,7 +331,7 @@ const createAllPages = (sections, api, siteData, createPage, template) => {
|
||||
api: api,
|
||||
title: edge.section.section_name,
|
||||
description: edge.section.schema ? edge.section.schema.description : "",
|
||||
to: { section: baseURL, method: null },
|
||||
to: { section: baseURL, method: null, sectionObj: edge.section },
|
||||
},
|
||||
})
|
||||
edge.section.paths.forEach(p => {
|
||||
@@ -345,7 +345,7 @@ const createAllPages = (sections, api, siteData, createPage, template) => {
|
||||
api: api,
|
||||
title: method.summary,
|
||||
description: method.description || "",
|
||||
to: { section: baseURL, method: methodURL },
|
||||
to: { section: baseURL, method: methodURL, sectionObj: edge.section },
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React from "react"
|
||||
import { Box, Flex } from "theme-ui"
|
||||
import Topbar from "../topbar"
|
||||
import Section from "./section"
|
||||
|
||||
const Content = ({ data, api }) => {
|
||||
import React from "react"
|
||||
import Section from "./section"
|
||||
import Topbar from "../topbar"
|
||||
|
||||
const Content = ({ data, currentSection, api }) => {
|
||||
return (
|
||||
<Flex
|
||||
sx={{
|
||||
@@ -20,11 +21,7 @@ const Content = ({ data, api }) => {
|
||||
},
|
||||
}}
|
||||
>
|
||||
<main className="DocSearch-content">
|
||||
{data.sections.map((s, i) => {
|
||||
return <Section key={i} data={s} api={api} />
|
||||
})}
|
||||
</main>
|
||||
<Section data={currentSection} api={api} />
|
||||
</Box>
|
||||
</Flex>
|
||||
)
|
||||
|
||||
@@ -13,7 +13,7 @@ import { formatMethodParams } from "../../utils/format-parameters"
|
||||
import { formatRoute } from "../../utils/format-route"
|
||||
import useInView from "../../hooks/use-in-view"
|
||||
|
||||
const Method = ({ data, section, pathname, api }) => {
|
||||
const Method = ({ data, section, sectionData, pathname, api }) => {
|
||||
const { parameters, requestBody, description, method, summary } = data
|
||||
const jsonResponse = data.responses[0].content?.[0].json
|
||||
const { updateHash, updateMetadata } = useContext(NavigationContext)
|
||||
@@ -27,7 +27,7 @@ const Method = ({ data, section, pathname, api }) => {
|
||||
|
||||
useEffect(() => {
|
||||
if (isInView) {
|
||||
updateHash(section, convertToKebabCase(summary))
|
||||
updateHash(section, convertToKebabCase(summary), sectionData)
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [isInView])
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import React, { useState, useRef, useEffect, useContext } from "react"
|
||||
import { Flex, Box, Heading, Text, Button } from "theme-ui"
|
||||
import Method from "./method"
|
||||
import Parameters from "./parameters"
|
||||
import { convertToKebabCase } from "../../utils/convert-to-kebab-case"
|
||||
import EndpointContainer from "./endpoint-container"
|
||||
import Markdown from "react-markdown"
|
||||
import JsonContainer from "./json-container"
|
||||
import ResponsiveContainer from "./responsive-container"
|
||||
import Description from "./description"
|
||||
import NavigationContext from "../../context/navigation-context"
|
||||
import { Box, Button, Flex, Heading, Text } from "theme-ui"
|
||||
import React, { useContext, useEffect, useRef, useState } from "react"
|
||||
|
||||
import ChevronDown from "../icons/chevron-down"
|
||||
import Description from "./description"
|
||||
import EndpointContainer from "./endpoint-container"
|
||||
import JsonContainer from "./json-container"
|
||||
import Markdown from "react-markdown"
|
||||
import Method from "./method"
|
||||
import NavigationContext from "../../context/navigation-context"
|
||||
import Parameters from "./parameters"
|
||||
import ResponsiveContainer from "./responsive-container"
|
||||
import { convertToKebabCase } from "../../utils/convert-to-kebab-case"
|
||||
import useInView from "../../hooks/use-in-view"
|
||||
|
||||
const Section = ({ data, api }) => {
|
||||
const { section } = data
|
||||
const section = data;
|
||||
const [isExpanded, setIsExpanded] = useState(false)
|
||||
const { openSections, updateSection, updateMetadata } = useContext(
|
||||
const { openSections, updateSection, updateMetadata, updateHash } = useContext(
|
||||
NavigationContext
|
||||
)
|
||||
|
||||
@@ -61,6 +62,12 @@ const Section = ({ data, api }) => {
|
||||
}
|
||||
}, [section.section_name, openSections, openSections.length])
|
||||
|
||||
useEffect(() => {
|
||||
if (section.section_name) {
|
||||
updateHash(convertToKebabCase(section.section_name), section.paths && section.paths.length ? (section.paths[0].methods[0].path || '') : '', section)
|
||||
}
|
||||
}, [section.section_name])
|
||||
|
||||
const [containerRef, isInView] = useInView({
|
||||
root: null,
|
||||
rootMargin: "0px 0px -80% 0px",
|
||||
@@ -70,7 +77,7 @@ const Section = ({ data, api }) => {
|
||||
useEffect(() => {
|
||||
const handleInView = () => {
|
||||
if (isInView) {
|
||||
updateSection(convertToKebabCase(section.section_name))
|
||||
updateSection({id: convertToKebabCase(section.section_name), section})
|
||||
}
|
||||
}
|
||||
handleInView()
|
||||
@@ -188,6 +195,7 @@ const Section = ({ data, api }) => {
|
||||
key={i}
|
||||
data={m}
|
||||
section={convertToKebabCase(section.section_name)}
|
||||
sectionData={section}
|
||||
pathname={p.name}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -1,10 +1,30 @@
|
||||
import { Box, Flex } from "theme-ui"
|
||||
|
||||
import React from "react"
|
||||
import { Flex, Box } from "theme-ui"
|
||||
import Sidebar from "./side-bar"
|
||||
import styled from "@emotion/styled"
|
||||
|
||||
const LayoutContainer = styled(Flex)`
|
||||
--side-bar-width: 220px;
|
||||
|
||||
@media screen and (min-width: 1680px) {
|
||||
--side-bar-width: 280px;
|
||||
}
|
||||
`
|
||||
|
||||
const ContentBox = styled(Box)`
|
||||
@media screen and (min-width: 849px) {
|
||||
width: calc(100% - var(--side-bar-width));
|
||||
}
|
||||
|
||||
@media screen and (max-width: 848px) {
|
||||
width: 100%;
|
||||
}
|
||||
`
|
||||
|
||||
const Layout = ({ data, api, children }) => {
|
||||
return (
|
||||
<Flex sx={{ p: "0", m: "0", overflow: "hidden" }}>
|
||||
<LayoutContainer sx={{ p: "0", m: "0", overflow: "hidden" }}>
|
||||
<Flex
|
||||
sx={{
|
||||
position: "absolute",
|
||||
@@ -17,9 +37,9 @@ const Layout = ({ data, api, children }) => {
|
||||
}}
|
||||
>
|
||||
<Sidebar data={data} api={api} />
|
||||
<Box>{children}</Box>
|
||||
<ContentBox>{children}</ContentBox>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</LayoutContainer>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import React, { useContext } from "react"
|
||||
import { convertToKebabCase } from "../../utils/convert-to-kebab-case"
|
||||
|
||||
import NavigationContext from "../../context/navigation-context"
|
||||
import { convertToKebabCase } from "../../utils/convert-to-kebab-case"
|
||||
import { navigate } from "gatsby"
|
||||
|
||||
const HitComponent = ({ hit, children }) => {
|
||||
const HitComponent = ({ hit, children, data }) => {
|
||||
const { goTo, api } = useContext(NavigationContext)
|
||||
let { url, type, hierarchy } = hit
|
||||
|
||||
@@ -20,13 +21,17 @@ const HitComponent = ({ hit, children }) => {
|
||||
*/
|
||||
const goToHierarchy = e => {
|
||||
e.preventDefault()
|
||||
//find section
|
||||
let section = data.sections.find((s) => s.section.section_name == hierarchy.lvl1);
|
||||
section = section ? section.section : {}
|
||||
if (hierarchy.lvl2) {
|
||||
goTo({
|
||||
section: convertToKebabCase(hierarchy.lvl1),
|
||||
method: convertToKebabCase(hierarchy.lvl2),
|
||||
sectionObj: section
|
||||
})
|
||||
} else {
|
||||
goTo({ section: convertToKebabCase(hierarchy.lvl1) })
|
||||
goTo({ section: convertToKebabCase(hierarchy.lvl1), sectionObj: section })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import React, { useContext } from "react"
|
||||
import { DocSearch } from "@docsearch/react"
|
||||
import "../../medusa-plugin-themes/docsearch/theme.css"
|
||||
|
||||
import React, { useContext } from "react"
|
||||
|
||||
import { DocSearch } from "@docsearch/react"
|
||||
import HitComponent from "./hit-component"
|
||||
import NavigationContext from "../../context/navigation-context"
|
||||
import { convertToKebabCase } from "../../utils/convert-to-kebab-case"
|
||||
@@ -8,7 +10,7 @@ import { navigate } from "gatsby-link"
|
||||
|
||||
const algoliaApiKey = process.env.ALGOLIA_API_KEY || "temp"
|
||||
|
||||
const Search = () => {
|
||||
const Search = ({data}) => {
|
||||
const { goTo, api } = useContext(NavigationContext)
|
||||
|
||||
const getOtherAPI = () => {
|
||||
@@ -36,13 +38,17 @@ const Search = () => {
|
||||
*/
|
||||
const goToHierarchy = item => {
|
||||
const { hierarchy } = item
|
||||
//find section
|
||||
let section = data.sections.find((s) => s.section.section_name == hierarchy.lvl1);
|
||||
section = section ? section.section : {}
|
||||
if (hierarchy.lvl2) {
|
||||
goTo({
|
||||
section: convertToKebabCase(hierarchy.lvl1),
|
||||
method: convertToKebabCase(hierarchy.lvl2),
|
||||
sectionObj: section
|
||||
})
|
||||
} else {
|
||||
goTo({ section: convertToKebabCase(hierarchy.lvl1) })
|
||||
goTo({ section: convertToKebabCase(hierarchy.lvl1), sectionObj: section })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +73,7 @@ const Search = () => {
|
||||
<DocSearch
|
||||
apiKey={algoliaApiKey}
|
||||
indexName="medusa-commerce"
|
||||
hitComponent={HitComponent}
|
||||
hitComponent={({hit, children}) => <HitComponent data={data} hit={hit} children={children} />}
|
||||
navigator={{
|
||||
navigate({ item }) {
|
||||
if (item.url.includes(`api/${api}`)) {
|
||||
|
||||
@@ -1,19 +1,14 @@
|
||||
import { Box, Flex, Image } from "theme-ui"
|
||||
import React, { useEffect, useState } from "react"
|
||||
import { Flex, Image, Box } from "theme-ui"
|
||||
import styled from "@emotion/styled"
|
||||
|
||||
import Logo from "../../assets/logo.svg"
|
||||
import LogoMuted from "../../assets/logo-muted.svg"
|
||||
import SideBarItem from "./sidebar-item"
|
||||
import SideBarSelector from "./sidebar-selector"
|
||||
import { navigate } from "gatsby"
|
||||
import styled from "@emotion/styled"
|
||||
|
||||
const SideBarContainer = styled(Flex)`
|
||||
--side-bar-width: 220px;
|
||||
|
||||
@media screen and (min-width: 1680px) {
|
||||
--side-bar-width: 280px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 848px) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import React, { useContext } from "react"
|
||||
import Collapsible from "react-collapsible"
|
||||
import { Flex, Box, Text } from "theme-ui"
|
||||
import styled from "@emotion/styled"
|
||||
import { convertToKebabCase } from "../../utils/convert-to-kebab-case"
|
||||
import { Box, Flex, Text } from "theme-ui"
|
||||
import React, { useContext, useEffect, useState } from "react"
|
||||
|
||||
import ChevronDown from "../icons/chevron-down"
|
||||
import Collapsible from "react-collapsible"
|
||||
import NavigationContext from "../../context/navigation-context"
|
||||
import { convertToKebabCase } from "../../utils/convert-to-kebab-case"
|
||||
import styled from "@emotion/styled"
|
||||
|
||||
const StyledCollapsible = styled(Collapsible)`
|
||||
margin-bottom: 10px;
|
||||
@@ -26,6 +27,7 @@ const SideBarItem = ({ item }) => {
|
||||
currentSection,
|
||||
goTo,
|
||||
} = useContext(NavigationContext)
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const { section } = item
|
||||
const subItems = section.paths
|
||||
.map(p => {
|
||||
@@ -47,16 +49,21 @@ const SideBarItem = ({ item }) => {
|
||||
if (element) {
|
||||
element.scrollIntoView()
|
||||
if (!openSections.includes(id)) {
|
||||
openSection(id)
|
||||
openSection({id, section})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubClick = path => {
|
||||
const id = convertToKebabCase(section.section_name)
|
||||
goTo({ section: id, method: path })
|
||||
goTo({ section: id, method: path, sectionObj: section })
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
setIsOpen(currentSection === convertToKebabCase(section.section_name) ||
|
||||
openSections.includes(convertToKebabCase(section.section_name)));
|
||||
}, [section.section_name, currentSection, openSections])
|
||||
|
||||
return (
|
||||
<Container id={`nav-${convertToKebabCase(section.section_name)}`}>
|
||||
<StyledCollapsible
|
||||
@@ -86,10 +93,7 @@ const SideBarItem = ({ item }) => {
|
||||
{section.section_name} <ChevronDown />
|
||||
</Flex>
|
||||
}
|
||||
open={
|
||||
currentSection === convertToKebabCase(section.section_name) ||
|
||||
openSections.includes(convertToKebabCase(section.section_name))
|
||||
}
|
||||
open={isOpen}
|
||||
onTriggerOpening={handleClick}
|
||||
transitionTime={1}
|
||||
>
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Box, Flex, Link, Select } from "@theme-ui/components"
|
||||
import { navigate } from "gatsby-link"
|
||||
import React, { useContext } from "react"
|
||||
|
||||
import ChevronDown from "./icons/chevron-down"
|
||||
import GitHub from "../components/icons/github"
|
||||
import NavigationContext from "../context/navigation-context"
|
||||
import { convertToKebabCase } from "../utils/convert-to-kebab-case"
|
||||
import ChevronDown from "./icons/chevron-down"
|
||||
import Search from "./search"
|
||||
|
||||
import { convertToKebabCase } from "../utils/convert-to-kebab-case"
|
||||
import { navigate } from "gatsby-link"
|
||||
|
||||
const Topbar = ({ data, api }) => {
|
||||
const { goTo, reset, currentSection } = useContext(NavigationContext)
|
||||
@@ -15,7 +15,10 @@ const Topbar = ({ data, api }) => {
|
||||
const parts = e.target.value.split(" ")
|
||||
|
||||
if (parts[0] === api) {
|
||||
goTo({ section: parts[1] })
|
||||
//find section
|
||||
let sectionObj = data.sections.find((s) => convertToKebabCase(s.section.section_name) === parts[1]);
|
||||
sectionObj = sectionObj ? sectionObj.section : {};
|
||||
goTo({ section: parts[1], sectionObj })
|
||||
} else {
|
||||
reset()
|
||||
navigate(`/api/${api === "admin" ? "store" : "admin"}`)
|
||||
@@ -112,7 +115,7 @@ const Topbar = ({ data, api }) => {
|
||||
>
|
||||
<GitHub />
|
||||
</Link>
|
||||
<Search />
|
||||
<Search data={data} />
|
||||
</Flex>
|
||||
</Flex>
|
||||
)
|
||||
|
||||
@@ -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"
|
||||
@@ -7,6 +8,11 @@ export const defaultNavigationContext = {
|
||||
api: "null",
|
||||
setApi: () => {},
|
||||
currentSection: null,
|
||||
currentSectionObj: {
|
||||
section_name: "",
|
||||
paths: [],
|
||||
schema: {}
|
||||
},
|
||||
updateSection: () => {},
|
||||
currentHash: null,
|
||||
updateHash: () => {},
|
||||
@@ -21,6 +27,7 @@ const NavigationContext = React.createContext(defaultNavigationContext)
|
||||
export default NavigationContext
|
||||
|
||||
const reducer = (state, action) => {
|
||||
let obj = []
|
||||
switch (action.type) {
|
||||
case types.SET_API: {
|
||||
return {
|
||||
@@ -29,23 +36,30 @@ const reducer = (state, action) => {
|
||||
}
|
||||
}
|
||||
case types.UPDATE_HASH:
|
||||
return {
|
||||
...state,
|
||||
currentSection: action.payload.section,
|
||||
currentHash: action.payload.method,
|
||||
}
|
||||
case types.UPDATE_SECTION:
|
||||
return {
|
||||
...state,
|
||||
currentSection: action.payload,
|
||||
currentHash: null,
|
||||
}
|
||||
case types.OPEN_SECTION:
|
||||
const obj = state.openSections
|
||||
obj.push(action.payload)
|
||||
obj.push(action.payload.section)
|
||||
return {
|
||||
...state,
|
||||
openSections: obj,
|
||||
currentSection: action.payload.section,
|
||||
currentHash: action.payload.method,
|
||||
currentSectionObj: action.payload.sectionObj
|
||||
}
|
||||
case types.UPDATE_SECTION:
|
||||
obj.push(action.payload.id)
|
||||
return {
|
||||
...state,
|
||||
openSections: obj,
|
||||
currentSection: action.payload.id,
|
||||
currentHash: null,
|
||||
currentSectionObj: action.payload.section
|
||||
}
|
||||
case types.OPEN_SECTION:
|
||||
obj.push(action.payload.id)
|
||||
return {
|
||||
...state,
|
||||
openSections: obj,
|
||||
currentSection: action.payload.id,
|
||||
currentSectionObj: action.payload.section
|
||||
}
|
||||
case types.RESET:
|
||||
return {
|
||||
@@ -53,6 +67,11 @@ const reducer = (state, action) => {
|
||||
openSections: [],
|
||||
currentSection: null,
|
||||
currentHash: null,
|
||||
currentSectionObj: {
|
||||
section_name: "",
|
||||
paths: [],
|
||||
schema: {}
|
||||
}
|
||||
}
|
||||
case types.UPDATE_METADATA:
|
||||
return {
|
||||
@@ -108,10 +127,10 @@ export const NavigationProvider = ({ children }) => {
|
||||
dispatch({ type: types.UPDATE_METADATA, payload: metadata })
|
||||
}
|
||||
|
||||
const updateHash = (section, method) => {
|
||||
const updateHash = (section, method, sectionObj) => {
|
||||
dispatch({
|
||||
type: types.UPDATE_HASH,
|
||||
payload: { method: method, section: section },
|
||||
payload: { method: method, section: section, sectionObj },
|
||||
})
|
||||
window.history.replaceState(
|
||||
null,
|
||||
@@ -121,21 +140,21 @@ export const NavigationProvider = ({ children }) => {
|
||||
scrollNav(method)
|
||||
}
|
||||
|
||||
const updateSection = section => {
|
||||
dispatch({ type: types.UPDATE_SECTION, payload: section })
|
||||
window.history.replaceState(null, "", `/api/${state.api}/${section}`)
|
||||
scrollNav(section)
|
||||
const updateSection = ({id, section}) => {
|
||||
dispatch({ type: types.UPDATE_SECTION, payload: {id, section} })
|
||||
window.history.replaceState(null, "", `/api/${state.api}/${id}`)
|
||||
scrollNav(id)
|
||||
}
|
||||
|
||||
const openSection = sectionName => {
|
||||
dispatch({ type: types.OPEN_SECTION, payload: sectionName })
|
||||
const openSection = ({id, section}) => {
|
||||
dispatch({ type: types.OPEN_SECTION, payload: {id, section} })
|
||||
}
|
||||
|
||||
const goTo = to => {
|
||||
const { section, method } = to
|
||||
const { section, method, sectionObj } = to
|
||||
|
||||
if (!state.openSections.includes(section)) {
|
||||
openSection(section)
|
||||
openSection({id: section, section: sectionObj})
|
||||
}
|
||||
scrollToElement(method || section)
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import React, { useContext, useEffect, useState } from "react"
|
||||
import { Helmet } from "react-helmet"
|
||||
|
||||
import Layout from "../components/layout"
|
||||
import Content from "../components/content"
|
||||
import { Helmet } from "react-helmet"
|
||||
import Layout from "../components/layout"
|
||||
import NavigationContext from "../context/navigation-context"
|
||||
import { convertToKebabCase } from "../utils/convert-to-kebab-case"
|
||||
|
||||
export default function ReferencePage({
|
||||
pageContext: { data, api, title, description, to },
|
||||
}) {
|
||||
const { setApi, goTo, metadata } = useContext(NavigationContext)
|
||||
const { setApi, goTo, metadata, currentSection, currentSectionObj } = useContext(NavigationContext)
|
||||
const [siteData, setSiteData] = useState({
|
||||
title: title,
|
||||
description: description,
|
||||
@@ -18,6 +19,14 @@ export default function ReferencePage({
|
||||
setApi(api)
|
||||
if (to) {
|
||||
goTo(to)
|
||||
} else if (data.sections && data.sections.length) {
|
||||
//go to the first section
|
||||
const firstSection = data.sections[0].section;
|
||||
goTo({
|
||||
section: convertToKebabCase(firstSection.section_name),
|
||||
method: firstSection.paths && firstSection.paths.length ? firstSection.paths[0].methods[0].method : '',
|
||||
sectionObj: firstSection
|
||||
})
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
@@ -34,10 +43,10 @@ export default function ReferencePage({
|
||||
return (
|
||||
<Layout data={data} api={api}>
|
||||
<Helmet>
|
||||
<title>{`API | Medusa Commerce API Reference`}</title>
|
||||
<title>{`API | Medusa API Reference`}</title>
|
||||
<meta name="description" content={siteData.description} />
|
||||
</Helmet>
|
||||
<Content data={data} api={api} />
|
||||
<Content data={data} currentSection={currentSectionObj} api={api} />
|
||||
</Layout>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user