Skip to content

Commit

Permalink
Merge pull request #494 from docat-org/feature/480-not-latest-version…
Browse files Browse the repository at this point in the history
…-banner

Feature: Add Info banner if user is not on latest version
  • Loading branch information
randombenj authored Apr 12, 2023
2 parents 3d8d18b + bd4cbc0 commit 1049824
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 44 deletions.
28 changes: 7 additions & 21 deletions web/src/components/InfoBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,29 @@ import React, { useEffect, useState } from 'react'
import { Message } from '../data-providers/MessageBannerProvider'

interface Props {
errorMsg?: string
successMsg?: string
message: Message
}

export default function Banner(props: Props): JSX.Element {
const messageFromProps = (props: Props): Message => {
if (props.errorMsg != null && props.errorMsg.trim() !== '') {
return { text: props.errorMsg, type: 'error' }
}
if (props.successMsg != null && props.successMsg.trim() !== '') {
return { text: props.successMsg, type: 'success' }
}

return { text: undefined, type: 'success' }
}

const [msg, setMsg] = useState<Message>(messageFromProps(props))
export default function Banner (props: Props): JSX.Element {
const [show, setShow] = useState<boolean>(false)

useEffect(() => {
setShow(true)
setMsg(messageFromProps(props))
}, [props])
}, [props.message])

return (
<Snackbar
key={uniqueId()}
open={show && msg.text != null}
autoHideDuration={6000}
open={show && props.message.content != null}
autoHideDuration={props.message.showMs}
onClose={() => setShow(false)}
>
<Alert
onClose={() => setShow(false)}
severity={msg.type}
severity={props.message.type}
sx={{ width: '100%' }}
>
{msg.text}
{props.message.content}
</Alert>
</Snackbar>
)
Expand Down
33 changes: 18 additions & 15 deletions web/src/data-providers/MessageBannerProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import React, { useState, useCallback, useContext } from 'react'
import Banner from '../components/InfoBanner'

export interface Message {
text: string | undefined
type: 'error' | 'success'
content: string | JSX.Element | undefined
type: 'success' | 'info' | 'warning' | 'error'
showMs: number | null // null = infinite
}

interface MessageBannerState {
Expand All @@ -22,14 +23,13 @@ export const Context = React.createContext<MessageBannerState>({
}
})

export function MessageBannerProvider({ children }: any): JSX.Element {
export function MessageBannerProvider ({ children }: any): JSX.Element {
// We need to store the last timeout, so we can clear when a new message is shown
const [lastTimeout, setLastTimeout] = useState<NodeJS.Timeout | undefined>(
undefined
)
const [lastTimeout, setLastTimeout] = useState<NodeJS.Timeout>()
const [message, setMessage] = useState<Message>({
text: undefined,
type: 'success'
content: undefined,
type: 'success',
showMs: 6000
})

const showMessage = useCallback((message: Message) => {
Expand All @@ -39,25 +39,28 @@ export function MessageBannerProvider({ children }: any): JSX.Element {

setMessage(message)

if (message.showMs === null) {
// don't hide message
return
}

// Hide message after 6 seconds
const newTimeout = setTimeout(
() =>
setMessage({
text: undefined,
type: 'success'
content: undefined,
type: 'success',
showMs: 6000
}),
6000
message.showMs
)

setLastTimeout(newTimeout)
}, [])

return (
<Context.Provider value={{ showMessage }}>
<Banner
successMsg={message.type === 'success' ? message.text : undefined}
errorMsg={message.type === 'error' ? message.text : undefined}
/>
<Banner message={message} />
{children}
</Context.Provider>
)
Expand Down
5 changes: 3 additions & 2 deletions web/src/data-providers/ProjectDataProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ export function ProjectDataProvider({ children }: any): JSX.Element {
console.error(e)

showMessage({
text: 'Failed to load projects',
type: 'error'
content: 'Failed to load projects',
type: 'error',
showMs: 6000
})

setProjects({
Expand Down
5 changes: 3 additions & 2 deletions web/src/pages/Claim.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ export default function Claim(): JSX.Element {
} catch (e) {
console.error(e)
showMessage({
text: (e as { message: string }).message,
type: 'error'
content: (e as { message: string }).message,
type: 'error',
showMs: 6000
})
}
}
Expand Down
6 changes: 4 additions & 2 deletions web/src/pages/Delete.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ export default function Delete(): JSX.Element {

showMessage({
type: 'success',
text: `Documentation for ${project} (${version}) deleted successfully.`
content: `Documentation for ${project} (${version}) deleted successfully.`,
showMs: 6000
})
setProject('none')
setVersion('none')
Expand All @@ -65,7 +66,8 @@ export default function Delete(): JSX.Element {

showMessage({
type: 'error',
text: (e as { message: string }).message
content: (e as { message: string }).message,
showMs: 6000
})
}
})()
Expand Down
21 changes: 21 additions & 0 deletions web/src/pages/Docs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import NotFound from './NotFound'

import styles from './../style/pages/Docs.module.css'
import { uniqueId } from 'lodash'
import { useMessageBanner } from '../data-providers/MessageBannerProvider'

export default function Docs (): JSX.Element {
const projectParam = useParams().project ?? ''
Expand All @@ -31,6 +32,7 @@ export default function Docs (): JSX.Element {
const [versions, setVersions] = useState<ProjectDetails[]>([])
const [loadingFailed, setLoadingFailed] = useState<boolean>(false)

const { showMessage } = useMessageBanner()
const location = useLocation()
const iFrameRef = useRef<HTMLIFrameElement>(null)

Expand Down Expand Up @@ -186,6 +188,25 @@ export default function Docs (): JSX.Element {
}
}, [location])

useEffect(() => {
// check every time the version changes whether the version
// is the latest version and if not, show a banner
if (versions.length === 0) {
return
}

const latestVersion = ProjectRepository.getLatestVersion(versions).name
if (version === latestVersion) {
return
}

showMessage({
content: 'You are viewing an outdated version of the documentation.',
type: 'warning',
showMs: null
})
}, [version, versions])

if (loadingFailed) {
return <NotFound />
}
Expand Down
6 changes: 4 additions & 2 deletions web/src/pages/Upload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,8 @@ export default function Upload(): JSX.Element {
setValidation({})
showMessage({
type: 'success',
text: 'Documentation uploaded successfully'
content: 'Documentation uploaded successfully',
showMs: 6000
})

// reload the projects
Expand All @@ -121,7 +122,8 @@ export default function Upload(): JSX.Element {
const message = (e as { message: string }).message
showMessage({
type: 'error',
text: message
content: message,
showMs: 6000
})
} finally {
setIsUploading(false)
Expand Down

0 comments on commit 1049824

Please sign in to comment.