Add comboboxes to the index side panel dropdowns (#25821)

* Add comboboxes to the index side panel dropdowns

* Add loading state for create index panel select a table field

* Add placehholder for columns field in create index side panel

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
This commit is contained in:
Terry SuttonandJoshen Lim authored and GitHub committed 2024-05-07 15:15:06 +08:00
1 parent c7678d1d27
commit 02c0d75dfb
2 files changed
+140 -44

No files matched your search

@@ -2,7 +2,6 @@ import Link from 'next/link'
import { useEffect, useMemo, useState } from 'react'
import toast from 'react-hot-toast'
import { SelectValue } from '@ui/components/shadcn/ui/select'
import { useProjectContext } from 'components/layouts/ProjectLayout/ProjectContext'
import { CodeEditor } from 'components/ui/CodeEditor'
import ShimmeringLoader from 'components/ui/ShimmeringLoader'
@@ -11,9 +10,19 @@ import { useSchemasQuery } from 'data/database/schemas-query'
import { useTableColumnsQuery } from 'data/database/table-columns-query'
import { useEntityTypesQuery } from 'data/entity-types/entity-types-infinite-query'
import { useExecuteSqlMutation } from 'data/sql/execute-sql-mutation'
import { Check, ChevronsUpDown } from 'lucide-react'
import {
Button,
Input,
CommandEmpty_Shadcn_,
CommandGroup_Shadcn_,
CommandInput_Shadcn_,
CommandItem_Shadcn_,
CommandList_Shadcn_,
Command_Shadcn_,
PopoverContent_Shadcn_,
PopoverTrigger_Shadcn_,
Popover_Shadcn_,
ScrollArea,
SelectContent_Shadcn_,
SelectItem_Shadcn_,
SelectSeparator_Shadcn_,
@@ -21,8 +30,10 @@ import {
SelectValue_Shadcn_,
Select_Shadcn_,
SidePanel,
cn,
} from 'ui'
import MultiSelect, { MultiSelectOption } from 'ui-patterns/MultiSelect'
import { MultiSelectOption } from 'ui-patterns/MultiSelect'
import { MultiSelectV2 } from 'ui-patterns/MultiSelect/MultiSelectV2'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { INDEX_TYPES } from './Indexes.constants'
@@ -37,6 +48,8 @@ const CreateIndexSidePanel = ({ visible, onClose }: CreateIndexSidePanelProps) =
const [selectedEntity, setSelectedEntity] = useState<string | undefined>(undefined)
const [selectedColumns, setSelectedColumns] = useState<string[]>([])
const [selectedIndexType, setSelectedIndexType] = useState<string>(INDEX_TYPES[0].value)
const [schemaDropdownOpen, setSchemaDropdownOpen] = useState(false)
const [tableDropdownOpen, setTableDropdownOpen] = useState(false)
const { refetch: refetchIndexes } = useIndexesQuery({
schema: selectedSchema,
@@ -47,7 +60,7 @@ const CreateIndexSidePanel = ({ visible, onClose }: CreateIndexSidePanelProps) =
projectRef: project?.ref,
connectionString: project?.connectionString,
})
const { data: entities } = useEntityTypesQuery({
const { data: entities, isLoading } = useEntityTypesQuery({
schema: selectedSchema,
sort: 'alphabetical',
search: undefined,
@@ -136,22 +149,62 @@ CREATE INDEX ON "${selectedSchema}"."${selectedEntity}" USING ${selectedIndexTyp
<div className="py-6 space-y-6">
<SidePanel.Content className="space-y-6">
<FormItemLayout label="Select a schema" name="select-schema" isReactForm={false}>
<Select_Shadcn_
value={selectedSchema}
onValueChange={setSelectedSchema}
name="select-schema"
<Popover_Shadcn_
modal={false}
open={schemaDropdownOpen}
onOpenChange={setSchemaDropdownOpen}
>
<SelectTrigger_Shadcn_ size="small">
<SelectValue_Shadcn_>{selectedSchema}</SelectValue_Shadcn_>
</SelectTrigger_Shadcn_>
<SelectContent_Shadcn_>
{(schemas ?? []).map((schema) => (
<SelectItem_Shadcn_ key={schema.name} value={schema.name}>
{schema.name}
</SelectItem_Shadcn_>
))}
</SelectContent_Shadcn_>
</Select_Shadcn_>
<PopoverTrigger_Shadcn_ asChild>
<Button
type="default"
size={'medium'}
className={`w-full [&>span]:w-full text-left`}
iconRight={
<ChevronsUpDown className="text-foreground-muted" strokeWidth={2} size={14} />
}
>
{selectedSchema !== undefined && selectedSchema !== ''
? selectedSchema
: 'Choose a schema'}
</Button>
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_
className="p-0"
side="bottom"
align="start"
sameWidthAsTrigger
>
<Command_Shadcn_>
<CommandInput_Shadcn_ placeholder="Find schema..." />
<CommandList_Shadcn_>
<CommandEmpty_Shadcn_>No schemas found</CommandEmpty_Shadcn_>
<CommandGroup_Shadcn_>
<ScrollArea className={(schemas || []).length > 7 ? 'h-[210px]' : ''}>
{(schemas ?? []).map((schema) => (
<CommandItem_Shadcn_
key={schema.name}
className="cursor-pointer flex items-center justify-between space-x-2 w-full"
onSelect={() => {
setSelectedSchema(schema.name)
setSchemaDropdownOpen(false)
}}
onClick={() => {
setSelectedSchema(schema.name)
setSchemaDropdownOpen(false)
}}
>
<span>{schema.name}</span>
{selectedEntity === schema.name && (
<Check className="text-brand" strokeWidth={2} size={16} />
)}
</CommandItem_Shadcn_>
))}
</ScrollArea>
</CommandGroup_Shadcn_>
</CommandList_Shadcn_>
</Command_Shadcn_>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
</FormItemLayout>
<FormItemLayout
@@ -159,42 +212,85 @@ CREATE INDEX ON "${selectedSchema}"."${selectedEntity}" USING ${selectedIndexTyp
name="select-table"
description={
isSelectEntityDisabled &&
!isLoading &&
'Create a table in this schema via the Table or SQL editor first'
}
isReactForm={false}
>
<Select_Shadcn_
disabled={isSelectEntityDisabled}
value={selectedEntity}
onValueChange={setSelectedEntity}
name="select-table"
<Popover_Shadcn_
modal={false}
open={tableDropdownOpen}
onOpenChange={setTableDropdownOpen}
>
<SelectTrigger_Shadcn_ size="small">
<SelectValue
placeholder={
isSelectEntityDisabled ? 'No tables available in schema' : 'Choose a table'
}
>
{selectedEntity}
</SelectValue>
</SelectTrigger_Shadcn_>
<SelectContent_Shadcn_>
{(entityTypes ?? []).map((entity) => (
<SelectItem_Shadcn_ key={entity.name} value={entity.name}>
{entity.name}
</SelectItem_Shadcn_>
))}
</SelectContent_Shadcn_>
</Select_Shadcn_>
<PopoverTrigger_Shadcn_ asChild disabled={isSelectEntityDisabled || isLoading}>
{isLoading ? (
<ShimmeringLoader className="h-[38px]" />
) : (
<Button
type="default"
size="medium"
className={cn(
'w-full [&>span]:w-full text-left',
selectedEntity === '' && 'text-foreground-lighter'
)}
iconRight={
<ChevronsUpDown className="text-foreground-muted" strokeWidth={2} size={14} />
}
>
{selectedEntity !== undefined && selectedEntity !== ''
? selectedEntity
: isSelectEntityDisabled
? 'No tables available in schema'
: 'Choose a table'}
</Button>
)}
</PopoverTrigger_Shadcn_>
<PopoverContent_Shadcn_
className="p-0"
side="bottom"
align="start"
sameWidthAsTrigger
>
<Command_Shadcn_>
<CommandInput_Shadcn_ placeholder="Find table..." />
<CommandList_Shadcn_>
<CommandEmpty_Shadcn_>No tables found</CommandEmpty_Shadcn_>
<CommandGroup_Shadcn_>
<ScrollArea className={(entityTypes || []).length > 7 ? 'h-[210px]' : ''}>
{(entityTypes ?? []).map((entity) => (
<CommandItem_Shadcn_
key={entity.name}
className="cursor-pointer flex items-center justify-between space-x-2 w-full"
onSelect={() => {
setSelectedEntity(entity.name)
setTableDropdownOpen(false)
}}
onClick={() => {
setSelectedEntity(entity.name)
setTableDropdownOpen(false)
}}
>
<span>{entity.name}</span>
{selectedEntity === entity.name && (
<Check className="text-brand" strokeWidth={2} size={16} />
)}
</CommandItem_Shadcn_>
))}
</ScrollArea>
</CommandGroup_Shadcn_>
</CommandList_Shadcn_>
</Command_Shadcn_>
</PopoverContent_Shadcn_>
</Popover_Shadcn_>
</FormItemLayout>
{selectedEntity && (
<FormItemLayout label="Select up to 32 columns" isReactForm={false}>
{isLoadingTableColumns && <ShimmeringLoader className="py-4" />}
{isSuccessTableColumns && (
<MultiSelect
<MultiSelectV2
options={columnOptions}
placeholder=""
placeholder="Choose which columns to create an index on"
searchPlaceholder="Search for a column"
value={selectedColumns}
onChange={setSelectedColumns}
@@ -116,7 +116,7 @@ export const MultiSelectV2 = ({
<CommandList_Shadcn_>
<CommandEmpty_Shadcn_>No options found</CommandEmpty_Shadcn_>
<CommandGroup_Shadcn_>
<ScrollArea className={cn(formattedOptions.length > 5 ? 'h-[225px]' : '')}>
<ScrollArea className={cn(formattedOptions.length > 7 ? 'h-[210px]' : '')}>
{formattedOptions?.map((option) => {
const active =
selectedOptions &&