From 77bf0a4ec9c19b2ea260e17e91b4308d87152e87 Mon Sep 17 00:00:00 2001 From: Gildas Garcia <1122076+djhi@users.noreply.github.com> Date: Fri, 26 Jun 2026 11:48:58 +0200 Subject: [PATCH] chore: more dead code cleanup (#47312) ## Problem There's still more unused code in the repository which slows down everything: - checkouts - tooling - probably builds (not sure how good turbopack is at handling this) ## Solution - remove old unused code - remove more recent code after checking git history to ensure it's not unfinished/ongoing work ## Summary by CodeRabbit * **Chores** * Removed several outdated UI components and helper utilities to streamline the app. * Cleaned up unused analytics, database, and observability hooks and queries. * **Refactor** * Simplified data table, unified logs, and assistant panel internals by removing legacy display and navigation pieces. * **Bug Fixes** * Reduced the chance of showing stale or inconsistent status, chart, and metric views by eliminating obsolete display paths. --- .../StripeSyncEngine/StatusDisplay.tsx | 81 ------- .../Observability/ServiceHealthCard.tsx | 110 --------- .../usePostgrestOverviewMetrics.ts | 98 --------- .../components/shared/BlockField.tsx | 82 ------- .../components/shared/FieldWithSeeMore.tsx | 123 ----------- .../shared/TruncatedTextWithPopover.tsx | 37 ---- .../ServiceFlow/config/fieldHelpers.ts | 142 ------------ .../components/AuthUserHoverCard.tsx | 36 --- .../Observability.Commands.tsx | 92 -------- .../components/ui/AIAssistantPanel/hooks.ts | 73 ------ .../components/ui/Charts/ChartHandler.tsx | 208 ------------------ .../DataTableColumn/DataTableColumnHeader.tsx | 23 -- .../ui/DataTable/DataTableHeaderLayout.tsx | 35 --- .../ui/DataTable/DataTableSheetDetails.tsx | 123 ----------- .../ui/DataTable/DataTableToolbar.tsx | 85 ------- .../components/ui/DataTable/LiveRow.tsx | 17 -- .../components/ui/Forms/Form.constants.ts | 17 -- .../analytics/functions-req-stats-query.ts | 70 ------ .../functions-resource-usage-query.ts | 71 ------ .../api-keys/api-key-id-update-mutation.ts | 69 ------ .../data/database/database-query-constants.ts | 8 - .../data/database/entity-definitions-query.ts | 50 ----- .../data/database/pgbouncer-status-query.ts | 40 ---- apps/studio/data/utils/pagination.ts | 11 - 24 files changed, 1701 deletions(-) delete mode 100644 apps/studio/components/interfaces/Integrations/templates/StripeSyncEngine/StatusDisplay.tsx delete mode 100644 apps/studio/components/interfaces/Observability/ServiceHealthCard.tsx delete mode 100644 apps/studio/components/interfaces/Observability/usePostgrestOverviewMetrics.ts delete mode 100644 apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/BlockField.tsx delete mode 100644 apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/FieldWithSeeMore.tsx delete mode 100644 apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/TruncatedTextWithPopover.tsx delete mode 100644 apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/config/fieldHelpers.ts delete mode 100644 apps/studio/components/interfaces/UnifiedLogs/components/AuthUserHoverCard.tsx delete mode 100644 apps/studio/components/layouts/ObservabilityLayout/Observability.Commands.tsx delete mode 100644 apps/studio/components/ui/AIAssistantPanel/hooks.ts delete mode 100644 apps/studio/components/ui/Charts/ChartHandler.tsx delete mode 100644 apps/studio/components/ui/DataTable/DataTableColumn/DataTableColumnHeader.tsx delete mode 100644 apps/studio/components/ui/DataTable/DataTableHeaderLayout.tsx delete mode 100644 apps/studio/components/ui/DataTable/DataTableSheetDetails.tsx delete mode 100644 apps/studio/components/ui/DataTable/DataTableToolbar.tsx delete mode 100644 apps/studio/components/ui/DataTable/LiveRow.tsx delete mode 100644 apps/studio/components/ui/Forms/Form.constants.ts delete mode 100644 apps/studio/data/analytics/functions-req-stats-query.ts delete mode 100644 apps/studio/data/analytics/functions-resource-usage-query.ts delete mode 100644 apps/studio/data/api-keys/api-key-id-update-mutation.ts delete mode 100644 apps/studio/data/database/database-query-constants.ts delete mode 100644 apps/studio/data/database/entity-definitions-query.ts delete mode 100644 apps/studio/data/database/pgbouncer-status-query.ts delete mode 100644 apps/studio/data/utils/pagination.ts diff --git a/apps/studio/components/interfaces/Integrations/templates/StripeSyncEngine/StatusDisplay.tsx b/apps/studio/components/interfaces/Integrations/templates/StripeSyncEngine/StatusDisplay.tsx deleted file mode 100644 index 85bb055f2b5..00000000000 --- a/apps/studio/components/interfaces/Integrations/templates/StripeSyncEngine/StatusDisplay.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import { SchemaInstallationStatus } from '@stripe/sync-engine/supabase' -import { AlertCircle, Check, RefreshCwIcon } from 'lucide-react' - -import { - hasInstallError, - hasUninstallError, - isInstalled, - isInstalling, - isUninstalling, -} from './stripe-sync-status' - -export const StatusDisplay = ({ - status, - isInstallRequested, - isInstallInitiated, - isUninstallRequested, - isUninstallInitiated, - isUpgrade, - timedOut, -}: { - status: SchemaInstallationStatus - isInstallRequested: boolean - isInstallInitiated: boolean - isUninstallRequested: boolean - isUninstallInitiated: boolean - isUpgrade?: boolean - timedOut: boolean -}) => { - const installed = isInstalled(status) - const installError = hasInstallError(status) - const uninstallError = hasUninstallError(status) - const installInProgress = isInstalling(status) - const uninstallInProgress = isUninstalling(status) - - const installing = (installInProgress || isInstallRequested || isInstallInitiated) && !timedOut - const uninstalling = - (uninstallInProgress || isUninstallRequested || isUninstallInitiated) && !timedOut - - if (uninstalling) { - return ( - - - Uninstalling... - - ) - } - if (uninstallError) { - return ( - - - Uninstallation error - - ) - } - if (installing) { - return ( - - - {isUpgrade ? 'Upgrading...' : 'Installing...'} - - ) - } - if (installError) { - return ( - - - {isUpgrade ? 'Upgrade error' : 'Installation error'} - - ) - } - if (installed) { - return ( - - Installed - - ) - } - return ( - Not installed - ) -} diff --git a/apps/studio/components/interfaces/Observability/ServiceHealthCard.tsx b/apps/studio/components/interfaces/Observability/ServiceHealthCard.tsx deleted file mode 100644 index d8faea781b4..00000000000 --- a/apps/studio/components/interfaces/Observability/ServiceHealthCard.tsx +++ /dev/null @@ -1,110 +0,0 @@ -import Link from 'next/link' -import { Button, Card, CardContent, CardFooter, CardHeader, CardTitle, cn, Loading } from 'ui' -import { LogsBarChart } from 'ui-patterns/LogsBarChart' - -import type { LogsBarChartDatum } from '../ProjectHome/ProjectUsage.metrics' -import { getHealthStatus, type ServiceKey } from './ObservabilityOverview.utils' -import NoDataPlaceholder from '@/components/ui/Charts/NoDataPlaceholder' - -const colorClassMap: Record = { - muted: 'bg-muted', - destructive: 'bg-destructive', - warning: 'bg-warning', - brand: 'bg-brand', -} - -export type ServiceHealthCardProps = { - serviceName: string - serviceKey: ServiceKey - total: number - errorRate: number - errorCount: number - warningCount: number - chartData: LogsBarChartDatum[] - reportUrl?: string // undefined if feature flag disabled or no report available - logsUrl: string - isLoading: boolean - onBarClick: (datum: any) => void - datetimeFormat: string -} - -export const ServiceHealthCard = ({ - serviceName, - serviceKey: _serviceKey, - total, - errorRate, - errorCount, - warningCount, - chartData, - reportUrl, - logsUrl, - isLoading, - onBarClick, - datetimeFormat, -}: ServiceHealthCardProps) => { - const { color } = getHealthStatus(errorRate, total) - - return ( - - -
- -
- {serviceName} - -
-
- {total.toLocaleString()} - requests -
-
- {errorRate.toFixed(1)}% - error rate -
-
-
-
-
-
-
- Warn -
- {warningCount.toLocaleString()} -
-
-
-
- Err -
- {errorCount.toLocaleString()} -
-
- - - - - - } - /> - - - - - {reportUrl && ( - - )} - - - - ) -} diff --git a/apps/studio/components/interfaces/Observability/usePostgrestOverviewMetrics.ts b/apps/studio/components/interfaces/Observability/usePostgrestOverviewMetrics.ts deleted file mode 100644 index 99bbffca30b..00000000000 --- a/apps/studio/components/interfaces/Observability/usePostgrestOverviewMetrics.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { useQuery } from '@tanstack/react-query' - -import type { LogsBarChartDatum } from '../ProjectHome/ProjectUsage.metrics' -import { executeAnalyticsSql } from '@/data/logs/execute-analytics-sql' -import { safeSql, type SafeLogSqlFragment } from '@/data/logs/safe-analytics-sql' - -type PostgrestMetricsVariables = { - projectRef: string - startDate: string - endDate: string - interval: '1hr' | '1day' | '7day' -} - -function getIntervalTrunc(interval: '1hr' | '1day' | '7day'): SafeLogSqlFragment { - switch (interval) { - case '1hr': - return safeSql`minute` // 1-minute buckets for 1 hour - case '1day': - return safeSql`hour` // 1-hour buckets for 1 day - case '7day': - return safeSql`day` // 1-day buckets for 7 days - default: - return safeSql`hour` - } -} - -const POSTGREST_METRICS_SQL = (interval: '1hr' | '1day' | '7day'): SafeLogSqlFragment => { - const trunc = getIntervalTrunc(interval) - - return safeSql` - -- postgrest-overview-metrics - select - cast(timestamp_trunc(t.timestamp, ${trunc}) as datetime) as timestamp, - countif(response.status_code < 300) as ok_count, - countif(response.status_code >= 300 and response.status_code < 400) as warning_count, - countif(response.status_code >= 400) as error_count - FROM edge_logs t - cross join unnest(metadata) as m - cross join unnest(m.response) as response - cross join unnest(m.request) as request - WHERE - request.path like '/rest/%' - GROUP BY - timestamp - ORDER BY - timestamp ASC - ` -} - -type MetricsRow = { - timestamp: string - ok_count: number - warning_count: number - error_count: number -} - -async function fetchPostgrestMetrics( - { projectRef, startDate, endDate, interval }: PostgrestMetricsVariables, - signal?: AbortSignal -) { - const sql = POSTGREST_METRICS_SQL(interval) - - const data = await executeAnalyticsSql({ - projectRef, - endpoint: '/platform/projects/{ref}/analytics/endpoints/logs.all', - sql, - iso_timestamp_start: startDate, - iso_timestamp_end: endDate, - method: 'get', - signal, - }) - - if (data?.error) throw data.error - - return (data?.result || []) as MetricsRow[] -} - -export const usePostgrestOverviewMetrics = ( - { projectRef, startDate, endDate, interval }: PostgrestMetricsVariables, - options?: { enabled?: boolean } -) => { - return useQuery({ - queryKey: ['postgrest-overview-metrics', projectRef, startDate, endDate, interval], - queryFn: ({ signal }) => - fetchPostgrestMetrics({ projectRef, startDate, endDate, interval }, signal), - enabled: (options?.enabled ?? true) && Boolean(projectRef), - staleTime: 1000 * 60, - }) -} - -export const transformPostgrestMetrics = (rows: MetricsRow[]): LogsBarChartDatum[] => { - return rows.map((row) => ({ - timestamp: row.timestamp, - ok_count: row.ok_count, - warning_count: row.warning_count, - error_count: row.error_count, - })) -} diff --git a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/BlockField.tsx b/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/BlockField.tsx deleted file mode 100644 index fa70470b0e7..00000000000 --- a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/BlockField.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import { Skeleton } from 'ui' - -import { BlockFieldProps } from '../../types' -import { TruncatedTextWithPopover } from './TruncatedTextWithPopover' -import { DataTableColumnStatusCode } from '@/components/ui/DataTable/DataTableColumn/DataTableColumnStatusCode' -import { DataTableSheetRowAction } from '@/components/ui/DataTable/DataTableSheetRowAction' - -export const BlockField = ({ - config, - data, - enrichedData, - isLoading, - filterFields, - table, -}: BlockFieldProps) => { - const value = config.getValue(data, enrichedData) - const displayValue = value ?? 'No value' - const stringValue = String(displayValue) - - const shouldShowSkeleton = config.requiresEnrichedData && isLoading && !value - - const filterField = filterFields.find((field) => field.value === config.id) - const isFilterable = !!filterField - - // Special handling for status field and key fields - const isStatusField = config.id === 'status' - const isApiKeyField = config.id === 'api_key_role' - - // Truncation config - const maxLength = config.maxLength || 50 // Default to 50 characters - - const fieldContent = ( - <> -
{config.label}
-
- {shouldShowSkeleton ? ( - - ) : isStatusField && displayValue !== 'N/A' ? ( - - ) : isApiKeyField && displayValue !== 'N/A' ? ( - - ) : displayValue !== 'N/A' ? ( - - ) : ( - - {displayValue} - - )} -
- - ) - - if (isFilterable && !shouldShowSkeleton && displayValue !== 'N/A') { - return ( - - {fieldContent} - - ) - } - - return
{fieldContent}
-} diff --git a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/FieldWithSeeMore.tsx b/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/FieldWithSeeMore.tsx deleted file mode 100644 index c210412ea46..00000000000 --- a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/FieldWithSeeMore.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import { Table } from '@tanstack/react-table' -import { X } from 'lucide-react' -import { useState } from 'react' -import { Badge, Collapsible, CollapsibleContent, CollapsibleTrigger, Skeleton } from 'ui' - -import { BlockFieldConfig } from '../../types' -import { BlockField } from './BlockField' -import { DataTableFilterField } from '@/components/ui/DataTable/DataTable.types' - -// Single source of truth for field row styling -export const FieldRow = ({ - label, - value, - expandButton, -}: { - label: string - value: React.ReactNode - expandButton?: React.ReactNode -}) => ( -
-
- {label} - {expandButton} -
-
{value}
-
-) - -interface FieldWithSeeMoreProps { - primaryField: BlockFieldConfig - additionalFields: BlockFieldConfig[] - data: any - enrichedData?: any - isLoading?: boolean - filterFields: DataTableFilterField[] - table: Table - showValueAsBadge?: boolean -} - -// Primary field with expandable additional details -export const FieldWithSeeMore = ({ - primaryField, - additionalFields, - data, - enrichedData, - isLoading, - filterFields, - table, - showValueAsBadge = false, -}: FieldWithSeeMoreProps) => { - const [isOpen, setIsOpen] = useState(false) - const hasAdditionalData = additionalFields.some( - (field) => field.getValue(data, enrichedData) && field.getValue(data, enrichedData) !== 'N/A' - ) - - const primaryValue = primaryField.getValue(data, enrichedData) - const shouldShowSkeleton = primaryField.requiresEnrichedData && isLoading && !primaryValue - const isApiKeyField = primaryField.id === 'api_key_role' - - // Common value rendering logic - const renderValue = () => { - if (shouldShowSkeleton) { - return - } - - if (isApiKeyField && primaryValue && primaryValue !== 'N/A') { - return ( - - {primaryValue} - - ) - } - - if (showValueAsBadge && primaryValue && primaryValue !== 'N/A') { - return {primaryValue} - } - - return ( - - {primaryValue ?? 'N/A'} - - ) - } - - const expandButton = hasAdditionalData ? ( - - - - ) : undefined - - return ( -
- {hasAdditionalData ? ( - - - -
- {additionalFields.map((field) => ( - - ))} -
-
-
- ) : ( - - )} -
- ) -} diff --git a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/TruncatedTextWithPopover.tsx b/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/TruncatedTextWithPopover.tsx deleted file mode 100644 index 809f06a994e..00000000000 --- a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/components/shared/TruncatedTextWithPopover.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { useState } from 'react' -import { Popover, PopoverContent, PopoverTrigger } from 'ui' - -interface TruncatedTextWithPopoverProps { - text: string - maxLength?: number - className?: string - children?: React.ReactNode -} - -export const TruncatedTextWithPopover = ({ - text, - maxLength = 50, - className = '', - children, -}: TruncatedTextWithPopoverProps) => { - const [isOpen, setIsOpen] = useState(false) - const isTruncated = text.length > maxLength - const truncatedText = isTruncated ? text.substring(0, maxLength) + '...' : text - - // If not truncated, just render the text without popover - if (!isTruncated) { - return children ? <>{children} : {text} - } - - // If truncated, render with popover - return ( - - - {children || truncatedText} - - -
{text}
-
-
- ) -} diff --git a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/config/fieldHelpers.ts b/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/config/fieldHelpers.ts deleted file mode 100644 index a96245f8f53..00000000000 --- a/apps/studio/components/interfaces/UnifiedLogs/ServiceFlow/config/fieldHelpers.ts +++ /dev/null @@ -1,142 +0,0 @@ -import { BlockFieldConfig } from '../types' - -/** - * Common field configuration helpers to reduce duplication - */ - -// Helper for simple fields that fallback from enrichedData to data -export const createField = ( - id: string, - label: string, - enrichedKey?: string, - dataKey?: string, - requiresEnrichedData = false -): BlockFieldConfig => ({ - id, - label, - getValue: (data, enrichedData) => { - const eKey = enrichedKey || id - const dKey = dataKey || id - return enrichedData?.[eKey] || data?.[dKey] - }, - requiresEnrichedData, -}) - -// Helper for truncated text fields -export const createTruncatedField = ( - id: string, - label: string, - maxLength: number, - enrichedKey?: string, - dataKey?: string, - requiresEnrichedData = false -): BlockFieldConfig => ({ - id, - label, - getValue: (data, enrichedData) => { - const eKey = enrichedKey || id - const dKey = dataKey || id - const value = enrichedData?.[eKey] || data?.[dKey] - if (!value || typeof value !== 'string') return value - return value.length > maxLength ? `${value.substring(0, maxLength)}...` : value - }, - requiresEnrichedData, -}) - -// Helper for ID fields that show truncated version -export const createIdField = ( - id: string, - label: string, - truncateLength = 8, - enrichedKey?: string, - dataKey?: string, - requiresEnrichedData = false -): BlockFieldConfig => ({ - id, - label, - getValue: (data, enrichedData) => { - const eKey = enrichedKey || id - const dKey = dataKey || id - const value = enrichedData?.[eKey] || data?.[dKey] - if (!value) return null - const stringValue = String(value) - return truncateLength ? `${stringValue.substring(0, truncateLength)}...` : stringValue - }, - requiresEnrichedData, -}) - -// Helper for time/duration fields -export const createTimeField = ( - id: string, - label: string, - unit = 'ms', - enrichedKey?: string, - dataKey?: string, - requiresEnrichedData = false -): BlockFieldConfig => ({ - id, - label, - getValue: (data, enrichedData) => { - const eKey = enrichedKey || id - const dKey = dataKey || id - const time = enrichedData?.[eKey] || data?.[dKey] - return time ? `${time}${unit}` : null - }, - requiresEnrichedData, -}) - -// Helper for status fields with fallback logic -export const createStatusField = ( - id: string = 'status', - label: string = 'Status' -): BlockFieldConfig => ({ - id, - label, - getValue: (data, enrichedData) => enrichedData?.status || data?.status, -}) - -// Helper for path/filename extraction -export const createFileNameField = ( - id: string, - label: string, - pathKey = 'path', - requiresEnrichedData = false -): BlockFieldConfig => ({ - id, - label, - getValue: (data, enrichedData) => { - const path = enrichedData?.[pathKey] || data?.[pathKey] - if (!path) return null - // Remove query parameters and hash, get last segment - const cleanPath = path.split('?')[0].split('#')[0] - const segments = cleanPath.split('/') - return segments[segments.length - 1] || null - }, - requiresEnrichedData, -}) - -// Helper for conditional fields based on error status -export const createConditionalField = ( - id: string, - label: string, - getValue: (data: any, enrichedData?: any) => any, - errorValue: string = 'Unavailable', - deletedValue: string = 'Object deleted', - requiresEnrichedData = false -): BlockFieldConfig => ({ - id, - label, - getValue: (data, enrichedData) => { - const status = enrichedData?.status || data?.status - const numStatus = Number(status) - - if (status === 404 || status === '404') { - return deletedValue - } else if (numStatus >= 400) { - return errorValue - } - - return getValue(data, enrichedData) - }, - requiresEnrichedData, -}) diff --git a/apps/studio/components/interfaces/UnifiedLogs/components/AuthUserHoverCard.tsx b/apps/studio/components/interfaces/UnifiedLogs/components/AuthUserHoverCard.tsx deleted file mode 100644 index 4f902b66f1b..00000000000 --- a/apps/studio/components/interfaces/UnifiedLogs/components/AuthUserHoverCard.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { User } from 'lucide-react' -import { - HoverCard, - HoverCardContent, - HoverCardTrigger, -} from 'ui/src/components/shadcn/ui/hover-card' - -interface AuthUserHoverCardProps { - authUser: string -} - -export const AuthUserHoverCard = ({ authUser }: AuthUserHoverCardProps) => { - if (!authUser) return null - - return ( - - - - - -
-
- -

