mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
Refine top section home new (#38802)
* refine activity * make component * Smol fix * Nit * add group --------- Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
1 parent
6cbc8b174b
commit
dc41cfd7e1
3 files changed
+108
-69
No files matched your search
@@ -1,9 +1,9 @@
|
||||
import dayjs from 'dayjs'
|
||||
import { GitBranch } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { Archive, Database, GitBranch } from 'lucide-react'
|
||||
import { useMemo } from 'react'
|
||||
|
||||
import { useParams } from 'common'
|
||||
import { SingleStat } from 'components/ui/SingleStat'
|
||||
import { useBranchesQuery } from 'data/branches/branches-query'
|
||||
import { useBackupsQuery } from 'data/database/backups-query'
|
||||
import { useMigrationsQuery } from 'data/database/migrations-query'
|
||||
@@ -55,17 +55,15 @@ export const ActivityStats = () => {
|
||||
|
||||
return (
|
||||
<div className="@container">
|
||||
<div className="grid grid-cols-2 xl:flex xl:gap-10 gap-4 flex-wrap">
|
||||
<div className="block">
|
||||
<p className="heading-meta text-foreground-light mb-1">Status</p>
|
||||
<ServiceStatus />
|
||||
</div>
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 flex-wrap">
|
||||
<ServiceStatus />
|
||||
|
||||
<Link className="block" href={`/project/${ref}/database/migrations`}>
|
||||
<h4 className="heading-meta text-foreground-light mb-1">Last migration</h4>
|
||||
|
||||
<div className={cn('h-[34px] flex items-center capitalize-sentence')}>
|
||||
{isLoadingMigrations ? (
|
||||
<SingleStat
|
||||
href={`/project/${ref}/database/migrations`}
|
||||
icon={<Database size={18} strokeWidth={1.5} className="text-foreground" />}
|
||||
label={<span>Last migration</span>}
|
||||
value={
|
||||
isLoadingMigrations ? (
|
||||
<Skeleton className="h-6 w-24" />
|
||||
) : latestMigration ? (
|
||||
<TimestampInfo
|
||||
@@ -75,15 +73,16 @@ export const ActivityStats = () => {
|
||||
/>
|
||||
) : (
|
||||
<p className="text-foreground-lighter">No migrations</p>
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
<Link className="block" href={`/project/${ref}/database/backups/scheduled`}>
|
||||
<h4 className="heading-meta text-foreground-light mb-1">Last backup</h4>
|
||||
|
||||
<div className={cn('h-[34px] flex items-center capitalize-sentence')}>
|
||||
{isLoadingBackups ? (
|
||||
<SingleStat
|
||||
href={`/project/${ref}/database/backups/scheduled`}
|
||||
icon={<Archive size={18} strokeWidth={1.5} className="text-foreground" />}
|
||||
label={<span>Last backup</span>}
|
||||
value={
|
||||
isLoadingBackups ? (
|
||||
<Skeleton className="h-6 w-24" />
|
||||
) : backupsData?.pitr_enabled ? (
|
||||
<p>PITR enabled</p>
|
||||
@@ -95,25 +94,26 @@ export const ActivityStats = () => {
|
||||
/>
|
||||
) : (
|
||||
<p className="text-foreground-lighter">No backups</p>
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
<Link className="block" href={`/project/${ref}/branches`}>
|
||||
<h4 className="heading-meta text-foreground-light mb-1">
|
||||
{isDefaultProject ? 'Recent branch' : 'Branch Created'}
|
||||
</h4>
|
||||
|
||||
<div className="text-foreground truncate h-[34px] flex items-center capitalize-sentence">
|
||||
{isLoadingBranches ? (
|
||||
<SingleStat
|
||||
href={`/project/${ref}/branches`}
|
||||
icon={<GitBranch size={18} strokeWidth={1.5} className="text-foreground" />}
|
||||
label={<span>{isDefaultProject ? 'Recent branch' : 'Branch Created'}</span>}
|
||||
value={
|
||||
isLoadingBranches ? (
|
||||
<Skeleton className="h-6 w-24" />
|
||||
) : isDefaultProject ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<GitBranch size={16} strokeWidth={1.5} className="text-foreground-lighter" />
|
||||
<p className={cn('truncate', !latestNonDefaultBranch && 'text-foreground-lighter')}>
|
||||
{latestNonDefaultBranch?.name ?? 'No branches'}
|
||||
</p>
|
||||
</div>
|
||||
<p
|
||||
className={cn(
|
||||
'truncate',
|
||||
!latestNonDefaultBranch && 'text-foreground-lighter truncate'
|
||||
)}
|
||||
>
|
||||
{latestNonDefaultBranch?.name ?? 'No branches'}
|
||||
</p>
|
||||
) : currentBranch?.created_at ? (
|
||||
<TimestampInfo
|
||||
className="text-base"
|
||||
@@ -122,9 +122,9 @@ export const ActivityStats = () => {
|
||||
/>
|
||||
) : (
|
||||
<p className="text-foreground-lighter">Unknown</p>
|
||||
)}
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { AlertTriangle, CheckCircle2, ChevronDown, ChevronRight, Loader2 } from 'lucide-react'
|
||||
import { AlertTriangle, CheckCircle2, ChevronRight, Loader2 } from 'lucide-react'
|
||||
import Link from 'next/link'
|
||||
import { useState } from 'react'
|
||||
|
||||
import { PopoverSeparator } from '@ui/components/shadcn/ui/popover'
|
||||
import { useParams } from 'common'
|
||||
import { SingleStat } from 'components/ui/SingleStat'
|
||||
import { useBranchesQuery } from 'data/branches/branches-query'
|
||||
import { useEdgeFunctionServiceStatusQuery } from 'data/service-status/edge-functions-status-query'
|
||||
import {
|
||||
@@ -12,14 +12,7 @@ import {
|
||||
} from 'data/service-status/service-status-query'
|
||||
import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled'
|
||||
import { useSelectedProjectQuery } from 'hooks/misc/useSelectedProject'
|
||||
import {
|
||||
Button,
|
||||
InfoIcon,
|
||||
PopoverContent_Shadcn_,
|
||||
PopoverTrigger_Shadcn_,
|
||||
Popover_Shadcn_,
|
||||
cn,
|
||||
} from 'ui'
|
||||
import { InfoIcon, PopoverContent_Shadcn_, PopoverTrigger_Shadcn_, Popover_Shadcn_, cn } from 'ui'
|
||||
|
||||
/**
|
||||
* [Joshen] JFYI before we go live with this, we need to revisit the migrations section
|
||||
@@ -85,7 +78,6 @@ const StatusIcon = ({
|
||||
export const ServiceStatus = () => {
|
||||
const { ref } = useParams()
|
||||
const { data: project } = useSelectedProjectQuery()
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
const {
|
||||
projectAuthAll: authEnabled,
|
||||
@@ -262,27 +254,29 @@ export const ServiceStatus = () => {
|
||||
: 'Healthy'
|
||||
|
||||
return (
|
||||
<Popover_Shadcn_ modal={false} open={open} onOpenChange={setOpen}>
|
||||
<PopoverTrigger_Shadcn_ asChild>
|
||||
<Button
|
||||
type="outline"
|
||||
className="text-base h-auto px-2"
|
||||
iconRight={<ChevronDown size={14} strokeWidth={1.5} />}
|
||||
<Popover_Shadcn_>
|
||||
<PopoverTrigger_Shadcn_>
|
||||
<SingleStat
|
||||
icon={
|
||||
isLoadingChecks || anyComingUp || isMigrationLoading ? (
|
||||
<Loader2 className="animate-spin ml-1" size={12} strokeWidth={1.5} />
|
||||
) : (
|
||||
<div
|
||||
className={cn(
|
||||
'w-2 h-2 rounded-full ml-1.5',
|
||||
allServicesOperational ? 'bg-brand' : 'bg-warning'
|
||||
)}
|
||||
/>
|
||||
)
|
||||
<div className="grid grid-cols-3 gap-1">
|
||||
{services.map((service, index) => (
|
||||
<div
|
||||
key={`${service.name}-${index}`}
|
||||
className={cn(
|
||||
'w-1.5 h-1.5 rounded-full',
|
||||
service.isLoading || service.status === 'COMING_UP'
|
||||
? 'bg-foreground-lighter animate-pulse'
|
||||
: service.isHealthy
|
||||
? 'bg-brand'
|
||||
: 'bg-selection'
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
}
|
||||
>
|
||||
{overallStatusLabel}
|
||||
</Button>
|
||||
label={<span>Health</span>}
|
||||
value={<span>{overallStatusLabel}</span>}
|
||||
/>
|
||||
</PopoverTrigger_Shadcn_>
|
||||
<PopoverContent_Shadcn_ portal className="p-0 w-56" side="bottom" align="start">
|
||||
{services.map((service) => (
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import Link from 'next/link'
|
||||
import type { ReactNode } from 'react'
|
||||
|
||||
type SingleStatProps = {
|
||||
icon: ReactNode
|
||||
label: ReactNode
|
||||
value: ReactNode
|
||||
className?: string
|
||||
href?: string
|
||||
onClick?: () => void
|
||||
}
|
||||
|
||||
export const SingleStat = ({ icon, label, value, className, href, onClick }: SingleStatProps) => {
|
||||
const content = (
|
||||
<div className={`group flex items-center gap-4 p-0 text-base justify-start ${className || ''}`}>
|
||||
<div className="w-16 h-16 rounded-md bg-surface-75 group-hover:bg-muted border flex items-center justify-center">
|
||||
{icon}
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-left heading-meta text-foreground-light">{label}</div>
|
||||
<div className="text-foreground truncate h-[34px] flex items-center capitalize-sentence">
|
||||
{value}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
if (href) {
|
||||
return (
|
||||
<Link className="group block" href={href}>
|
||||
{content}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
if (onClick) {
|
||||
return (
|
||||
<button className="group" onClick={onClick}>
|
||||
{content}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
return content
|
||||
}
|
||||
Reference in new issue
Block a user