Home / Function/ ProjectSelector() — supabase Function Reference

ProjectSelector() — supabase Function Reference

Architecture documentation for the ProjectSelector() function in McpConfigPanel.tsx from the supabase codebase.

Entity Profile

Dependency Diagram

graph TD
  8c9f4578_cfa6_e337_1047_0b169262ad94["ProjectSelector()"]
  23b7acbe_3635_77a2_1239_87ad1661ea8e["useDebounce()"]
  8c9f4578_cfa6_e337_1047_0b169262ad94 -->|calls| 23b7acbe_3635_77a2_1239_87ad1661ea8e
  49800345_99af_55a9_d6fd_a34b97143772["useIntersectionObserver()"]
  8c9f4578_cfa6_e337_1047_0b169262ad94 -->|calls| 49800345_99af_55a9_d6fd_a34b97143772
  b510335d_4ef5_173b_d8f3_49e057a79d53["useProjectsInfiniteQuery()"]
  8c9f4578_cfa6_e337_1047_0b169262ad94 -->|calls| b510335d_4ef5_173b_d8f3_49e057a79d53
  style 8c9f4578_cfa6_e337_1047_0b169262ad94 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

apps/docs/features/ui/McpConfigPanel.tsx lines 41–194

function ProjectSelector({
  className,
  selectedProject,
  onProjectSelect,
}: {
  className?: string
  selectedProject?: { ref: string; name: string } | null
  onProjectSelect?: (project: { ref: string; name: string } | null) => void
}) {
  const [open, setOpen] = useState(false)
  const [search, setSearch] = useState('')
  const debouncedSearch = useDebounce(search, 500)

  const scrollRootRef = useRef<HTMLDivElement | null>(null)
  const [sentinelRef, entry] = useIntersectionObserver({
    root: scrollRootRef.current,
    threshold: 0,
    rootMargin: '0px',
  })

  const isUserLoading = useIsUserLoading()
  const isLoggedIn = useIsLoggedIn()

  const {
    data: projectsData,
    isLoading,
    isError,
    isFetching,
    isFetchingNextPage,
    hasNextPage,
    fetchNextPage,
  } = useProjectsInfiniteQuery(
    { search: search.length === 0 ? search : debouncedSearch },
    { enabled: isLoggedIn }
  )
  const projects =
    useMemo(() => projectsData?.pages.flatMap((page) => page.projects), [projectsData?.pages]) || []

  useEffect(() => {
    if (
      !isLoading &&
      !isFetching &&
      !isFetchingNextPage &&
      hasNextPage &&
      entry?.isIntersecting &&
      !!fetchNextPage
    ) {
      fetchNextPage()
    }
  }, [isLoading, isFetching, isFetchingNextPage, hasNextPage, entry?.isIntersecting, fetchNextPage])

  return (
    <Popover_Shadcn_
      modal={false}
      open={open}
      onOpenChange={(open) => {
        setOpen(open)
        if (!open) setSearch('')
      }}
    >
      <div className={cn('flex', className)}>
        <span className="flex items-center text-foreground-lighter px-3 rounded-lg rounded-r-none text-xs border border-button border-r-0">
          Project
        </span>

        {!isUserLoading && !isLoggedIn ? (
          <Button size="small" type="default" className="gap-0 rounded-l-none" asChild>
            <Link href="https://supabase.com/dashboard" rel="noreferrer noopener" target="_blank">
              <div className="flex items-center gap-2">Log in to choose a project</div>
            </Link>
          </Button>
        ) : (
          <PopoverTrigger_Shadcn_ asChild disabled={isUserLoading || isLoading || isError}>
            <Button
              size="small"
              type="default"
              className="gap-0 rounded-l-none"
              iconRight={
                <ChevronDown
                  strokeWidth={1.5}
                  className={cn('transition-transform duration-200', open && 'rotate-180')}
                />
              }
            >
              <div className="flex items-center gap-2">
                {selectedProject?.name ??
                  (isUserLoading || isLoading
                    ? 'Loading projects...'
                    : isError
                      ? 'Error fetching projects'
                      : 'Select a project')}
              </div>
            </Button>
          </PopoverTrigger_Shadcn_>
        )}
      </div>
      <PopoverContent_Shadcn_ className="mt-0 p-0 w-56" side="bottom" align="start">
        <Command_Shadcn_ shouldFilter={false}>
          <CommandInput_Shadcn_
            placeholder="Search ..."
            className="h-8"
            showResetIcon
            value={search}
            onValueChange={setSearch}
            handleReset={() => setSearch('')}
          />
          <CommandList_Shadcn_>
            <CommandGroup_Shadcn_>
              {isLoading ? (
                <div className="px-2 py-1 flex flex-col gap-2">
                  <ShimmeringLoader className="w-full" />
                  <ShimmeringLoader className="w-4/5" />
                </div>
              ) : (
                <>
                  {search.length > 0 && projects.length === 0 && (
                    <p className="text-xs text-center text-foreground-lighter py-3">
                      No projects found based on your search
                    </p>
                  )}
                  <ScrollArea className={projects.length > 7 ? 'h-[210px]' : ''}>
                    {projects?.map((project) => (
                      <CommandItem_Shadcn_
                        key={project.ref}
                        value={project.ref}
                        onSelect={() => {
                          onProjectSelect?.(project.ref === selectedProject?.ref ? null : project)
                          setOpen(false)
                        }}
                        className="flex gap-2 items-center"
                      >
                        {project.name}
                        <Check
                          aria-label={project.ref === selectedProject?.ref ? 'selected' : undefined}
                          size={15}
                          className={cn(
                            'ml-auto',
                            project.ref === selectedProject?.ref ? 'opacity-100' : 'opacity-0'
                          )}
                        />
                      </CommandItem_Shadcn_>
                    ))}
                    <div ref={sentinelRef} className="h-1 -mt-1" />
                    {hasNextPage && <ShimmeringLoader className="px-2 py-3" />}
                  </ScrollArea>
                </>
              )}
            </CommandGroup_Shadcn_>
          </CommandList_Shadcn_>
        </Command_Shadcn_>
      </PopoverContent_Shadcn_>
    </Popover_Shadcn_>
  )
}

Subdomains

Frequently Asked Questions

What does ProjectSelector() do?
ProjectSelector() is a function in the supabase codebase.
What does ProjectSelector() call?
ProjectSelector() calls 3 function(s): useDebounce, useIntersectionObserver, useProjectsInfiniteQuery.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free