User Details

-
-
-
- ID/Email: {authUser} -
- {/* Additional user details can be added here if available */} -
-
-
-
- ) -} diff --git a/apps/studio/components/layouts/ObservabilityLayout/Observability.Commands.tsx b/apps/studio/components/layouts/ObservabilityLayout/Observability.Commands.tsx deleted file mode 100644 index ebfbd4bb87a..00000000000 --- a/apps/studio/components/layouts/ObservabilityLayout/Observability.Commands.tsx +++ /dev/null @@ -1,92 +0,0 @@ -import { useParams } from 'common' -import { useMemo } from 'react' -import type { CommandOptions, ICommand } from 'ui-patterns/CommandMenu' -import { orderSectionFirst, useQuery, useRegisterCommands } from 'ui-patterns/CommandMenu' - -import { COMMAND_MENU_SECTIONS } from '@/components/interfaces/App/CommandMenu/CommandMenu.utils' -import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' - -const QUERY_PERFORMANCE_COMMAND_ID = 'nav-reports-query-performance' - -export function useReportsGotoCommands(options?: CommandOptions) { - let { ref } = useParams() - ref ||= '_' - - const { reportsAll } = useIsFeatureEnabled(['reports:all']) - - const commandQuery = useQuery()?.toLowerCase() ?? '' - const prioritizeQueryPerformance = commandQuery.includes('query') - - const orderQueryPerformanceCommand = useMemo(() => { - if (!prioritizeQueryPerformance) return undefined - - return (existingCommands: ICommand[], incomingCommands: ICommand[]) => { - const filteredExisting = existingCommands.filter( - (command) => command.id !== QUERY_PERFORMANCE_COMMAND_ID - ) - - return [...incomingCommands, ...filteredExisting] - } - }, [prioritizeQueryPerformance]) - - const orderNavigateSection = useMemo(() => { - return prioritizeQueryPerformance ? orderSectionFirst : options?.orderSection - }, [options?.orderSection, prioritizeQueryPerformance]) - - useRegisterCommands( - COMMAND_MENU_SECTIONS.NAVIGATE, - reportsAll - ? [ - { - id: 'nav-reports', - name: 'Reports', - route: `/project/${ref}/observability`, - defaultHidden: true, - }, - { - id: 'nav-reports-api', - name: 'API Reports', - route: `/project/${ref}/observability/api-overview`, - defaultHidden: true, - }, - { - id: 'nav-reports-storage', - name: 'Storage Reports', - route: `/project/${ref}/observability/storage`, - defaultHidden: true, - }, - { - id: 'nav-reports-database', - name: 'Database Reports', - route: `/project/${ref}/observability/database`, - defaultHidden: true, - }, - ] - : [], - { - ...options, - orderSection: orderNavigateSection, - deps: [ref, orderNavigateSection, ...(options?.deps ?? [])], - } - ) - - useRegisterCommands( - COMMAND_MENU_SECTIONS.NAVIGATE, - reportsAll - ? [ - { - id: QUERY_PERFORMANCE_COMMAND_ID, - name: 'Query Performance Reports', - route: `/project/${ref}/observability/query-performance`, - defaultHidden: true, - }, - ] - : [], - { - ...options, - orderCommands: orderQueryPerformanceCommand ?? options?.orderCommands, - orderSection: orderNavigateSection, - deps: [ref, orderQueryPerformanceCommand, orderNavigateSection, ...(options?.deps ?? [])], - } - ) -} diff --git a/apps/studio/components/ui/AIAssistantPanel/hooks.ts b/apps/studio/components/ui/AIAssistantPanel/hooks.ts deleted file mode 100644 index 70a2f231bdc..00000000000 --- a/apps/studio/components/ui/AIAssistantPanel/hooks.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { useCallback, useEffect, useRef, useState } from 'react' - -interface UseAutoScrollProps { - enabled?: boolean -} - -export function useAutoScroll({ enabled = true }: UseAutoScrollProps = {}) { - const [container, setContainer] = useState(null) - const [isSticky, setIsSticky] = useState(true) - const isStickyRef = useRef(true) - const lastScrollHeightRef = useRef(null) - - const ref = useCallback((element: HTMLDivElement | null) => { - if (element) { - setContainer(element) - } - }, []) - - const scrollToEnd = useCallback(() => { - if (container) { - isStickyRef.current = true - setIsSticky(true) - container.scrollTo({ - top: container.scrollHeight, - behavior: 'smooth', - }) - } - }, [container]) - - useEffect(() => { - if (!container || !enabled) return - - let timeoutId: NodeJS.Timeout - - const resizeObserver = new ResizeObserver(() => { - clearTimeout(timeoutId) - timeoutId = setTimeout(() => { - if ( - lastScrollHeightRef.current != null && - container.scrollHeight !== lastScrollHeightRef.current - ) { - lastScrollHeightRef.current = container.scrollHeight - if (isStickyRef.current) { - scrollToEnd() - } - } - }, 100) - }) - - const handleScroll = () => { - const isAtBottom = - Math.abs(container.scrollHeight - container.scrollTop - container.clientHeight) < 10 - - isStickyRef.current = isAtBottom - setIsSticky(isAtBottom) - } - - // Observe all children of the container - Array.from(container.children).forEach((child) => { - resizeObserver.observe(child) - }) - - container.addEventListener('scroll', handleScroll) - - return () => { - clearTimeout(timeoutId) - resizeObserver.disconnect() - container.removeEventListener('scroll', handleScroll) - } - }, [container, enabled, scrollToEnd]) - - return { ref, isSticky, scrollToEnd, setIsSticky } -} diff --git a/apps/studio/components/ui/Charts/ChartHandler.tsx b/apps/studio/components/ui/Charts/ChartHandler.tsx deleted file mode 100644 index 52b5921ab47..00000000000 --- a/apps/studio/components/ui/Charts/ChartHandler.tsx +++ /dev/null @@ -1,208 +0,0 @@ -import dayjs from 'dayjs' -import { Activity, BarChartIcon, Loader2 } from 'lucide-react' -import { useRouter } from 'next/router' -import { PropsWithChildren, useMemo, useState } from 'react' -import { Button, Tooltip, TooltipContent, TooltipTrigger, WarningIcon } from 'ui' - -import type { ChartData } from './Charts.types' -import AreaChart from '@/components/ui/Charts/AreaChart' -import BarChart from '@/components/ui/Charts/BarChart' -import { AnalyticsInterval } from '@/data/analytics/constants' -import { mapMultiResponseToAnalyticsData } from '@/data/analytics/infra-monitoring-queries' -import { - InfraMonitoringAttribute, - useInfraMonitoringAttributesQuery, -} from '@/data/analytics/infra-monitoring-query' -import { - ProjectDailyStatsAttribute, - useProjectDailyStatsQuery, -} from '@/data/analytics/project-daily-stats-query' -import { useDatabaseSelectorStateSnapshot } from '@/state/database-selector' - -interface ChartHandlerProps { - id?: string - label: string - attribute: string - provider: 'infra-monitoring' | 'daily-stats' - startDate: string - endDate: string - interval: string - customDateFormat?: string - defaultChartStyle?: 'bar' | 'line' - hideChartType?: boolean - data?: ChartData - isLoading?: boolean - format?: string - highlightedValue?: string | number - syncId?: string -} - -/** - * Controls chart display state. Optionally fetches static chart data if data is not provided. - * - * If the `data` prop is provided, it will disable automatic chart data fetching and pass the data directly to the chart render. - * - loading state can also be provided through the `isLoading` prop, to display loading placeholders. Ignored if `data` key not provided. - * - if `isLoading=true` and `data` is `undefined`, loading error message will be shown. - * - * Provided data must be in the expected chart format. - */ -const ChartHandler = ({ - label, - attribute, - provider, - startDate, - endDate, - interval, - customDateFormat, - children = null, - defaultChartStyle = 'bar', - hideChartType = false, - data, - isLoading, - format, - highlightedValue, - syncId, - ...otherProps -}: PropsWithChildren) => { - const router = useRouter() - const { ref } = router.query - - const state = useDatabaseSelectorStateSnapshot() - const [chartStyle, setChartStyle] = useState(defaultChartStyle) - - const databaseIdentifier = state.selectedDatabaseId - - const { data: dailyStatsData, isPending: isFetchingDailyStats } = useProjectDailyStatsQuery( - { - projectRef: ref as string, - attribute: attribute as ProjectDailyStatsAttribute, - startDate: dayjs(startDate).format('YYYY-MM-DD'), - endDate: dayjs(endDate).format('YYYY-MM-DD'), - }, - { enabled: provider === 'daily-stats' && data === undefined } - ) - - const { data: infraMonitoringData, isPending: isFetchingInfraMonitoring } = - useInfraMonitoringAttributesQuery( - { - projectRef: ref as string, - attributes: [attribute as InfraMonitoringAttribute], - startDate, - endDate, - interval: interval as AnalyticsInterval, - databaseIdentifier, - }, - { enabled: provider === 'infra-monitoring' && data === undefined } - ) - - const transformedInfraData = useMemo(() => { - if (!infraMonitoringData) return undefined - const mapped = mapMultiResponseToAnalyticsData(infraMonitoringData, [ - attribute as InfraMonitoringAttribute, - ]) - return mapped[attribute] - }, [infraMonitoringData, attribute]) - - const chartData = - data || - (provider === 'infra-monitoring' - ? transformedInfraData - : provider === 'daily-stats' - ? dailyStatsData - : undefined) - - const loading = - isLoading || - (provider === 'infra-monitoring' - ? isFetchingInfraMonitoring - : provider === 'daily-stats' - ? isFetchingDailyStats - : isLoading) - - const shouldHighlightMaxValue = - provider === 'daily-stats' && - !attribute.includes('ingress') && - !attribute.includes('egress') && - chartData !== undefined && - 'maximum' in chartData - const shouldHighlightTotalGroupedValue = chartData !== undefined && 'totalGrouped' in chartData - - const _highlightedValue = - highlightedValue !== undefined - ? highlightedValue - : shouldHighlightMaxValue - ? chartData?.maximum - : provider === 'daily-stats' - ? chartData?.total - : shouldHighlightTotalGroupedValue - ? chartData?.totalGrouped?.[attribute] - : (chartData?.data[chartData?.data.length - 1] as any)?.[attribute as any] - - if (loading) { - return ( -
- -

