mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Feature ## Summary - Replace advisor panel tabs with multi-select category filters, including Health - Load health lints in the advisor panel (without blocking other categories on the slower health request) - Rename item `tab` to `category` and add empty-state copy for health Stacked on #49661. ## To test 1. Open any project in Studio. 2. Open Advisor Center from the toolbar (the advisor / lightbulb control). 3. Confirm the old All / Security / Performance / Messages **tabs are gone**. You should see **Category**, **Status**, and **Severity** filters instead. 4. Open Category and confirm **Health** is in the list with Security, Performance, and Messages. 5. Select only **Health**: - If the project is healthy: empty state “No health issues detected” / “Your database, instance and services are all responding normally”. - If it is not: only health issues in the list. 6. Clear Health, then filter **Security** and **Performance** separately. Those lists should still match what you expect from before. 7. With Health selected, also filter Severity to **Info** only. If nothing matches, you should get “No items found” and a way to clear filters — not a false “no health issues” message. 8. From project home, click an advisor card. Advisor Center should still open on that same item. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Added category-based filtering for Advisor recommendations, including Security, Performance, Health, and Messages. - Added Health issue recommendations and category-specific icons, labels, and empty-state messaging. - Advisor results now load according to the selected categories. - Added clearer project requirements and hidden-item controls for filtered results. - **Bug Fixes** - Invalid category and severity filter values are safely ignored. - Improved categorization and telemetry for Advisor items, including health and security recommendations. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
73 lines
2.3 KiB
TypeScript
73 lines
2.3 KiB
TypeScript
import { TextSearch } from 'lucide-react'
|
|
import { Button } from 'ui'
|
|
|
|
import type { AdvisorCategory } from '@/state/advisor-state'
|
|
|
|
const emptyCopyByCategory: Record<AdvisorCategory, { heading: string; message: string }> = {
|
|
security: {
|
|
heading: 'No security issues detected',
|
|
message: 'Congrats! There are no security issues detected for this project',
|
|
},
|
|
performance: {
|
|
heading: 'No performance issues detected',
|
|
message: 'Congrats! There are no performance issues detected for this project',
|
|
},
|
|
health: {
|
|
heading: 'No health issues detected',
|
|
message: 'Your database, instance and services are all responding normally',
|
|
},
|
|
messages: {
|
|
heading: 'No messages',
|
|
message: 'Messages alert you of upcoming changes or potential issues with your project',
|
|
},
|
|
}
|
|
|
|
interface EmptyAdvisorProps {
|
|
categoryFilters: AdvisorCategory[]
|
|
/**
|
|
* Whether severity or status filters are narrowing the list. Unlike the category filter,
|
|
* these can hide items the user would otherwise see, so we can't claim nothing was found.
|
|
*/
|
|
hasFilters: boolean
|
|
onClearFilters: () => void
|
|
}
|
|
|
|
export const EmptyAdvisor = ({
|
|
categoryFilters,
|
|
hasFilters,
|
|
onClearFilters,
|
|
}: EmptyAdvisorProps) => {
|
|
const singleCategory = categoryFilters.length === 1 ? categoryFilters[0] : undefined
|
|
const canClearFilters = hasFilters || categoryFilters.length > 0
|
|
|
|
const getCopy = () => {
|
|
if (hasFilters) {
|
|
return {
|
|
heading: 'No items found',
|
|
message: 'No advisor items match your current filters',
|
|
}
|
|
}
|
|
|
|
if (singleCategory) return emptyCopyByCategory[singleCategory]
|
|
|
|
return { heading: 'No issues detected', message: 'Congrats! There are no issues detected' }
|
|
}
|
|
|
|
const { heading, message } = getCopy()
|
|
|
|
return (
|
|
<div className="h-full px-6 flex flex-col items-center justify-center w-full gap-y-2">
|
|
<TextSearch className="text-foreground-muted" strokeWidth={1} />
|
|
<div className="flex flex-col items-center gap-y-0.5 text-center">
|
|
<h3 className="heading-default">{heading}</h3>
|
|
<p className="text-foreground-light text-sm text-balance">{message}</p>
|
|
</div>
|
|
{canClearFilters && (
|
|
<Button variant="outline" onClick={onClearFilters}>
|
|
Clear filters
|
|
</Button>
|
|
)}
|
|
</div>
|
|
)
|
|
}
|