Files
supabase/apps/studio/components/ui/DatabaseSelector.tsx
T
Joshen LimandAlaister Young da792ba0ba Chore/show rr UI only if project is enabled (#19642)
* Only show RR UI if project is enabled

* Only show RR UI if project has read replicas enabled, shift DatabaseSelector state to valtio, add Database Selector to API URl

* Update usage of Project interface from types to Project from project-details-query

* Fix ts errors

* Another one

* Another one...

* God one more

* Fingers crossed

* jesus

* Add deprecate mark on ProjectBase

* Resolve conflicts

* Rename ProjectState from valtio to DatabaseSelectorState

* Rename file

* fix imports

* tiny code changes

* Fixes

---------

Co-authored-by: Alaister Young <a@alaisteryoung.com>
2023-12-20 16:49:53 +07:00

137 lines
5.0 KiB
TypeScript

import Link from 'next/link'
import { useRouter } from 'next/router'
import { useState } from 'react'
import { useParams } from 'common'
import { useReadReplicasQuery } from 'data/read-replicas/replicas-query'
import { formatDatabaseID, formatDatabaseRegion } from 'data/read-replicas/replicas.utils'
import { useDatabaseSelectorStateSnapshot } from 'state/database-selector'
import {
Button,
CommandGroup_Shadcn_,
CommandItem_Shadcn_,
CommandList_Shadcn_,
Command_Shadcn_,
IconCheck,
IconChevronDown,
IconPlus,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
Popover_Shadcn_,
ScrollArea,
cn,
} from 'ui'
interface DatabaseSelectorProps {
variant?: 'regular' | 'connected-on-right' | 'connected-on-left' | 'connected-on-both'
}
const DatabaseSelector = ({ variant = 'regular' }: DatabaseSelectorProps) => {
const router = useRouter()
const { ref: projectRef } = useParams()
const [open, setOpen] = useState(false)
const state = useDatabaseSelectorStateSnapshot()
const selectedDatabaseId = state.selectedDatabaseId
const { data } = useReadReplicasQuery({ projectRef })
const databases = data ?? []
const selectedDatabase = databases.find((db) => db.identifier === selectedDatabaseId)
const selectedDatabaseRegion = formatDatabaseRegion(selectedDatabase?.region ?? '')
const formattedDatabaseId = formatDatabaseID(selectedDatabaseId ?? '')
return (
<Popover_Shadcn_ open={open} onOpenChange={setOpen} modal={false}>
<PopoverTrigger_Shadcn_ asChild>
<div className="flex items-center space-x-2 cursor-pointer">
<Button
type="default"
className={cn(
'pr-2',
variant === 'connected-on-right' && 'rounded-r-none',
variant === 'connected-on-left' && 'rounded-l-none border-l-0',
variant === 'connected-on-both' && 'rounded-none border-x-0'
)}
iconRight={
<IconChevronDown className="text-foreground-light" strokeWidth={2} size={12} />
}
>
Source:{' '}
<span className="capitalize">
{selectedDatabase?.identifier === projectRef ? 'Primary database' : 'Read replica'}
</span>{' '}
{selectedDatabase?.identifier !== projectRef && (
<span>
({selectedDatabaseRegion} - {formattedDatabaseId})
</span>
)}
</Button>
</div>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_ className="p-0 w-64" side="bottom" align="end">
<Command_Shadcn_>
<CommandList_Shadcn_>
<CommandGroup_Shadcn_>
<ScrollArea className={(databases || []).length > 7 ? 'h-[210px]' : ''}>
{databases?.map((database) => {
const region = formatDatabaseRegion(database.region)
const id = formatDatabaseID(database.identifier)
return (
<CommandItem_Shadcn_
key={database.identifier}
value={database.identifier}
className="cursor-pointer w-full"
onSelect={() => {
state.setSelectedDatabaseId(database.identifier)
setOpen(false)
}}
onClick={() => {
state.setSelectedDatabaseId(database.identifier)
setOpen(false)
}}
>
<div className="w-full flex items-center justify-between">
<p>
{database.identifier === projectRef
? 'Primary database'
: `Read replica (${region} - ${id})`}
</p>
{database.identifier === selectedDatabaseId && <IconCheck />}
</div>
</CommandItem_Shadcn_>
)
})}
</ScrollArea>
</CommandGroup_Shadcn_>
<CommandGroup_Shadcn_ className="border-t">
<CommandItem_Shadcn_
className="cursor-pointer w-full"
onSelect={() => {
setOpen(false)
router.push(`/project/${projectRef}/settings/infrastructure`)
}}
onClick={() => setOpen(false)}
>
<Link
href={`/project/${projectRef}/settings/infrastructure`}
onClick={() => {
setOpen(false)
}}
className="w-full flex items-center gap-2"
>
<IconPlus size={14} strokeWidth={1.5} />
<p>Create a new read replica</p>
</Link>
</CommandItem_Shadcn_>
</CommandGroup_Shadcn_>
</CommandList_Shadcn_>
</Command_Shadcn_>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
)
}
export default DatabaseSelector