mirror of
https://github.com/supabase/supabase.git
synced 2026-07-03 06:14:29 +08:00
* feat: more generic observability banner on db report * feat: try popup in corner * feat: tidy up and fix up event as well * feat: add event for dismiss as well * feat: add supplementary link at bottom of reports * fix: sizing of fonts * feat: banner stack approach * fix: isIndexAdvisorAvailable dep * chore: remove unused import for old banner * feat: remove unused isDismissed * chore: remove unused cn * chore: change prio on query perf page * chore: remove unused sendEvent * chore: better useEffect cleanup * chore: remove unused index advisor notice * fix: priority of banner stack * fix: first time loader flickering * chore: lowercase the word Free * feat: add IS_PLATFORM to make sure metrics api banner is scoped to platform * chore: another copy update for observability link * fix: telemetry keys to match styleguide * fix: use the correct way to apply events * feat: add events for index advisor banner too * chore: delete unused old banner * fix: dismiss buttons not working * feat: add extra event to enable index advisor
50 lines
1.4 KiB
TypeScript
50 lines
1.4 KiB
TypeScript
import { createContext, useContext, useState, useCallback } from 'react'
|
|
|
|
export interface Banner {
|
|
id: string
|
|
content: React.ReactNode
|
|
isDismissed: boolean
|
|
priority?: number
|
|
onDismiss?: () => void
|
|
}
|
|
|
|
interface BannerStackContextType {
|
|
banners: Banner[]
|
|
addBanner: (banner: Banner) => void
|
|
dismissBanner: (id: string) => void
|
|
}
|
|
|
|
const BannerStackContext = createContext<BannerStackContextType | undefined>(undefined)
|
|
|
|
export const BannerStackProvider = ({ children }: { children: React.ReactNode }) => {
|
|
const [banners, setBanners] = useState<Banner[]>([])
|
|
|
|
const addBanner = useCallback((banner: Banner) => {
|
|
setBanners((prev) => {
|
|
const exists = prev.some((b) => b.id === banner.id)
|
|
if (exists) return prev
|
|
const newBanners = [...prev, banner]
|
|
return newBanners.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0))
|
|
})
|
|
}, [])
|
|
|
|
const dismissBanner = useCallback((id: string) => {
|
|
setBanners((prev) => prev.map((b) => (b.id === id ? { ...b, isDismissed: true } : b)))
|
|
setTimeout(() => {
|
|
setBanners((prev) => prev.filter((b) => b.id !== id))
|
|
}, 300)
|
|
}, [])
|
|
|
|
return (
|
|
<BannerStackContext.Provider value={{ banners, addBanner, dismissBanner }}>
|
|
{children}
|
|
</BannerStackContext.Provider>
|
|
)
|
|
}
|
|
|
|
export const useBannerStack = () => {
|
|
const context = useContext(BannerStackContext)
|
|
if (!context) throw new Error('useBannerStack must be used within BannerStackProvider')
|
|
return context
|
|
}
|