import { Search } from 'lucide-react' import { parseAsString, useQueryState } from 'nuqs' import { buttonVariants, cn, Tabs_Shadcn_, TabsList_Shadcn_, TabsTrigger_Shadcn_ } from 'ui' import { Admonition } from 'ui-patterns/admonition' import { Input } from 'ui-patterns/DataInputs/Input' import { IntegrationCard, IntegrationLoadingCard } from './IntegrationCard' import { useAvailableIntegrations } from './useAvailableIntegrations' import { useInstalledIntegrations } from './useInstalledIntegrations' import AlertError from '@/components/ui/AlertError' import { NoSearchResults } from '@/components/ui/NoSearchResults' import { useIsFeatureEnabled } from '@/hooks/misc/useIsFeatureEnabled' type IntegrationCategory = 'all' | 'wrapper' | 'postgres_extensions' | 'custom' const CATEGORIES = [ { key: 'all', label: 'All Integrations' }, { key: 'wrapper', label: 'Wrappers' }, { key: 'postgres_extension', label: 'Postgres Modules' }, ] as const export const AvailableIntegrations = () => { const { integrationsWrappers } = useIsFeatureEnabled(['integrations:wrappers']) const [selectedCategory, setSelectedCategory] = useQueryState( 'category', parseAsString.withDefault('all').withOptions({ clearOnDefault: true }) ) const [search, setSearch] = useQueryState( 'search', parseAsString.withDefault('').withOptions({ clearOnDefault: true }) ) const { data: allIntegrations = [] } = useAvailableIntegrations() const { installedIntegrations, error, isError, isLoading, isSuccess } = useInstalledIntegrations() const installedIds = installedIntegrations.map((i) => i.id) // available integrations for install const availableIntegrations = integrationsWrappers ? allIntegrations : allIntegrations.filter((x) => !x.id.endsWith('_wrapper')) const integrationsByCategory = selectedCategory === 'all' ? availableIntegrations : availableIntegrations.filter((i) => i.type === selectedCategory) const filteredIntegrations = ( search.length > 0 ? integrationsByCategory.filter((i) => i.name.toLowerCase().includes(search.toLowerCase())) : integrationsByCategory ).sort((a, b) => a.name.localeCompare(b.name)) return ( <> setSelectedCategory(value as IntegrationCategory)} > {CATEGORIES.map((category) => ( setSelectedCategory(category.key as IntegrationCategory)} className={cn( buttonVariants({ size: 'tiny', type: selectedCategory === category.key ? 'default' : 'outline', }), selectedCategory === category.key ? 'text-foreground' : 'text-foreground-lighter', 'rounded-full! px-3' )} > {category.label} ))} { setSearch(e.target.value) setSelectedCategory('all') }} containerClassName="group w-40 ml-5" icon={ } iconContainerClassName="p-0" className="pl-7 rounded-none border-0! border-transparent bg-transparent shadow-none! ring-0! ring-offset-0!" placeholder="Search..." />
{isLoading && Array.from({ length: 3 }).map((_, idx) => ( ))} {isError && ( )} {isSuccess && filteredIntegrations.map((i) => ( ))} {isSuccess && search.length > 0 && filteredIntegrations.length === 0 && ( setSearch('')} /> )} {isSuccess && selectedCategory !== 'all' && search.length === 0 && filteredIntegrations.length === 0 && ( )}
) }