Skip to content
Snippets Groups Projects
Commit fd6fef6b authored by David Schwarzmann's avatar David Schwarzmann
Browse files

Improve API spec version loading

parent 2385c060
No related branches found
No related tags found
1 merge request!61Improve API spec version loading
......@@ -4,8 +4,5 @@ hide_table_of_contents: true
---
import ApiSpec from '@site/src/components/ApiSpec'
import VersionDisplay from '@site/src/components/VersionDisplay'
Die aktuell ausgewählte Version der API ist <VersionDisplay artifact={"zustelldienst.yml"}/>.
<ApiSpec specUrl="https://fitko.uber.space/0.9.0/zustelldienst.yml"/>
<ApiSpec artifact={"zustelldienst.yml"} />
......@@ -15,6 +15,7 @@
"@docusaurus/preset-classic": "2.0.0-beta.0",
"@mdx-js/react": "^1.6.21",
"@svgr/webpack": "^5.5.0",
"axios": "^0.21.1",
"clsx": "^1.1.1",
"file-loader": "^6.2.0",
"mermaid": "^8.10.2",
......@@ -22,6 +23,7 @@
"react": "^17.0.1",
"react-dom": "^17.0.1",
"remark-collapse": "^0.1.2",
"semver": "^7.3.5",
"url-loader": "^4.1.1"
},
"browserslist": {
......
import React from 'react'
import React, {useEffect} from 'react'
import axios from 'axios'
import semver from 'semver'
import ExecutionEnvironment from '@docusaurus/ExecutionEnvironment'
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
import BrowserOnly from '@docusaurus/BrowserOnly'
import useAsync from '@site/src/hooks/useAsync'
const SCHEMA_BASE_URL = 'https://fitko.uber.space'
const getLatestVersion = async (siteVersion) => {
return axios.get('https://git.fitko.de/api/v4/projects/1/repository/tags')
.catch((error) => {
throw `Fetching of latest tags failed with ${error.response.status}`
})
.then(async ({ data }) => {
if (siteVersion === 'next') {
return data[0].name
} else {
const versionRange = `~${siteVersion}`
const suitableVersions = await data
.filter(({ name }) => semver.satisfies(name, versionRange))
.map(({ name }) => name)
.sort()
.reverse()
console.log('suitableVersions', suitableVersions, suitableVersions[0])
return suitableVersions[0]
}
})
}
const DownloadLabel = ({ version, artifact }) => {
return <a href={`${SCHEMA_BASE_URL}/${version}/${artifact}`} download>
(herunterladen)
</a>
}
export default function ApiSpec(props) {
const isInBrowser = ExecutionEnvironment.canUseDOM
const { siteVersion = 'next' } = useDocusaurusContext().siteMetadata
const { execute, status, error, value: latestVersion } = useAsync(getLatestVersion, [siteVersion], false)
if (isInBrowser) {
useEffect(() => {
execute()
}, [])
}
return (
<BrowserOnly fallback={<div>Lädt...</div>}>
{() => {
import('rapidoc')
return (
<rapi-doc
render-style="view"
layout="column"
spec-url={props.specUrl}
theme="light"
show-info="false"
show-header="false"
show-components="false"
allow-spec-file-load="false"
info-description-headings-in-navbar="false"
allow-try="false"
primary-color="#11171a"
allow-server-selection="false"
server-url=""
/>
<div>
<p>Die aktuell angezeigte Version der API ist {status === 'success' && <code>{latestVersion}</code>} {status === 'success' && <DownloadLabel version={latestVersion} artifact={props.artifact} />}.</p>
{ status === 'success' && latestVersion && <rapi-doc
render-style="view"
layout="column"
spec-url={`${SCHEMA_BASE_URL}/${latestVersion}/${props.artifact}`}
theme="light"
show-info="false"
show-header="false"
show-components="false"
allow-spec-file-load="false"
info-description-headings-in-navbar="false"
allow-try="false"
primary-color="#11171a"
allow-server-selection="false"
server-url=""
/>}
{status === 'error' && <p>Die API-Spezifikation konnte leider nicht geladen werden.</p>}
</div>
)
}}
</BrowserOnly>
......
import React from 'react'
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
const DownloadLabel = ({ version, artifact }) => {
return <a href={`https://fitko.uber.space/${version}/${artifact}`} download>
herunterladen
</a>
}
export default function ({ artifact }) {
const { siteMetadata } = useDocusaurusContext()
return (
<span>
<code>{siteMetadata.siteVersion || 'next'}</code>&nbsp;
{siteMetadata.siteVersion ? (
<DownloadLabel version={siteMetadata.siteVersion} artifact={artifact} />
) : undefined }
</span>
)
}
import {useCallback, useEffect, useRef, useState} from "react";
const useAsync = (fn, params = [], immediate = true) => {
const [status, setStatus] = useState("idle")
const [value, setValue] = useState(null)
const [error, setError] = useState(null)
const mountedRef = useRef(true)
const execute = useCallback(() => {
setStatus("pending")
setValue(null)
setError(null)
return fn(...params)
.then((val) => {
if (!mountedRef.current) return null
setValue(val)
setStatus("success")
})
.catch((error) => {
if (!mountedRef.current) return null
setError(error)
setStatus("error")
throw err
})
}, [fn])
useEffect(async () => {
if (immediate){
execute()
}
return () => {
mountedRef.current = false
}
}, [execute, immediate])
return { execute, status, value, error }
}
export default useAsync
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment