mirror of
https://github.com/supabase/supabase.git
synced 2026-06-13 10:09:12 +08:00
This PR migrates the whole monorepo to use Tailwind v4: - Removed `@tailwindcss/container-queries` plugin since it's included by default in v4, - Bump all instances of Tailwind to v4. Made minimal changes to the shared config to remove non-supported features (`alpha` mentions), - Migrate all apps to be compatible with v4 configs, - Fix the `typography.css` import in 3 apps, - Add missing rules which were included by default in v3, - Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot of classes - Rename all misnamed classes according to https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all apps. --------- Co-authored-by: Jordi Enric <jordi.err@gmail.com>
158 lines
5.2 KiB
TypeScript
158 lines
5.2 KiB
TypeScript
import { useQueryClient } from '@tanstack/react-query'
|
|
import { createContext, PropsWithChildren, useCallback, useContext, useState } from 'react'
|
|
import { Sheet, SheetContent, SheetHeader, SheetTitle } from 'ui'
|
|
|
|
import { useIndexAdvisorStatus } from '@/components/interfaces/QueryPerformance/hooks/useIsIndexAdvisorStatus'
|
|
import { QueryIndexes } from '@/components/interfaces/QueryPerformance/QueryIndexes'
|
|
import { databaseKeys } from '@/data/database/keys'
|
|
import {
|
|
cleanIndexColumnName,
|
|
IndexAdvisorSuggestion,
|
|
TableIndexAdvisorData,
|
|
useTableIndexAdvisorQuery,
|
|
} from '@/data/database/table-index-advisor-query'
|
|
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
|
|
|
|
interface TableIndexAdvisorContextValue {
|
|
isLoading: boolean
|
|
isAvailable: boolean
|
|
isEnabled: boolean
|
|
columnsWithSuggestions: string[]
|
|
suggestions: TableIndexAdvisorData['suggestions']
|
|
openSheet: (columnName: string) => void
|
|
getSuggestionsForColumn: (columnName: string) => IndexAdvisorSuggestion[]
|
|
invalidate: () => Promise<void>
|
|
}
|
|
|
|
const TableIndexAdvisorContext = createContext<TableIndexAdvisorContextValue>({
|
|
isLoading: false,
|
|
isAvailable: false,
|
|
isEnabled: false,
|
|
columnsWithSuggestions: [],
|
|
suggestions: [],
|
|
openSheet: () => {},
|
|
getSuggestionsForColumn: () => [],
|
|
invalidate: async () => {},
|
|
})
|
|
|
|
interface TableIndexAdvisorProviderProps {
|
|
schema: string
|
|
table: string
|
|
}
|
|
|
|
export function TableIndexAdvisorProvider({
|
|
children,
|
|
schema,
|
|
table,
|
|
}: PropsWithChildren<TableIndexAdvisorProviderProps>) {
|
|
const { data: project } = useSelectedProjectQuery()
|
|
const { isIndexAdvisorAvailable, isIndexAdvisorEnabled } = useIndexAdvisorStatus()
|
|
const queryClient = useQueryClient()
|
|
const [isSheetOpen, setIsSheetOpen] = useState(false)
|
|
const [selectedColumn, setSelectedColumn] = useState<string | undefined>(undefined)
|
|
|
|
const { data, isLoading } = useTableIndexAdvisorQuery(
|
|
{
|
|
projectRef: project?.ref,
|
|
connectionString: project?.connectionString,
|
|
schema,
|
|
table,
|
|
},
|
|
{
|
|
enabled: isIndexAdvisorEnabled && !!schema && !!table,
|
|
}
|
|
)
|
|
|
|
const openSheet = useCallback((columnName: string) => {
|
|
setSelectedColumn(columnName)
|
|
setIsSheetOpen(true)
|
|
}, [])
|
|
|
|
const closeSheet = useCallback(() => {
|
|
setIsSheetOpen(false)
|
|
setSelectedColumn(undefined)
|
|
}, [])
|
|
|
|
const getSuggestionsForColumn = useCallback(
|
|
(columnName: string): IndexAdvisorSuggestion[] => {
|
|
if (!data?.suggestions) return []
|
|
// Filter suggestions that include this column in their index statements
|
|
return data.suggestions.filter((suggestion) =>
|
|
suggestion.index_statements.some((stmt) => {
|
|
const match = stmt.match(/USING\s+\w+\s*\(([^)]+)\)/i)
|
|
if (match) {
|
|
const columns = match[1].split(',').map((c) => cleanIndexColumnName(c))
|
|
return columns.includes(columnName)
|
|
}
|
|
return false
|
|
})
|
|
)
|
|
},
|
|
[data?.suggestions]
|
|
)
|
|
|
|
const invalidate = useCallback(async () => {
|
|
if (project?.ref && schema && table) {
|
|
await queryClient.invalidateQueries({
|
|
queryKey: databaseKeys.tableIndexAdvisor(project.ref, schema, table),
|
|
})
|
|
}
|
|
}, [queryClient, project?.ref, schema, table])
|
|
|
|
// Get the first suggestion for the selected column to pass to QueryIndexes
|
|
const selectedSuggestion = selectedColumn ? getSuggestionsForColumn(selectedColumn)[0] : null
|
|
|
|
const prefetchedIndexAdvisorResult = selectedSuggestion
|
|
? {
|
|
errors: [],
|
|
index_statements: selectedSuggestion.index_statements,
|
|
startup_cost_before: selectedSuggestion.startup_cost_before,
|
|
startup_cost_after: selectedSuggestion.startup_cost_after,
|
|
total_cost_before: selectedSuggestion.total_cost_before,
|
|
total_cost_after: selectedSuggestion.total_cost_after,
|
|
}
|
|
: null
|
|
|
|
const value: TableIndexAdvisorContextValue = {
|
|
isLoading,
|
|
isAvailable: isIndexAdvisorAvailable,
|
|
isEnabled: isIndexAdvisorEnabled,
|
|
columnsWithSuggestions: data?.columnsWithSuggestions ?? [],
|
|
suggestions: data?.suggestions ?? [],
|
|
openSheet,
|
|
getSuggestionsForColumn,
|
|
invalidate,
|
|
}
|
|
|
|
return (
|
|
<TableIndexAdvisorContext.Provider value={value}>
|
|
{children}
|
|
<Sheet open={isSheetOpen} onOpenChange={(open) => !open && closeSheet()}>
|
|
<SheetContent className="flex flex-col gap-0 p-0 lg:w-[calc(100vw-802px)]! max-w-[700px]">
|
|
<SheetHeader className="border-b px-5 py-3">
|
|
<SheetTitle>Index Recommendation</SheetTitle>
|
|
</SheetHeader>
|
|
{selectedSuggestion && (
|
|
<QueryIndexes
|
|
selectedRow={{ query: selectedSuggestion.query }}
|
|
columnName={selectedColumn}
|
|
suggestedSelectQuery={selectedSuggestion.query}
|
|
prefetchedIndexAdvisorResult={prefetchedIndexAdvisorResult}
|
|
onClose={closeSheet}
|
|
/>
|
|
)}
|
|
</SheetContent>
|
|
</Sheet>
|
|
</TableIndexAdvisorContext.Provider>
|
|
)
|
|
}
|
|
|
|
export function useTableIndexAdvisor() {
|
|
return useContext(TableIndexAdvisorContext)
|
|
}
|
|
|
|
export function useColumnHasIndexSuggestion(columnName: string): boolean {
|
|
const { columnsWithSuggestions } = useTableIndexAdvisor()
|
|
return columnsWithSuggestions.includes(columnName)
|
|
}
|