import { Check, ChevronsUpDown } from 'lucide-react' import { useMemo, useState } from 'react' import { Button, cn, Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Popover, PopoverContent, PopoverTrigger, ScrollArea, } from 'ui' import { ShimmeringLoader } from 'ui-patterns/ShimmeringLoader' import { useSchemasQuery } from '@/data/database/schemas-query' import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject' import { INTERNAL_SCHEMAS } from '@/hooks/useProtectedSchemas' import { pluralize } from '@/lib/helpers' /** * [Joshen] This would only affect graphql_public and pgmq_public, given that they're intended * to be public, we can let users expose them via the API, but not let them adjust the schema via the dashboard * */ export const internalSchemasCannotExpose = new Set( INTERNAL_SCHEMAS.filter((x) => !x.endsWith('_public')) ) interface ExposedSchemaSelectorProps { disabled?: boolean selectedSchemas: string[] onToggleSchema: (schema: string) => void } export const ExposedSchemaSelector = ({ disabled = false, selectedSchemas, onToggleSchema, }: ExposedSchemaSelectorProps) => { const [open, setOpen] = useState(false) const { data: project } = useSelectedProjectQuery() const { data: allSchemas, isPending, isError, isSuccess, } = useSchemasQuery({ projectRef: project?.ref, connectionString: project?.connectionString, }) const schemas = useMemo( () => (allSchemas ?? []) .filter((s) => !internalSchemasCannotExpose.has(s.name)) .sort((a, b) => a.name.localeCompare(b.name)), [allSchemas] ) const missingExposedSchema = useMemo( () => selectedSchemas.filter((schema) => !schemas.some((s) => s.name === schema)), [schemas, selectedSchemas] ) const selectedSet = useMemo(() => new Set(selectedSchemas), [selectedSchemas]) const selectedCount = schemas.filter((s) => selectedSet.has(s.name)).length return ( {isPending ? ( <>
) : isError ? (

Failed to retrieve schemas

) : ( <>

No schemas found

7 ? 'h-[210px]' : ''}> {missingExposedSchema.map((schema) => ( { onToggleSchema(schema) }} >
{schema}
{internalSchemasCannotExpose.has(schema) ? ( This schema is protected and should not be exposed ) : ( This schema does not exist and can be safely removed )}
))} {schemas.map((schema) => { const isExposed = selectedSet.has(schema.name) return ( { onToggleSchema(schema.name) }} >
{isExposed && } {schema.name}
) })}
)}
) }