diff --git a/apps/studio/components/interfaces/Home/SecurityStatus.tsx b/apps/studio/components/interfaces/Home/SecurityStatus.tsx index 9e78f312af6..eeba9e89523 100644 --- a/apps/studio/components/interfaces/Home/SecurityStatus.tsx +++ b/apps/studio/components/interfaces/Home/SecurityStatus.tsx @@ -1,19 +1,18 @@ import { CheckCircle2, ChevronRight, Loader2 } from 'lucide-react' +import Link from 'next/link' import { useState } from 'react' + +import { useParams } from 'common' +import { useProjectLintsQuery } from 'data/lint/lint-query' import { Button, PopoverContent_Shadcn_, + PopoverSeparator_Shadcn_, PopoverTrigger_Shadcn_, Popover_Shadcn_, - PopoverSeparator_Shadcn_, cn, } from 'ui' -import { useProjectLintsQuery } from 'data/lint/lint-query' -import { useSelectedProject } from 'hooks/misc/useSelectedProject' -import Link from 'next/link' - import { LINTER_LEVELS, LINT_TABS } from '../Linter/Linter.constants' -import { useParams } from 'common' export const SecurityStatus = () => { const { ref } = useParams() diff --git a/apps/studio/components/interfaces/Home/ServiceStatus.tsx b/apps/studio/components/interfaces/Home/ServiceStatus.tsx index 6e5ed6fa0e1..f8ea3106270 100644 --- a/apps/studio/components/interfaces/Home/ServiceStatus.tsx +++ b/apps/studio/components/interfaces/Home/ServiceStatus.tsx @@ -1,5 +1,7 @@ -import { AlertTriangle, CheckCircle2, Loader2 } from 'lucide-react' -import { useState } from 'react' +import dayjs from 'dayjs' +import { AlertTriangle, CheckCircle2, ChevronRight, Loader2 } from 'lucide-react' +import Link from 'next/link' +import { useEffect, useState } from 'react' import { useParams } from 'common' import { useEdgeFunctionServiceStatusQuery } from 'data/service-status/edge-functions-status-query' @@ -9,6 +11,37 @@ import { useIsFeatureEnabled } from 'hooks/misc/useIsFeatureEnabled' import { useSelectedProject } from 'hooks/misc/useSelectedProject' import { Button, PopoverContent_Shadcn_, PopoverTrigger_Shadcn_, Popover_Shadcn_ } from 'ui' +const SERVICE_STATUS_THRESHOLD = 5 // minutes + +const StatusMessage = ({ + isLoading, + isSuccess, + isProjectNew, +}: { + isLoading: boolean + isSuccess: boolean + isProjectNew: boolean +}) => { + if (isLoading) return 'Checking status' + if (isProjectNew) return 'Coming up...' + if (isSuccess) return 'No issues' + return 'Unable to connect' +} + +const StatusIcon = ({ + isLoading, + isSuccess, + isProjectNew, +}: { + isLoading: boolean + isSuccess: boolean + isProjectNew: boolean +}) => { + if (isLoading || isProjectNew) return + if (isSuccess) return + return +} + const ServiceStatus = () => { const { ref } = useParams() const project = useSelectedProject() @@ -29,13 +62,21 @@ const ServiceStatus = () => { const isBranch = project?.parentRef !== project?.ref // [Joshen] Need pooler service check eventually - const { data: status, isLoading } = useProjectServiceStatusQuery({ projectRef: ref }) - const { data: edgeFunctionsStatus } = useEdgeFunctionServiceStatusQuery({ projectRef: ref }) - const { isLoading: isLoadingPostgres, isSuccess: isSuccessPostgres } = - usePostgresServiceStatusQuery({ - projectRef: ref, - connectionString: project?.connectionString, - }) + const { + data: status, + isLoading, + refetch: refetchServiceStatus, + } = useProjectServiceStatusQuery({ projectRef: ref }) + const { data: edgeFunctionsStatus, refetch: refetchEdgeFunctionServiceStatus } = + useEdgeFunctionServiceStatusQuery({ projectRef: ref }) + const { + isLoading: isLoadingPostgres, + isSuccess: isSuccessPostgres, + refetch: refetchPostgresServiceStatus, + } = usePostgresServiceStatusQuery({ + projectRef: ref, + connectionString: project?.connectionString, + }) const authStatus = status?.find((service) => service.name === 'auth') const restStatus = status?.find((service) => service.name === 'rest') @@ -49,6 +90,7 @@ const ServiceStatus = () => { docsUrl?: string isLoading: boolean isSuccess?: boolean + logsUrl: string }[] = [ { name: 'Database', @@ -56,6 +98,7 @@ const ServiceStatus = () => { docsUrl: undefined, isLoading: isLoadingPostgres, isSuccess: isSuccessPostgres, + logsUrl: '/logs/postgres-logs', }, { name: 'PostgREST', @@ -63,6 +106,7 @@ const ServiceStatus = () => { docsUrl: undefined, isLoading, isSuccess: restStatus?.healthy, + logsUrl: '/logs/postgrest-logs', }, ...(authEnabled ? [ @@ -72,6 +116,7 @@ const ServiceStatus = () => { docsUrl: undefined, isLoading, isSuccess: authStatus?.healthy, + logsUrl: '/logs/auth-logs', }, ] : []), @@ -83,6 +128,7 @@ const ServiceStatus = () => { docsUrl: undefined, isLoading, isSuccess: realtimeStatus?.healthy, + logsUrl: '/logs/realtime-logs', }, ] : []), @@ -94,6 +140,7 @@ const ServiceStatus = () => { docsUrl: undefined, isLoading, isSuccess: storageStatus?.healthy, + logsUrl: '/logs/storage-logs', }, ] : []), @@ -105,6 +152,7 @@ const ServiceStatus = () => { docsUrl: 'https://supabase.com/docs/guides/functions/troubleshooting', isLoading, isSuccess: edgeFunctionsStatus?.healthy, + logsUrl: '/logs/edge-functions-logs', }, ] : []), @@ -113,13 +161,39 @@ const ServiceStatus = () => { const isLoadingChecks = services.some((service) => service.isLoading) const allServicesOperational = services.every((service) => service.isSuccess) + // If the project is less than 5 minutes old, and status is not operational, then it's likely the service is still starting up + const isProjectNew = + dayjs.utc().diff(dayjs.utc(project?.inserted_at), 'minute') < SERVICE_STATUS_THRESHOLD + + useEffect(() => { + let timer: any + + if (isProjectNew) { + const secondsSinceProjectCreated = dayjs + .utc() + .diff(dayjs.utc(project?.inserted_at), 'seconds') + const remainingTimeTillNextCheck = SERVICE_STATUS_THRESHOLD * 60 - secondsSinceProjectCreated + + timer = setTimeout(() => { + refetchServiceStatus() + refetchPostgresServiceStatus() + refetchEdgeFunctionServiceStatus() + }, remainingTimeTillNextCheck * 1000) + } + + return () => { + clearTimeout(timer) + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [isProjectNew]) + return ( ) : ( { {services.map((service) => ( - - - {service.name} - - {service.isLoading - ? 'Checking status' - : service.isSuccess - ? 'No issues' - : 'Unable to connect'} - + + + + {service.name} + + + + - {service.isLoading ? ( - - ) : service.isSuccess ? ( - - ) : ( - - )} - + + View logs + + + ))}
{service.name}
- {service.isLoading - ? 'Checking status' - : service.isSuccess - ? 'No issues' - : 'Unable to connect'} -
+ +