diff --git a/apps/studio/components/interfaces/Auth/OAuthApps/OAuthAppsList.tsx b/apps/studio/components/interfaces/Auth/OAuthApps/OAuthAppsList.tsx index 902b259d075..9e8331a6129 100644 --- a/apps/studio/components/interfaces/Auth/OAuthApps/OAuthAppsList.tsx +++ b/apps/studio/components/interfaces/Auth/OAuthApps/OAuthAppsList.tsx @@ -132,7 +132,7 @@ export const OAuthAppsList = () => { return filtered.sort((a, b) => { if (sortCol === 'name') { - return a.client_name.localeCompare(b.client_name) * orderMultiplier + return (a.client_name || '').localeCompare(b.client_name || '') * orderMultiplier } if (sortCol === 'client_type') { return a.client_type.localeCompare(b.client_type) * orderMultiplier diff --git a/apps/studio/components/interfaces/ConnectSheet/ConnectionString.utils.ts b/apps/studio/components/interfaces/ConnectSheet/ConnectionString.utils.ts index a681ca002c4..bc24971ad08 100644 --- a/apps/studio/components/interfaces/ConnectSheet/ConnectionString.utils.ts +++ b/apps/studio/components/interfaces/ConnectSheet/ConnectionString.utils.ts @@ -18,8 +18,10 @@ export const resolveConnectionString = ({ }: { connectionMethod: ConnectionStringMethod useSharedPooler: boolean - connectionStringPooler: ConnectionStringPooler + connectionStringPooler: ConnectionStringPooler | undefined }) => { + if (!connectionStringPooler) return '' + if (connectionMethod === 'direct') { return connectionStringPooler.direct ?? '' } diff --git a/apps/studio/components/interfaces/Database/Backups/PITR/PITR.utils.ts b/apps/studio/components/interfaces/Database/Backups/PITR/PITR.utils.ts index f4993b93ae0..c4dc7bafd0d 100644 --- a/apps/studio/components/interfaces/Database/Backups/PITR/PITR.utils.ts +++ b/apps/studio/components/interfaces/Database/Backups/PITR/PITR.utils.ts @@ -1,4 +1,5 @@ import dayjs from 'dayjs' +import { guessLocalTimezone } from 'lib/dayjs' import { ALL_TIMEZONES } from './PITR.constants' import type { Time } from './PITR.types' import type { ProjectSelectedAddon } from 'data/subscriptions/types' @@ -17,7 +18,7 @@ export const getDatesBetweenRange = (startDate: dayjs.Dayjs, endDate: dayjs.Dayj } export const getClientTimezone = () => { - const defaultTz = dayjs.tz.guess() + const defaultTz = guessLocalTimezone() const utcTz = ALL_TIMEZONES.find((option) => option.value === 'UTC') const timezone = ALL_TIMEZONES.find((option) => { if (option.utc.includes(defaultTz)) return option diff --git a/apps/studio/components/interfaces/ProjectAPIDocs/Content/Entity.tsx b/apps/studio/components/interfaces/ProjectAPIDocs/Content/Entity.tsx index ba969463c82..13a7597a09b 100644 --- a/apps/studio/components/interfaces/ProjectAPIDocs/Content/Entity.tsx +++ b/apps/studio/components/interfaces/ProjectAPIDocs/Content/Entity.tsx @@ -39,7 +39,7 @@ export const Entity = ({ language, apikey = '', endpoint = '' }: ContentProps) = const definition = jsonSchema?.definitions?.[resource] const columns = - definition !== undefined + definition?.properties !== undefined ? Object.entries(definition.properties).map(([id, val]: any) => ({ ...val, id, diff --git a/apps/studio/components/interfaces/QueryInsights/QueryInsightsChart/QueryInsightsChartTooltip.tsx b/apps/studio/components/interfaces/QueryInsights/QueryInsightsChart/QueryInsightsChartTooltip.tsx index 52eeec2e9b8..20780afb222 100644 --- a/apps/studio/components/interfaces/QueryInsights/QueryInsightsChart/QueryInsightsChartTooltip.tsx +++ b/apps/studio/components/interfaces/QueryInsights/QueryInsightsChart/QueryInsightsChartTooltip.tsx @@ -1,4 +1,5 @@ import dayjs from 'dayjs' +import { guessLocalTimezone } from 'lib/dayjs' import type { TooltipProps } from 'recharts' import { formatDuration } from '../QueryInsightsTable/QueryInsightsTable.utils' import { isTimeMetric } from './QueryInsightsChart.utils' @@ -7,7 +8,7 @@ export const QueryInsightsChartTooltip = ({ active, payload }: TooltipProps diff --git a/apps/studio/components/ui/Charts/ComposedChart.utils.tsx b/apps/studio/components/ui/Charts/ComposedChart.utils.tsx index b411ef0b031..cce3bb48683 100644 --- a/apps/studio/components/ui/Charts/ComposedChart.utils.tsx +++ b/apps/studio/components/ui/Charts/ComposedChart.utils.tsx @@ -1,6 +1,7 @@ 'use client' import dayjs from 'dayjs' +import { guessLocalTimezone } from 'lib/dayjs' import { formatBytes } from 'lib/helpers' import { useState } from 'react' import { cn, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from 'ui' @@ -193,7 +194,7 @@ export const CustomTooltip = ({ ...(maxValueAttribute?.attribute ? [maxValueAttribute.attribute] : []), ] - const localTimeZone = dayjs.tz.guess() + const localTimeZone = guessLocalTimezone() const rawPayload = payload.map((entry: any) => ({ ...entry, diff --git a/apps/studio/components/ui/ProjectUpgradeFailedBanner.tsx b/apps/studio/components/ui/ProjectUpgradeFailedBanner.tsx index 67018c65260..12c2b5bde9e 100644 --- a/apps/studio/components/ui/ProjectUpgradeFailedBanner.tsx +++ b/apps/studio/components/ui/ProjectUpgradeFailedBanner.tsx @@ -1,5 +1,6 @@ import { DatabaseUpgradeStatus } from '@supabase/shared-types/out/events' import dayjs from 'dayjs' +import { guessLocalTimezone } from 'lib/dayjs' import { X } from 'lucide-react' import { useEffect, useState } from 'react' @@ -28,7 +29,7 @@ export const ProjectUpgradeFailedBanner = () => { const isFailed = status === DatabaseUpgradeStatus.Failed const initiatedAt = dayjs .utc(initiated_at ?? 0) - .tz(dayjs.tz.guess()) + .tz(guessLocalTimezone()) .format('DD MMM YYYY HH:mm:ss') const subject = 'Upgrade%20failed%20for%20project' diff --git a/apps/studio/lib/dayjs.ts b/apps/studio/lib/dayjs.ts new file mode 100644 index 00000000000..383f8bd7a74 --- /dev/null +++ b/apps/studio/lib/dayjs.ts @@ -0,0 +1,11 @@ +import dayjs from 'dayjs' + +export function guessLocalTimezone(): string { + const guess = dayjs.tz.guess() + try { + Intl.DateTimeFormat(undefined, { timeZone: guess }) + return guess + } catch { + return 'UTC' + } +}