import { PermissionAction } from '@supabase/shared-types/out/constants' import { Check, Plus } from 'lucide-react' import { ComponentPropsWithoutRef, forwardRef, useMemo, useState } from 'react' import { Alert, AlertDescription, AlertTitle, Button, ComboboxTrigger, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, Popover, PopoverContent, PopoverTrigger, ScrollArea, Skeleton, } from 'ui' import { RestartProjectDialog } from '@/components/interfaces/ErrorHandling/RestartProjectDialog' import { useSchemasQuery } from '@/data/database/schemas-query' import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions' import { useSchemasFilteredForHighAvailability } from '@/hooks/misc/useHighAvailability' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' type SchemaSelectorProps = Omit, 'onSelect'> & { disabled?: boolean size?: 'tiny' | 'small' showError?: boolean selectedSchemaName?: string placeholderLabel?: string supportSelectAll?: boolean excludedSchemas?: string[] onSelectSchema: (name: string) => void onSelectCreateSchema?: () => void align?: 'start' | 'end' open?: boolean onOpenChange?: (open: boolean) => void } const DEFAULT_EXCLUDED_SCHEMAS: string[] = [] export const SchemaSelector = forwardRef( ( { className, disabled = false, size = 'tiny', showError = true, selectedSchemaName, placeholderLabel = 'Choose a schema...', supportSelectAll = false, excludedSchemas = DEFAULT_EXCLUDED_SCHEMAS, onSelectSchema, onSelectCreateSchema, align = 'start', open: openProp, onOpenChange, ...rest }, ref ) => { const [internalOpen, setInternalOpen] = useState(false) const [isRestartDialogVisible, setIsRestartDialogVisible] = useState(false) const isControlled = openProp !== undefined const open = isControlled ? openProp : internalOpen const setOpen = (next: boolean) => { if (!isControlled) setInternalOpen(next) onOpenChange?.(next) } const { can: canCreateSchemas } = useAsyncCheckPermissions( PermissionAction.TENANT_SQL_ADMIN_WRITE, 'schemas' ) const { data: project } = useSelectedProjectQuery() const { data, isPending: isSchemasLoading, isSuccess: isSchemasSuccess, isError: isSchemasError, error: schemasError, refetch: refetchSchemas, } = useSchemasQuery({ projectRef: project?.ref, connectionString: project?.connectionString, }) const visibleSchemas = useSchemasFilteredForHighAvailability(data) const schemas = useMemo( () => visibleSchemas .filter((schema) => !excludedSchemas.includes(schema.name)) .sort((a, b) => a.name.localeCompare(b.name)), [visibleSchemas, excludedSchemas] ) return (
{isSchemasLoading && ( )} {showError && isSchemasError && ( Failed to load schemas Error: {(schemasError as any)?.message}
setIsRestartDialogVisible(false)} restartType="database" />
)} {isSchemasSuccess && ( {selectedSchemaName ? ( schema {selectedSchemaName === '*' ? 'All schemas' : selectedSchemaName} ) : ( {placeholderLabel} )} No schemas found 7 ? 'h-[210px]' : ''}> {supportSelectAll && ( { onSelectSchema('*') setOpen(false) }} onClick={() => { onSelectSchema('*') setOpen(false) }} > All schemas {selectedSchemaName === '*' && ( )} )} {schemas.map((schema) => ( { onSelectSchema(schema.name) setOpen(false) }} onClick={() => { onSelectSchema(schema.name) setOpen(false) }} > {schema.name} {selectedSchemaName === schema.name && ( )} ))} {onSelectCreateSchema !== undefined && canCreateSchemas && ( <> { onSelectCreateSchema() setOpen(false) }} onClick={() => { onSelectCreateSchema() setOpen(false) }} > Create a new schema )} )}
) } ) SchemaSelector.displayName = 'SchemaSelector'