Loading data for {label}

-
- ) - } - - if (chartData === undefined) { - return ( -
- -

Unable to load data for {label}

-
- ) - } - - return ( -
-
- {!hideChartType && ( - - -
- {chartStyle === 'bar' ? ( - - ) : ( - - )} -
- ) -} - -export default ChartHandler diff --git a/apps/studio/components/ui/DataTable/DataTableColumn/DataTableColumnHeader.tsx b/apps/studio/components/ui/DataTable/DataTableColumn/DataTableColumnHeader.tsx deleted file mode 100644 index ee6f6127aec..00000000000 --- a/apps/studio/components/ui/DataTable/DataTableColumn/DataTableColumnHeader.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { type Column } from '@tanstack/react-table' -import { TanStackTableHeadSort } from 'ui-patterns/Table' - -interface DataTableColumnHeaderProps { - column: Column - title: string - className?: string -} - -/** - * @deprecated Use `TanStackTableHeadSort` from `ui-patterns/Table` instead. - */ -export const DataTableColumnHeader = ({ - column, - title, - className, -}: DataTableColumnHeaderProps) => { - return ( - - {title} - - ) -} diff --git a/apps/studio/components/ui/DataTable/DataTableHeaderLayout.tsx b/apps/studio/components/ui/DataTable/DataTableHeaderLayout.tsx deleted file mode 100644 index 3a7f19778b9..00000000000 --- a/apps/studio/components/ui/DataTable/DataTableHeaderLayout.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { forwardRef, PropsWithChildren, useEffect, useRef } from 'react' -import { cn } from 'ui' - -export const DataTableHeaderLayout = forwardRef< - HTMLDivElement, - PropsWithChildren<{ - setTopBarHeight: (height: number) => void - }> ->(({ setTopBarHeight, ...props }, _ref) => { - const topBarRef = useRef(null) - - useEffect(() => { - const observer = new ResizeObserver(() => { - const rect = topBarRef.current?.getBoundingClientRect() - if (rect) { - setTopBarHeight(rect.height) - } - }) - - const topBar = topBarRef.current - if (!topBar) return - - observer.observe(topBar) - return () => observer.unobserve(topBar) - }, [topBarRef]) - - return ( -
- ) -}) -DataTableHeaderLayout.displayName = 'DataTableHeaderLayout' diff --git a/apps/studio/components/ui/DataTable/DataTableSheetDetails.tsx b/apps/studio/components/ui/DataTable/DataTableSheetDetails.tsx deleted file mode 100644 index cee10d24cd9..00000000000 --- a/apps/studio/components/ui/DataTable/DataTableSheetDetails.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import { ChevronDown, ChevronUp, X } from 'lucide-react' -import { ReactNode, useCallback, useEffect, useMemo } from 'react' -import { Button, cn, Separator, Skeleton, Tooltip, TooltipContent, TooltipTrigger } from 'ui' - -import { Kbd } from './primitives/Kbd' -import { useDataTable } from './providers/DataTableProvider' - -export interface DataTableSheetDetailsProps { - title?: ReactNode - titleClassName?: string - children?: ReactNode -} - -export function DataTableSheetDetails({ - title, - titleClassName, - children, -}: DataTableSheetDetailsProps) { - const { table, rowSelection, isLoading } = useDataTable() - - const selectedRowKey = Object.keys(rowSelection)?.[0] - - const selectedRow = useMemo(() => { - if (isLoading && !selectedRowKey) return - return table.getRowModel().rows.find((row) => row.id === selectedRowKey) - }, [selectedRowKey, isLoading, table]) - - const index = table.getRowModel().rows.findIndex((row) => row.id === selectedRow?.id) - - const nextId = useMemo(() => table.getRowModel().rows[index + 1]?.id, [index, table]) - - const prevId = useMemo(() => table.getRowModel().rows[index - 1]?.id, [index, table]) - - const onPrev = useCallback(() => { - if (prevId) table.setRowSelection({ [prevId]: true }) - }, [prevId, table]) - - const onNext = useCallback(() => { - if (nextId) table.setRowSelection({ [nextId]: true }) - }, [nextId, table]) - - useEffect(() => { - const down = (e: KeyboardEvent) => { - if (!selectedRowKey) return - - // REMINDER: prevent dropdown navigation inside of sheet to change row selection - const activeElement = document.activeElement - const isMenuActive = activeElement?.closest('[role="menu"]') - - if (isMenuActive) return - - if (e.key === 'ArrowUp') { - e.preventDefault() - onPrev() - } - if (e.key === 'ArrowDown') { - e.preventDefault() - onNext() - } - } - - document.addEventListener('keydown', down) - return () => document.removeEventListener('keydown', down) - }, [selectedRowKey, onNext, onPrev]) - - return ( -
-
-
- {isLoading && !selectedRowKey ? : title} -
-
- - -
-
- - {children} -
- ) -} diff --git a/apps/studio/components/ui/DataTable/DataTableToolbar.tsx b/apps/studio/components/ui/DataTable/DataTableToolbar.tsx deleted file mode 100644 index 7deab48fb3b..00000000000 --- a/apps/studio/components/ui/DataTable/DataTableToolbar.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import { PanelLeftClose, PanelLeftOpen } from 'lucide-react' -import { ReactNode, useMemo } from 'react' -import { Button, Tooltip, TooltipContent, TooltipTrigger } from 'ui' - -import { formatCompactNumber } from './DataTable.utils' -import { DataTableFilterControlsDrawer } from './DataTableFilters/DataTableFilterControlsDrawer' -import { DataTableResetButton } from './DataTableResetButton' -import { DataTableViewOptions } from './DataTableViewOptions' -import { Kbd } from './primitives/Kbd' -import { useDataTable } from './providers/DataTableProvider' -import { SHORTCUT_IDS } from '@/state/shortcuts/registry' -import { useShortcut } from '@/state/shortcuts/useShortcut' - -interface DataTableToolbarProps { - renderActions?: () => ReactNode - isFilterBarOpen: boolean - setIsFilterBarOpen: React.Dispatch> -} - -export function DataTableToolbar({ - renderActions, - isFilterBarOpen, - setIsFilterBarOpen, -}: DataTableToolbarProps) { - const { table, isLoading, columnFilters } = useDataTable() - const filters = table.getState().columnFilters - - useShortcut(SHORTCUT_IDS.DATA_TABLE_TOGGLE_FILTERS, () => setIsFilterBarOpen((prev) => !prev)) - - const rows = useMemo( - () => ({ - total: table.getCoreRowModel().rows.length, - filtered: table.getFilteredRowModel().rows.length, - }), - [isLoading, columnFilters] - ) - - return ( -
-
- - - - - -

- Toggle controls with{' '} - - ⌘ - B - -

-
-
-
- -
-
-

- {formatCompactNumber(rows.filtered)} of{' '} - {formatCompactNumber(rows.total)} row(s){' '} - filtered -

-

- {formatCompactNumber(rows.filtered)}{' '} - row(s) -

-
-
-
- {filters.length ? : null} - {renderActions?.()} - -
-
- ) -} diff --git a/apps/studio/components/ui/DataTable/LiveRow.tsx b/apps/studio/components/ui/DataTable/LiveRow.tsx deleted file mode 100644 index 1b1305dd7ac..00000000000 --- a/apps/studio/components/ui/DataTable/LiveRow.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { TableCell, TableRow } from 'ui' - -export function LiveRow({ colSpan }: { colSpan: number }) { - return ( - - -
- - -
-
- - Live Mode - -
- ) -} diff --git a/apps/studio/components/ui/Forms/Form.constants.ts b/apps/studio/components/ui/Forms/Form.constants.ts deleted file mode 100644 index e3910fabb06..00000000000 --- a/apps/studio/components/ui/Forms/Form.constants.ts +++ /dev/null @@ -1,17 +0,0 @@ -import * as z from 'zod' - -export const StringNumberOrNull = z - .string() - .transform((v) => (v === '' ? null : v)) - .nullable() - .refine((value) => value === null || !isNaN(Number(value)), { - message: 'Invalid number', - }) - .transform((value) => (value === null ? null : Number(value))) - -/** - * [Joshen] After wrangling with RHF I think this is the easiest way to handle nullable number fields - * - Declare the field normally as you would in the zod form schema (e.g field: z.number().nullable()) - * - In the InputField, add a form.register call `{...form.register('field_name', { setValueAs: setValueAsNullableNumber })}` - */ -export const setValueAsNullableNumber = (v: any) => (v === '' || v === null ? null : parseInt(v)) diff --git a/apps/studio/data/analytics/functions-req-stats-query.ts b/apps/studio/data/analytics/functions-req-stats-query.ts deleted file mode 100644 index 88f04586fbe..00000000000 --- a/apps/studio/data/analytics/functions-req-stats-query.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { useQuery } from '@tanstack/react-query' -import { operations } from 'api-types' - -import { analyticsKeys } from './keys' -import { get, handleError } from '@/data/fetchers' -import { UseCustomQueryOptions } from '@/types' - -export type FunctionsReqStatsVariables = { - projectRef?: string - functionId?: string - interval?: operations['FunctionsLogsController_getRequestStats']['parameters']['query']['interval'] -} - -export type FunctionsReqStatsResponse = any - -export async function getFunctionsReqStats( - { projectRef, functionId, interval }: FunctionsReqStatsVariables, - signal?: AbortSignal -) { - if (!projectRef) { - throw new Error('projectRef is required') - } - if (!functionId) { - throw new Error('functionId is required') - } - if (!interval) { - throw new Error('interval is required') - } - - const { data, error } = await get( - '/platform/projects/{ref}/analytics/endpoints/functions.req-stats', - { - params: { - path: { - ref: projectRef, - }, - query: { - function_id: functionId, - interval, - }, - }, - signal, - } - ) - - if (error) handleError(error) - - return data -} - -export type FunctionsReqStatsData = Awaited> -export type FunctionsReqStatsError = unknown - -export const useFunctionsReqStatsQuery = ( - { projectRef, functionId, interval }: FunctionsReqStatsVariables, - { - enabled = true, - ...options - }: UseCustomQueryOptions = {} -) => - useQuery({ - queryKey: analyticsKeys.functionsReqStats(projectRef, { functionId, interval }), - queryFn: ({ signal }) => getFunctionsReqStats({ projectRef, functionId, interval }, signal), - enabled: - enabled && - typeof projectRef !== 'undefined' && - typeof functionId !== 'undefined' && - typeof interval !== 'undefined', - ...options, - }) diff --git a/apps/studio/data/analytics/functions-resource-usage-query.ts b/apps/studio/data/analytics/functions-resource-usage-query.ts deleted file mode 100644 index 44622300a9d..00000000000 --- a/apps/studio/data/analytics/functions-resource-usage-query.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { useQuery } from '@tanstack/react-query' -import { operations } from 'api-types' - -import { analyticsKeys } from './keys' -import { get, handleError } from '@/data/fetchers' -import { UseCustomQueryOptions } from '@/types' - -export type FunctionsResourceUsageVariables = { - projectRef?: string - functionId?: string - interval?: operations['FunctionsLogsController_getRequestStats']['parameters']['query']['interval'] -} - -export type FunctionsResourceUsageResponse = any - -export async function getFunctionsResourceUsage( - { projectRef, functionId, interval }: FunctionsResourceUsageVariables, - signal?: AbortSignal -) { - if (!projectRef) { - throw new Error('projectRef is required') - } - if (!functionId) { - throw new Error('functionId is required') - } - if (!interval) { - throw new Error('interval is required') - } - - const { data, error } = await get( - '/platform/projects/{ref}/analytics/endpoints/functions.resource-usage', - { - params: { - path: { - ref: projectRef, - }, - query: { - function_id: functionId, - interval, - }, - }, - signal, - } - ) - - if (error) handleError(error) - - return data -} - -export type FunctionsResourceUsageData = Awaited> -export type FunctionsResourceUsageError = unknown - -export const useFunctionsResourceUsageQuery = ( - { projectRef, functionId, interval }: FunctionsResourceUsageVariables, - { - enabled = true, - ...options - }: UseCustomQueryOptions = {} -) => - useQuery({ - queryKey: analyticsKeys.functionsResourceUsage(projectRef, { functionId, interval }), - queryFn: ({ signal }) => - getFunctionsResourceUsage({ projectRef, functionId, interval }, signal), - enabled: - enabled && - typeof projectRef !== 'undefined' && - typeof functionId !== 'undefined' && - typeof interval !== 'undefined', - ...options, - }) diff --git a/apps/studio/data/api-keys/api-key-id-update-mutation.ts b/apps/studio/data/api-keys/api-key-id-update-mutation.ts deleted file mode 100644 index 108e43667ad..00000000000 --- a/apps/studio/data/api-keys/api-key-id-update-mutation.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { useMutation, useQueryClient } from '@tanstack/react-query' -import { toast } from 'sonner' - -import { apiKeysKeys } from './keys' -import { handleError, patch } from '@/data/fetchers' -import type { ResponseError, UseCustomMutationOptions } from '@/types' - -export interface UpdateAPIKeybyIdVariables { - projectRef?: string - id?: string - description?: string -} - -export async function updateAPIKeysById( - { projectRef, id, description }: UpdateAPIKeybyIdVariables, - signal?: AbortSignal -) { - if (typeof projectRef === 'undefined') throw new Error('projectRef is required') - if (typeof id === 'undefined') throw new Error('API key ID is required') - - const { data, error } = await patch('/v1/projects/{ref}/api-keys/{id}', { - params: { - path: { ref: projectRef, id }, - query: { reveal: false }, - }, - body: { - description: description, - }, - signal, - }) - - if (error) { - handleError(error) - } - - return data -} - -export type ResourceUpdateData = Awaited> - -export const useResourceUpdateMutation = ({ - onSuccess, - onError, - ...options -}: Omit< - UseCustomMutationOptions, - 'mutationFn' -> = {}) => { - const queryClient = useQueryClient() - - return useMutation({ - mutationFn: (vars) => updateAPIKeysById(vars), - async onSuccess(data, variables, context) { - const { projectRef } = variables - - await queryClient.invalidateQueries({ queryKey: apiKeysKeys.list(projectRef) }) - - await onSuccess?.(data, variables, context) - }, - async onError(data, variables, context) { - if (onError === undefined) { - toast.error(`Failed to mutate: ${data.message}`) - } else { - onError(data, variables, context) - } - }, - ...options, - }) -} diff --git a/apps/studio/data/database/database-query-constants.ts b/apps/studio/data/database/database-query-constants.ts deleted file mode 100644 index f05a837a205..00000000000 --- a/apps/studio/data/database/database-query-constants.ts +++ /dev/null @@ -1,8 +0,0 @@ -// https://www.postgresql.org/docs/current/catalog-pg-constraint.html -export enum FOREIGN_KEY_CASCADE_ACTION { - NO_ACTION = 'a', - RESTRICT = 'r', - CASCADE = 'c', - SET_NULL = 'n', - SET_DEFAULT = 'd', -} diff --git a/apps/studio/data/database/entity-definitions-query.ts b/apps/studio/data/database/entity-definitions-query.ts deleted file mode 100644 index a016eaca4ba..00000000000 --- a/apps/studio/data/database/entity-definitions-query.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { getEntityDefinitionsSql } from '@supabase/pg-meta' -import { useQuery } from '@tanstack/react-query' - -import { databaseKeys } from './keys' -import { executeSql } from '@/data/sql/execute-sql-mutation' -import { ResponseError, UseCustomQueryOptions } from '@/types' - -export type EntityDefinitionsVariables = { - limit?: number - projectRef?: string - connectionString?: string | null - schemas: string[] -} - -export async function getEntityDefinitions( - { projectRef, connectionString, schemas, limit }: EntityDefinitionsVariables, - signal?: AbortSignal -) { - const sql = getEntityDefinitionsSql({ schemas, limit }) - const { result } = await executeSql( - { - projectRef, - connectionString, - sql, - queryKey: ['entity-definitions', schemas], - }, - signal - ) - - return result[0].data.definitions -} - -type EntityDefinition = { id: number; sql: string } -export type EntityDefinitionsData = EntityDefinition[] -export type EntityDefinitionsError = ResponseError - -export const useEntityDefinitionsQuery = ( - { projectRef, connectionString, schemas, limit }: EntityDefinitionsVariables, - { - enabled = true, - ...options - }: UseCustomQueryOptions = {} -) => - useQuery({ - queryKey: databaseKeys.entityDefinitions(projectRef, schemas), - queryFn: ({ signal }) => - getEntityDefinitions({ projectRef, connectionString, schemas, limit }, signal), - enabled: enabled && typeof projectRef !== 'undefined' && schemas.length > 0, - ...options, - }) diff --git a/apps/studio/data/database/pgbouncer-status-query.ts b/apps/studio/data/database/pgbouncer-status-query.ts deleted file mode 100644 index 6354168e155..00000000000 --- a/apps/studio/data/database/pgbouncer-status-query.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { useQuery } from '@tanstack/react-query' - -import { databaseKeys } from './keys' -import { get, handleError } from '@/data/fetchers' -import type { ResponseError, UseCustomQueryOptions } from '@/types' - -export type PgbouncerStatusVariables = { - projectRef?: string -} - -export async function getPgbouncerStatus( - { projectRef }: PgbouncerStatusVariables, - signal?: AbortSignal -) { - if (!projectRef) throw new Error('projectRef is required') - - const { data, error } = await get('/platform/projects/{ref}/config/pgbouncer/status', { - params: { path: { ref: projectRef } }, - signal, - }) - if (error) handleError(error) - return data -} - -export type PgbouncerStatusData = Awaited> -export type PgbouncerStatusError = ResponseError - -export const usePgbouncerStatusQuery = ( - { projectRef }: PgbouncerStatusVariables, - { - enabled = true, - ...options - }: UseCustomQueryOptions = {} -) => - useQuery({ - queryKey: databaseKeys.pgbouncerStatus(projectRef), - queryFn: ({ signal }) => getPgbouncerStatus({ projectRef }, signal), - enabled: enabled && typeof projectRef !== 'undefined', - ...options, - }) diff --git a/apps/studio/data/utils/pagination.ts b/apps/studio/data/utils/pagination.ts deleted file mode 100644 index ea72c3e45d6..00000000000 --- a/apps/studio/data/utils/pagination.ts +++ /dev/null @@ -1,11 +0,0 @@ -/* Utils for use in queries / mutations */ - -export const DEFAULT_PAGE_SIZE = 100 - -export function getPagination(page?: number, size: number = DEFAULT_PAGE_SIZE) { - const limit = size - const from = page ? page * limit : 0 - const to = page ? from + size - 1 : size - 1 - - return { from, to } -}