Skip to content

Commit

Permalink
Fix: Links to Docs page didn't work
Browse files Browse the repository at this point in the history
The docs page was way too complicated anyway, so I simlified it a bit.
  • Loading branch information
reglim committed Mar 22, 2023
1 parent 21a47d3 commit b494493
Showing 1 changed file with 55 additions and 76 deletions.
131 changes: 55 additions & 76 deletions web/src/pages/Docs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@
and we need to use some of it's members, which is unsafe
*/

import React, { useCallback, useEffect, useRef, useState } from 'react'
import React, { useEffect, useRef, useState } from 'react'
import { useParams, useSearchParams } from 'react-router-dom'
import DocumentControlButtons from '../components/DocumentControlButtons'
import { useProjects } from '../data-providers/ProjectDataProvider'
import ProjectVersion from '../models/ProjectVersion'
import ProjectRepository from '../repositories/ProjectRepository'

import styles from './../style/pages/Docs.module.css'
import LoadingPage from './LoadingPage'
import NotFound from './NotFound'

export default function Docs(): JSX.Element {
export default function Docs (): JSX.Element {
const projectParam = useParams().project ?? ''
const versionParam = useParams().version ?? 'latest'
const pageParam = useParams().page ?? 'index.html'
Expand All @@ -28,7 +27,6 @@ export default function Docs(): JSX.Element {
const [versions, setVersions] = useState<ProjectVersion[]>([])
const [loadingFailed, setLoadingFailed] = useState<boolean>(false)

const { projectsWithHiddenVersions: projects } = useProjects()
const iFrameRef = useRef(null)

document.title = `${project} | docat`
Expand All @@ -37,97 +35,79 @@ export default function Docs(): JSX.Element {
setLoadingFailed(true)
}

const updateRoute = useCallback(
(
project: string,
version: string,
page: string,
hideControls: boolean
): void => {
const newState = `/#/${project}/${version}/${page}${
hideControls ? '?hide-ui=true' : ''
}`

// skip updating the route if the new state is the same as the current one
if (window.location.hash === newState.substring(1)) {
return
}

window.history.pushState({}, '', newState)
},
[]
)
const getVersionToUse = (allVersions: ProjectVersion[]): string => {
if (version === 'latest') {
// latest version -> check if there is a latest tag
const versionWithLatestTag = allVersions.find((v) =>
(v.tags ?? []).includes('latest')
)

updateRoute(project, version, page, hideUi)
// if there is a latest tag, use it,
// otherwise use the latest version by sorting
const latestVersion =
versionWithLatestTag != null
? versionWithLatestTag.name
: allVersions[allVersions.length - 1].name

useEffect(() => {
if (project === '' || project === 'none') {
setVersions([])
return
return latestVersion
}

if (projects == null || projects.length === 0) {
return
// custom version -> check if it exists
const versionsAndTags = allVersions.map((v) => [v.name, ...v.tags]).flat()

if (!versionsAndTags.includes(version)) {
return ''
}

try {
const matchingProjects = projects.filter((p) => p.name === project)
return version
}

if (matchingProjects.length !== 1) {
setLoadingFailed(true)
return
}
useEffect(() => {
const url = `/#/${project}/${version}/${page}${hideUi ? '?hide-ui=true' : ''}`

let res = matchingProjects[0].versions
// skip updating the route if the new state is the same as the current one
if (window.location.hash === url.substring(1)) {
return
}

if (res == null || res.length === 0) {
setLoadingFailed(true)
return
}
window.history.pushState({}, '', url)
}, [project, version, page, hideUi])

res = res.sort((a, b) => ProjectRepository.compareVersions(a, b))
setVersions(res)
useEffect(() => {
void (async (): Promise<void> => {
try {
let allVersions = await ProjectRepository.getVersions(project)

if (allVersions.length === 0) {
setLoadingFailed(true)
return
}

if (version !== 'latest') {
// custom version -> check if it exists
const versionsAndTags = res.map((v) => [v.name, ...v.tags]).flat()
allVersions = allVersions.sort((a, b) => ProjectRepository.compareVersions(a, b))
const versionToUse = getVersionToUse(allVersions)

if (!versionsAndTags.includes(version)) {
if (versionToUse === '') {
// version does not exist -> fail
setLoadingFailed(true)
console.log("Version doesn't exist")
return
}

return
setVersion(versionToUse)
setVersions(allVersions)
setLoadingFailed(false)
} catch (e) {
console.error(e)
setLoadingFailed(true)
}

// latest version -> check if there is a latest tag
const versionWithLatestTag = res.find((v) =>
(v.tags ?? []).includes('latest')
)

// if there is a latest tag, use it,
// otherwise use the latest version by sorting
const latestVersion =
versionWithLatestTag != null
? versionWithLatestTag.name
: res[res.length - 1].name

setVersion(latestVersion)
updateRoute(project, latestVersion, page, hideUi)
} catch (e) {
console.error(e)
setLoadingFailed(true)
}
}, [project, projects, version, page, hideUi, updateRoute])
})()
}, [project])

const handleVersionChange = (v: string): void => {
setVersion(v)
updateRoute(project, v, page, hideUi)
}

const handleHideControls = (): void => {
updateRoute(project, version, page, true)
setHideUi(true)
}

Expand All @@ -150,7 +130,6 @@ export default function Docs(): JSX.Element {
}

setPage(page)
updateRoute(project, version, page, hideUi)

// make all links in iframe open in new tab
// @ts-expect-error - ts does not find the document on the iframe
Expand All @@ -163,14 +142,14 @@ export default function Docs(): JSX.Element {
})
}

if (versions == null || versions.length === 0) {
return <LoadingPage />
}

if (loadingFailed) {
return <NotFound />
}

if (versions.length === 0) {
return <LoadingPage />
}

return (
<>
<iframe
Expand Down

0 comments on commit b494493

Please sign in to comment.