Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions packages/server-admin-ui/src/components/Sidebar/Sidebar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from '../../store'
import classNames from 'classnames'
import { isOverrideDormantUnderGroups } from '../../utils/sourceGroups'
import { useHistoryProviderUnavailable } from '../../hooks/useHistoryProviderStatus'
import './Sidebar.css'
import SidebarFooter from './../SidebarFooter/SidebarFooter'
import SidebarForm from './../SidebarForm/SidebarForm'
Expand Down Expand Up @@ -158,6 +159,7 @@ export default function Sidebar({ location }: SidebarProps) {
).length

const unconfiguredGnssCount = useUnconfiguredGnssSources().length
const historyProviderUnavailable = useHistoryProviderUnavailable()

const items = useMemo((): NavItemData[] => {
const appUpdates = appStore.updates.length
Expand Down Expand Up @@ -306,13 +308,17 @@ export default function Sidebar({ location }: SidebarProps) {
})()
]

const historyProviderBadge: BadgeData | null = historyProviderUnavailable
? { variant: 'warning', text: '!' }
: null

if (isAdmin) {
result.push(
{
name: 'Apps & Plugins',
url: '/apps',
icon: 'icon-basket',
badges: [updatesBadge, unconfiguredBadge],
badges: [updatesBadge, unconfiguredBadge, historyProviderBadge],
children: [
{
name: 'Store',
Expand All @@ -322,7 +328,7 @@ export default function Sidebar({ location }: SidebarProps) {
{
name: 'Configuration',
url: '/apps/configuration/-',
badge: unconfiguredBadge
badges: [unconfiguredBadge, historyProviderBadge]
}
]
},
Expand Down Expand Up @@ -432,7 +438,8 @@ export default function Sidebar({ location }: SidebarProps) {
conflictCount,
unconfiguredPriorityCount,
overridesWithMissingSourcesCount,
unconfiguredGnssCount
unconfiguredGnssCount,
historyProviderUnavailable
])

const [openDropdowns, setOpenDropdowns] = useState<Set<string>>(
Expand Down
50 changes: 50 additions & 0 deletions packages/server-admin-ui/src/hooks/useHistoryProviderStatus.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useState, useEffect } from 'react'
import { usePlugins } from '../store'

const PROVIDERS_PATH = '/signalk/v2/api/history/_providers'

/**
* True when a default History API provider is configured but not
* currently registered (e.g. its plugin is disabled), so requests are
* served by a fallback. Re-checks whenever the plugin list changes,
* since providers register and unregister with plugin enable/disable.
*/
export function useHistoryProviderUnavailable(): boolean {
const plugins = usePlugins()
const [unavailable, setUnavailable] = useState(false)

useEffect(() => {
let cancelled = false
const check = async () => {
try {
const [providersRes, defaultRes] = await Promise.all([
fetch(PROVIDERS_PATH, { credentials: 'include' }),
fetch(`${PROVIDERS_PATH}/_default`, { credentials: 'include' })
])
if (!providersRes.ok || !defaultRes.ok) {
return
}
const ids = Object.keys(
(await providersRes.json()) as Record<string, unknown>
)
const defaultBody = (await defaultRes.json()) as {
configured?: string
}
if (!cancelled) {
setUnavailable(
defaultBody.configured !== undefined &&
!ids.includes(defaultBody.configured)
)
}
} catch {
// status stays as-is; the badge is best-effort
}
}
check()
return () => {
cancelled = true
}
}, [plugins])

return unavailable
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
Loading
Loading