mirror of
https://github.com/traefik/traefik.git
synced 2025-10-03 19:51:19 +02:00
Update hub-button-app to use a local script
Co-authored-by: Firespray-31 <147506444+Firespray-31@users.noreply.github.com>
This commit is contained in:
parent
5df4c270a7
commit
2580d0f95c
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,14 +1,14 @@
|
||||
import { Box, darkTheme, FaencyProvider, lightTheme } from '@traefiklabs/faency'
|
||||
import { Suspense, useEffect } from 'react'
|
||||
import { Helmet, HelmetProvider } from 'react-helmet-async'
|
||||
import { HelmetProvider } from 'react-helmet-async'
|
||||
import { HashRouter, Navigate, Route, Routes as RouterRoutes, useLocation } from 'react-router-dom'
|
||||
import { SWRConfig } from 'swr'
|
||||
|
||||
import Page from './layout/Page'
|
||||
import fetch from './libs/fetch'
|
||||
|
||||
import { VersionProvider } from 'contexts/version'
|
||||
import { useIsDarkMode } from 'hooks/use-theme'
|
||||
import useVersion from 'hooks/use-version'
|
||||
import ErrorSuspenseWrapper from 'layout/ErrorSuspenseWrapper'
|
||||
import { Dashboard, HTTPPages, NotFound, TCPPages, UDPPages } from 'pages'
|
||||
import { DashboardSkeleton } from 'pages/dashboard/Dashboard'
|
||||
@ -33,15 +33,8 @@ const ScrollToTop = () => {
|
||||
}
|
||||
|
||||
export const Routes = () => {
|
||||
const { showHubButton } = useVersion()
|
||||
|
||||
return (
|
||||
<Suspense fallback={<PageLoader />}>
|
||||
{showHubButton && (
|
||||
<Helmet>
|
||||
<script src="https://traefik.github.io/traefiklabs-hub-button-app/main-v1.js"></script>
|
||||
</Helmet>
|
||||
)}
|
||||
<RouterRoutes>
|
||||
<Route
|
||||
path="/"
|
||||
@ -100,10 +93,12 @@ const App = () => {
|
||||
fetcher: fetch,
|
||||
}}
|
||||
>
|
||||
<HashRouter basename={import.meta.env.VITE_APP_BASE_URL || ''}>
|
||||
<ScrollToTop />
|
||||
<Routes />
|
||||
</HashRouter>
|
||||
<VersionProvider>
|
||||
<HashRouter basename={import.meta.env.VITE_APP_BASE_URL || ''}>
|
||||
<ScrollToTop />
|
||||
<Routes />
|
||||
</HashRouter>
|
||||
</VersionProvider>
|
||||
</SWRConfig>
|
||||
</HelmetProvider>
|
||||
</FaencyProvider>
|
||||
|
40
webui/src/contexts/version.tsx
Normal file
40
webui/src/contexts/version.tsx
Normal file
@ -0,0 +1,40 @@
|
||||
import { createContext, ReactNode, useEffect, useState } from 'react'
|
||||
|
||||
type VersionContextProps = {
|
||||
showHubButton: boolean
|
||||
version: string
|
||||
}
|
||||
|
||||
export const VersionContext = createContext<VersionContextProps>({
|
||||
showHubButton: false,
|
||||
version: '',
|
||||
})
|
||||
|
||||
type VersionProviderProps = {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export const VersionProvider = ({ children }: VersionProviderProps) => {
|
||||
const [showHubButton, setShowHubButton] = useState(false)
|
||||
const [version, setVersion] = useState('')
|
||||
|
||||
useEffect(() => {
|
||||
const fetchVersion = async () => {
|
||||
try {
|
||||
const response = await fetch('/api/version')
|
||||
if (!response.ok) {
|
||||
throw new Error(`Network error: ${response.status}`)
|
||||
}
|
||||
const data: API.Version = await response.json()
|
||||
setShowHubButton(!data.disableDashboardAd)
|
||||
setVersion(data.Version)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
}
|
||||
|
||||
fetchVersion()
|
||||
}, [])
|
||||
|
||||
return <VersionContext.Provider value={{ showHubButton, version }}>{children}</VersionContext.Provider>
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
import { useMemo } from 'react'
|
||||
import useSWR from 'swr'
|
||||
|
||||
export default function useVersion() {
|
||||
const { data: version } = useSWR('/version')
|
||||
|
||||
const showHubButton = useMemo(() => {
|
||||
if (!version) return false
|
||||
return !version?.disableDashboardAd
|
||||
}, [version])
|
||||
|
||||
return { showHubButton, version }
|
||||
}
|
@ -19,7 +19,7 @@ import {
|
||||
Tooltip,
|
||||
VisuallyHidden,
|
||||
} from '@traefiklabs/faency'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useContext, useEffect, useMemo, useState } from 'react'
|
||||
import { BsChevronDoubleRight, BsChevronDoubleLeft } from 'react-icons/bs'
|
||||
import { FiBookOpen, FiGithub, FiHelpCircle } from 'react-icons/fi'
|
||||
import { matchPath, useHref } from 'react-router'
|
||||
@ -34,9 +34,9 @@ import Logo from 'components/icons/Logo'
|
||||
import { PluginsIcon } from 'components/icons/PluginsIcon'
|
||||
import ThemeSwitcher from 'components/ThemeSwitcher'
|
||||
import TooltipText from 'components/TooltipText'
|
||||
import { VersionContext } from 'contexts/version'
|
||||
import useTotals from 'hooks/use-overview-totals'
|
||||
import { useIsDarkMode } from 'hooks/use-theme'
|
||||
import useVersion from 'hooks/use-version'
|
||||
import { Route, ROUTES } from 'routes'
|
||||
|
||||
export const LAPTOP_BP = 1025
|
||||
@ -136,7 +136,7 @@ export const SideNav = ({
|
||||
isResponsive?: boolean
|
||||
}) => {
|
||||
const windowSize = useWindowSize()
|
||||
const { version } = useVersion()
|
||||
const { version } = useContext(VersionContext)
|
||||
|
||||
const { http, tcp, udp } = useTotals()
|
||||
|
||||
@ -228,7 +228,7 @@ export const SideNav = ({
|
||||
>
|
||||
<Logo height={isSmallScreen ? 36 : 56} isSmallScreen={isSmallScreen} />
|
||||
{!!version && !isSmallScreen && (
|
||||
<TooltipText text={version.Version} css={{ maxWidth: 50, fontWeight: '$semiBold' }} isTruncated />
|
||||
<TooltipText text={version} css={{ maxWidth: 50, fontWeight: '$semiBold' }} isTruncated />
|
||||
)}
|
||||
</Flex>
|
||||
{ROUTES.map((section, index) => (
|
||||
@ -289,23 +289,60 @@ export const SideNav = ({
|
||||
}
|
||||
|
||||
export const TopNav = () => {
|
||||
const { showHubButton, version } = useVersion()
|
||||
const [hasHubButtonComponent, setHasHubButtonComponent] = useState(false)
|
||||
const { showHubButton, version } = useContext(VersionContext)
|
||||
const isDarkMode = useIsDarkMode()
|
||||
|
||||
const parsedVersion = useMemo(() => {
|
||||
if (!version?.Version) {
|
||||
if (!version) {
|
||||
return 'master'
|
||||
}
|
||||
if (version.Version === 'dev') {
|
||||
if (version === 'dev') {
|
||||
return 'master'
|
||||
}
|
||||
const matches = version.Version.match(/^(v?\d+\.\d+)/)
|
||||
const matches = version.match(/^(v?\d+\.\d+)/)
|
||||
return matches ? 'v' + matches[1] : 'master'
|
||||
}, [version])
|
||||
|
||||
useEffect(() => {
|
||||
if (!showHubButton) {
|
||||
setHasHubButtonComponent(false)
|
||||
return
|
||||
}
|
||||
|
||||
if (customElements.get('hub-button-app')) {
|
||||
setHasHubButtonComponent(true)
|
||||
return
|
||||
}
|
||||
|
||||
const scripts: HTMLScriptElement[] = []
|
||||
const createScript = (scriptSrc: string): HTMLScriptElement => {
|
||||
const script = document.createElement('script')
|
||||
script.src = scriptSrc
|
||||
script.async = true
|
||||
script.onload = () => {
|
||||
setHasHubButtonComponent(customElements.get('hub-button-app') !== undefined)
|
||||
}
|
||||
scripts.push(script)
|
||||
return script
|
||||
}
|
||||
|
||||
// Source: https://github.com/traefik/traefiklabs-hub-button-app
|
||||
document.head.appendChild(createScript('traefiklabs-hub-button-app/main-v1.js'))
|
||||
|
||||
return () => {
|
||||
// Remove the scripts on unmount.
|
||||
scripts.forEach((script) => {
|
||||
if (script.parentNode) {
|
||||
script.parentNode.removeChild(script)
|
||||
}
|
||||
})
|
||||
}
|
||||
}, [showHubButton])
|
||||
|
||||
return (
|
||||
<Flex as="nav" role="navigation" justify="end" align="center" css={{ gap: '$2', mb: '$6' }}>
|
||||
{showHubButton && (
|
||||
{hasHubButtonComponent && (
|
||||
<Box css={{ fontFamily: '$rubik', fontWeight: '500 !important' }}>
|
||||
<hub-button-app
|
||||
key={`dark-mode-${isDarkMode}`}
|
||||
|
8
webui/src/types/API.d.ts
vendored
Normal file
8
webui/src/types/API.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
namespace API {
|
||||
type Version = {
|
||||
Codename: string
|
||||
Version: string
|
||||
disableDashboardAd: boolean
|
||||
startDate: string
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user