ruvector/studio/components/layouts/ObservabilityLayout/ObservabilityLayout.tsx
rUv 814f595995 feat(studio): Add complete RuVector Studio application
Major additions:
- Complete Next.js studio application with 1600+ components
- Docker support (Dockerfile.combined, docker-compose.yml)
- GCP deployment documentation and benchmarks
- SQL benchmark scripts for performance testing
- Sentry integration for monitoring
- Comprehensive test suite and mocks

Studio features:
- Dashboard and admin interfaces
- Data visualization components
- Authentication and user management
- API integration with RuVector backend
- Static data and public assets

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-06 23:04:48 +00:00

120 lines
3.6 KiB
TypeScript

import { PropsWithChildren, useEffect } from 'react'
import { useParams } from 'common'
import { LOCAL_STORAGE_KEYS, IS_PLATFORM } from 'common'
import { UnknownInterface } from 'components/ui/UnknownInterface'
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
import { withAuth } from 'hooks/misc/withAuth'
import { useLocalStorageQuery } from 'hooks/misc/useLocalStorage'
import { BannerMetricsAPI } from 'components/ui/BannerStack/Banners/BannerMetricsAPI'
import { ProjectLayout } from '../ProjectLayout'
import ObservabilityMenu from './ObservabilityMenu'
import { BannerStackProvider, useBannerStack } from 'components/ui/BannerStack/BannerStackProvider'
import { BannerStack } from 'components/ui/BannerStack/BannerStack'
import { usePathname } from 'next/navigation'
import { useIndexAdvisorStatus } from 'components/interfaces/QueryPerformance/hooks/useIsIndexAdvisorStatus'
import { BannerIndexAdvisor } from 'components/ui/BannerStack/Banners/BannerIndexAdvisor'
import { useRef } from 'react'
interface ObservabilityLayoutProps {
title?: string
}
const ObservabilityLayoutContent = ({
title,
children,
}: PropsWithChildren<ObservabilityLayoutProps>) => {
const { ref } = useParams()
const pathname = usePathname()
const { addBanner, dismissBanner } = useBannerStack()
const { isIndexAdvisorAvailable, isIndexAdvisorEnabled } = useIndexAdvisorStatus()
const [isMetricsBannerDismissed] = useLocalStorageQuery(
LOCAL_STORAGE_KEYS.OBSERVABILITY_BANNER_DISMISSED(ref ?? ''),
false
)
const [isIndexAdvisorBannerDismissed] = useLocalStorageQuery(
LOCAL_STORAGE_KEYS.INDEX_ADVISOR_NOTICE_DISMISSED(ref ?? ''),
false
)
useEffect(() => {
if (!isMetricsBannerDismissed && IS_PLATFORM) {
addBanner({
id: 'metrics-api-banner',
isDismissed: false,
content: <BannerMetricsAPI />,
priority: 1,
})
} else {
dismissBanner('metrics-api-banner')
}
}, [isMetricsBannerDismissed, addBanner, dismissBanner])
const prevPathnameRef = useRef(pathname)
useEffect(() => {
const isQueryPerformancePage = pathname?.includes('/query-performance')
const wasQueryPerformancePage = prevPathnameRef.current?.includes('/query-performance')
if (
isQueryPerformancePage &&
isIndexAdvisorAvailable &&
!isIndexAdvisorEnabled &&
!isIndexAdvisorBannerDismissed
) {
addBanner({
id: 'index-advisor-banner',
isDismissed: false,
content: <BannerIndexAdvisor />,
priority: 3,
})
} else if (isIndexAdvisorBannerDismissed || !isQueryPerformancePage) {
dismissBanner('index-advisor-banner')
}
prevPathnameRef.current = pathname
}, [
pathname,
isIndexAdvisorAvailable,
isIndexAdvisorEnabled,
isIndexAdvisorBannerDismissed,
addBanner,
dismissBanner,
])
const { reportsAll } = useIsFeatureEnabled(['reports:all'])
if (reportsAll) {
return (
<ProjectLayout
title={title}
product="Observability"
productMenu={<ObservabilityMenu />}
isBlocking={false}
>
{children}
</ProjectLayout>
)
} else {
return <UnknownInterface urlBack={`/project/${ref}`} />
}
}
const ObservabilityLayout = (props: PropsWithChildren<ObservabilityLayoutProps>) => {
const { ref } = useParams()
const { reportsAll } = useIsFeatureEnabled(['reports:all'])
if (reportsAll) {
return (
<BannerStackProvider>
<ObservabilityLayoutContent {...props} />
<BannerStack />
</BannerStackProvider>
)
} else {
return <UnknownInterface urlBack={`/project/${ref}`} />
}
}
export default withAuth(ObservabilityLayout)