| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172 |
- import type { IncidentCache } from '@/lib/api/incident-status'
- type BannerIncident = { id: string; cache?: IncidentCache | null }
- /**
- * Determines whether the incident status banner should be shown to a given user,
- * given all active incidents and the user's project state.
- *
- * Returns true if any incident matches the user's context.
- *
- * @param incidents - Active incidents from the incident-status endpoint
- * @param hasProjects - Whether the user has any projects at all
- * @param userRegions - Deduplicated set of regions of all databases (primary and read replicas) owned by the user
- * @param hasUnknownRegions - True when region data is incomplete (org has >100 projects).
- * When true, the region check is skipped and a match is assumed.
- */
- export function shouldShowBanner({
- incidents,
- hasProjects,
- userRegions,
- hasUnknownRegions = false,
- }: {
- incidents: Array<BannerIncident>
- hasProjects: boolean
- userRegions: Set<string>
- hasUnknownRegions?: boolean
- }): boolean {
- return incidents.some((incident) => {
- // Forced incidents are shown unconditionally, regardless of regions or project state
- if (incident.cache?.force) return true
- const affectedRegions = incident.cache?.affected_regions ?? []
- const affectsProjectCreation = incident.cache?.affects_project_creation ?? false
- // Users with no projects only see the banner if the incident affects project creation
- // and has no specific region targeting (inline notice in RegionSelector handles region-specific incidents)
- if (!hasProjects) return affectsProjectCreation && affectedRegions.length === 0
- // User has projects: if no region restriction, always show
- if (affectedRegions.length === 0) return true
- // Region data is incomplete — assume the user has a database in an affected region
- if (hasUnknownRegions) return true
- // Region restriction: only show if the user has a database in an affected region
- return affectedRegions.some((region) => userRegions.has(region.toLowerCase()))
- })
- }
- /**
- * Returns the IDs of incidents that are relevant to the given user.
- *
- * An incident is considered relevant if it would trigger banner visibility for
- * the user, per the same logic as shouldShowBanner.
- */
- export function getRelevantIncidentIds({
- incidents,
- hasProjects,
- userRegions,
- hasUnknownRegions = false,
- }: {
- incidents: Array<BannerIncident>
- hasProjects: boolean
- userRegions: Set<string>
- hasUnknownRegions?: boolean
- }): Array<string> {
- return incidents
- .filter((incident) =>
- shouldShowBanner({ incidents: [incident], hasProjects, userRegions, hasUnknownRegions })
- )
- .map((incident) => incident.id)
- }
|