Reports
- {canUpdateReport || canCreateReport ? (
-
}>
- Add block
-
- }
- side="bottom"
- align="end"
- autoFocus
- />
- ) : null}
+
+ {layout.length > 0 && (
+ }
+ className="w-7"
+ disabled={isRefreshing}
+ tooltip={{ content: { side: 'bottom', text: 'Refresh report' } }}
+ onClick={onRefreshReport}
+ />
+ )}
+ {canUpdateReport || canCreateReport ? (
+ }>
+ Add block
+
+ }
+ side="bottom"
+ align="end"
+ autoFocus
+ />
+ ) : null}
+
{layout.length === 0 ? (
@@ -343,7 +382,7 @@ export function CustomReportSection() {
('1d' as AnalyticsInterval)
}
disableUpdate={false}
- isRefreshing={false}
+ isRefreshing={isRefreshing}
onRemoveChart={handleRemoveChart}
onUpdateChart={(config) => handleUpdateChart(item.id, config)}
/>
diff --git a/apps/studio/components/interfaces/HomeNew/ServiceStatus.tsx b/apps/studio/components/interfaces/HomeNew/ServiceStatus.tsx
index 294aecd09b8f6..d5ed3f78d2b33 100644
--- a/apps/studio/components/interfaces/HomeNew/ServiceStatus.tsx
+++ b/apps/studio/components/interfaces/HomeNew/ServiceStatus.tsx
@@ -37,16 +37,17 @@ const StatusMessage = ({
status,
isLoading,
isHealthy,
+ isProjectNew,
}: {
isLoading: boolean
isHealthy: boolean
+ isProjectNew: boolean
status?: ProjectServiceStatus
}) => {
- if (isHealthy) return 'Healthy'
+ if (isHealthy || status === 'ACTIVE_HEALTHY') return 'Healthy'
if (isLoading) return 'Checking status'
if (status === 'UNHEALTHY') return 'Unhealthy'
- if (status === 'COMING_UP') return 'Coming up...'
- if (status === 'ACTIVE_HEALTHY') return 'Healthy'
+ if (isProjectNew || status === 'COMING_UP') return 'Coming up...'
if (status) return status
return 'Unable to connect'
}
@@ -62,17 +63,16 @@ const CheckIcon = () =>
const StatusIcon = ({
isLoading,
isHealthy,
+ isProjectNew,
projectStatus,
}: {
isLoading: boolean
isHealthy: boolean
+ isProjectNew: boolean
projectStatus?: ProjectServiceStatus
}) => {
- if (isHealthy) return
- if (isLoading) return
- if (projectStatus === 'UNHEALTHY') return
- if (projectStatus === 'COMING_UP') return
- if (projectStatus === 'ACTIVE_HEALTHY') return
+ if (isHealthy || projectStatus === 'ACTIVE_HEALTHY') return
+ if (isLoading || isProjectNew || projectStatus === 'COMING_UP') return
return
}
@@ -242,15 +242,23 @@ export const ServiceStatus = () => {
const isLoadingChecks = services.some((service) => service.isLoading)
const allServicesOperational = services.every((service) => service.isHealthy)
+ // Check if project or branch is in a startup state
+ const isProjectNew =
+ project?.status === 'COMING_UP' ||
+ (isBranch &&
+ (currentBranch?.status === 'CREATING_PROJECT' ||
+ currentBranch?.status === 'RUNNING_MIGRATIONS' ||
+ isMigrationLoading))
+
const anyUnhealthy = services.some(
(service) => !service.isHealthy && service.status !== 'COMING_UP'
)
const anyComingUp = services.some((service) => service.status === 'COMING_UP')
const overallStatusLabel = isLoadingChecks
? 'Checking...'
- : anyUnhealthy
+ : anyUnhealthy && !isProjectNew
? 'Unhealthy'
- : anyComingUp || isMigrationLoading
+ : anyComingUp || isMigrationLoading || (isProjectNew && !allServicesOperational)
? 'Coming up...'
: 'Healthy'
@@ -265,7 +273,9 @@ export const ServiceStatus = () => {
key={`${service.name}-${index}`}
className={cn(
'w-1.5 h-1.5 rounded-full',
- service.isLoading || service.status === 'COMING_UP'
+ service.isLoading ||
+ service.status === 'COMING_UP' ||
+ (isProjectNew && !service.isHealthy)
? 'bg-foreground-lighter animate-pulse'
: service.isHealthy
? 'bg-brand'
@@ -290,6 +300,7 @@ export const ServiceStatus = () => {
@@ -298,6 +309,7 @@ export const ServiceStatus = () => {
diff --git a/apps/studio/data/analytics/utils.ts b/apps/studio/data/analytics/utils.ts
new file mode 100644
index 0000000000000..543bd472de6b8
--- /dev/null
+++ b/apps/studio/data/analytics/utils.ts
@@ -0,0 +1,35 @@
+import { useQueryClient } from '@tanstack/react-query'
+import { analyticsKeys } from './keys'
+
+export const useInvalidateAnalyticsQuery = () => {
+ const queryClient = useQueryClient()
+
+ const invalidateInfraMonitoringQuery = (
+ ref: string,
+ {
+ attribute,
+ startDate,
+ endDate,
+ interval,
+ databaseIdentifier,
+ }: {
+ attribute?: string
+ startDate?: string
+ endDate?: string
+ interval?: string
+ databaseIdentifier?: string
+ }
+ ) => {
+ queryClient.invalidateQueries(
+ analyticsKeys.infraMonitoring(ref, {
+ attribute,
+ startDate,
+ endDate,
+ interval,
+ databaseIdentifier,
+ })
+ )
+ }
+
+ return { invalidateInfraMonitoringQuery }
+}
diff --git a/apps/studio/lib/api/self-hosted/migrations.ts b/apps/studio/lib/api/self-hosted/migrations.ts
index 8966cf9e5c79e..56d484d5f80d2 100644
--- a/apps/studio/lib/api/self-hosted/migrations.ts
+++ b/apps/studio/lib/api/self-hosted/migrations.ts
@@ -34,7 +34,7 @@ const applyAndTrackMigrationsQuery = (query: string, name?: string) => {
-- track statements in history table
insert into supabase_migrations.schema_migrations (version, name, statements)
values (
- to_char(current_timestamp, 'YYYYMMDDHHMISS'),
+ to_char(current_timestamp, 'YYYYMMDDHH24MISS'),
${quote(name)},
array[${quote(query)}]
);
diff --git a/apps/studio/pages/project/[ref]/auth/overview.tsx b/apps/studio/pages/project/[ref]/auth/overview.tsx
index 0a42fba0eb92a..a0c89ea5d1381 100644
--- a/apps/studio/pages/project/[ref]/auth/overview.tsx
+++ b/apps/studio/pages/project/[ref]/auth/overview.tsx
@@ -1,12 +1,13 @@
import { NextPageWithLayout } from 'types'
import DefaultLayout from 'components/layouts/DefaultLayout'
import AuthLayout from 'components/layouts/AuthLayout/AuthLayout'
-import { ScaffoldContainer, ScaffoldSection } from 'components/layouts/Scaffold'
+import { ScaffoldContainer } from 'components/layouts/Scaffold'
import { PageLayout } from 'components/layouts/PageLayout/PageLayout'
import { DocsButton } from 'components/ui/DocsButton'
import { DOCS_URL } from 'lib/constants'
import { OverviewUsage } from 'components/interfaces/Auth/Overview/OverviewUsage'
import { OverviewLearnMore } from 'components/interfaces/Auth/Overview/OverviewLearnMore'
+import { OverviewMonitoring } from 'components/interfaces/Auth/Overview/OverviewMonitoring'
import { useRouter } from 'next/router'
import { FeatureFlagContext, useFlag, useParams } from 'common'
import { useContext, useEffect } from 'react'
@@ -32,6 +33,7 @@ const AuthOverview: NextPageWithLayout = () => {
+