mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
<img width="1758" height="1252" alt="image" src="https://github.com/user-attachments/assets/6f5ff072-9b47-4265-924d-0ca22368f6cb" /> ## What With the Explorer feature preview on, the homepage **Reports** row becomes a **Notebooks** row showing the four newest notebooks. - Advisor and notebook cards share a new `HomeCard` layout: same height and header, content anchored to the bottom, 3-line description clamp. - Notebook cards show the cell count, the creation date, and an **Analyze** button that starts the same chat as the Explorer notebook tab (`useAnalyzeNotebook`, now shared by both). - Advisor lint cards replace the assistant dropdown with two icon buttons: **Ask Assistant** and **Copy prompt**. Copy prompt shows a check after copying. - The empty state matches the Reports one. ## How to test 1. Turn on the Explorer feature preview and open a project's Home page. 2. The Reports row should be replaced by Notebooks. With no notebooks, you should see the empty state; **Create your first notebook** opens a new notebook in Explorer. 3. Click a notebook card to open it. Click **Analyze** to start an assistant chat. It should be disabled on a notebook with no cells. 4. On an advisor lint card, check **Ask Assistant** opens the assistant with the lint prompt, and **Copy prompt** copies it and briefly shows a check. 5. Turn the preview off: the Reports row comes back unchanged. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Project home now displays up to four notebooks, with options to create a notebook, open it, and see its cell count. * Start an AI analysis of a notebook directly from its card or from the notebook explorer. Analysis is unavailable for notebooks without cells. * Advisor cards now offer a one-click AI chat and a copyable prompt. * Project home shows notebooks when the Explorer preview is enabled; otherwise, it continues to show custom reports. <!-- end of auto-generated comment: release notes by coderabbit.ai --> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
64 lines
2.2 KiB
TypeScript
64 lines
2.2 KiB
TypeScript
import Link from 'next/link'
|
|
import type { ReactNode } from 'react'
|
|
import { Card, CardContent, CardHeader, CardTitle, cn } from 'ui'
|
|
|
|
// Stretches the title's link/button over the whole card so the card is clickable without
|
|
// nesting the header actions inside an interactive element
|
|
const STRETCHED_TARGET_CLASS =
|
|
'block w-full truncate text-left outline-hidden after:absolute after:inset-0 after:rounded-lg focus-visible:after:ring-1 focus-visible:after:ring-foreground-muted'
|
|
|
|
type HomeCardTarget = { href: string; onClick?: never } | { onClick: () => void; href?: never }
|
|
|
|
type HomeCardProps = HomeCardTarget & {
|
|
icon: ReactNode
|
|
label: string
|
|
title: string
|
|
/** Rendered on the right of the header, above the card's click target */
|
|
actions?: ReactNode
|
|
description?: ReactNode
|
|
meta?: ReactNode
|
|
className?: string
|
|
}
|
|
|
|
/** Fixed-height card used by the project homepage rows, with its content anchored to the bottom */
|
|
export const HomeCard = ({
|
|
href,
|
|
onClick,
|
|
icon,
|
|
label,
|
|
title,
|
|
actions,
|
|
description,
|
|
meta,
|
|
className,
|
|
}: HomeCardProps) => (
|
|
<Card className={cn('relative h-64 flex flex-col', className)}>
|
|
<CardHeader className="border-b-0 shrink-0 flex flex-row gap-2 space-y-0 justify-between items-center">
|
|
<div className="flex flex-row items-center gap-3">
|
|
{icon}
|
|
<CardTitle className="text-foreground-light">{label}</CardTitle>
|
|
</div>
|
|
{actions && <div className="relative z-10 flex items-center gap-1">{actions}</div>}
|
|
</CardHeader>
|
|
<CardContent className="pt-0 flex flex-col justify-end flex-1 min-h-0">
|
|
<h3 className="mb-1">
|
|
{href !== undefined ? (
|
|
<Link href={href} className={STRETCHED_TARGET_CLASS}>
|
|
{title}
|
|
</Link>
|
|
) : (
|
|
<button type="button" tabIndex={0} onClick={onClick} className={STRETCHED_TARGET_CLASS}>
|
|
{title}
|
|
</button>
|
|
)}
|
|
</h3>
|
|
{description && (
|
|
<div className="text-sm text-muted-foreground line-clamp-3 [&_a]:relative [&_a]:z-10">
|
|
{description}
|
|
</div>
|
|
)}
|
|
{meta && <p className="mt-3 text-sm text-foreground-lighter">{meta}</p>}
|
|
</CardContent>
|
|
</Card>
|
|
)
|