chore: migrate Input usages to Shadcn component in database screens/components (#45600)

## Screenshots

### Extensions search input
Before:
<img width="955" height="256" alt="image"
src="https://github.com/user-attachments/assets/c69e428a-8ab5-4dce-a45a-5d6a6d30472d"
/>

After:
<img width="965" height="212" alt="image"
src="https://github.com/user-attachments/assets/a08294cc-14ea-4c8d-af24-a207de3dada9"
/>

### Triggers search input
Before:
<img width="961" height="249" alt="image"
src="https://github.com/user-attachments/assets/21df2aeb-cc83-42e2-a35e-23e6451182ad"
/>

After:
<img width="979" height="248" alt="image"
src="https://github.com/user-attachments/assets/f365661d-5075-4041-a4f2-8fd1b7fdeb4b"
/>

### Hooks search input
Before:
<img width="974" height="361" alt="image"
src="https://github.com/user-attachments/assets/baaad7fb-1ede-46a4-8148-3cc05a53c955"
/>

After:
<img width="976" height="363" alt="image"
src="https://github.com/user-attachments/assets/9c3b2467-1e9a-4919-a6df-9e3ff46a30b8"
/>

### Backups - restore to new project dialog
Before:
<img width="544" height="656" alt="image"
src="https://github.com/user-attachments/assets/181018ac-cda6-4a57-bfc3-028ac6a1eeed"
/>

After:
<img width="536" height="643" alt="image"
src="https://github.com/user-attachments/assets/4c177884-4415-4744-b3d1-67fe83065565"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Standardized search inputs across database interfaces by consolidating
into a grouped input pattern for consistent behavior and keyboard focus.

* **Style**
* Improved layout of the database creation dialog’s password field,
including visible reveal control and relocated strength indicator for
clearer form presentation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Ali Waseem <waseema393@gmail.com>
This commit is contained in:
Gildas Garcia
2026-05-05 19:24:58 +02:00
committed by GitHub
parent 153f2619bc
commit aee4c8fdd7
4 changed files with 67 additions and 44 deletions

View File

@@ -14,9 +14,9 @@ import {
Form,
FormControl,
FormField,
Input,
Input_Shadcn_,
} from 'ui'
import { Input } from 'ui-patterns/DataInputs/Input'
import { FormItemLayout } from 'ui-patterns/form/FormItemLayout/FormItemLayout'
import { z } from 'zod'
@@ -149,15 +149,25 @@ export const CreateNewProjectDialog = ({
control={form.control}
name="password"
render={({ field }) => (
<FormItemLayout>
<FormItemLayout
label="Database password"
description={
<PasswordStrengthBar
passwordStrengthScore={passwordStrengthScore as PasswordStrengthScore}
password={field.value}
passwordStrengthMessage={passwordStrengthMessage}
generateStrongPassword={generatePassword}
/>
}
>
<FormControl>
<Input
id="db-password"
label="Database password"
type="password"
placeholder="Type in a strong password"
value={field.value}
copy={field.value?.length > 0}
reveal
onChange={(e) => {
const value = e.target.value
field.onChange(value)
@@ -166,14 +176,6 @@ export const CreateNewProjectDialog = ({
setPasswordStrengthMessage('')
} else checkPasswordStrength(value)
}}
descriptionText={
<PasswordStrengthBar
passwordStrengthScore={passwordStrengthScore as PasswordStrengthScore}
password={field.value}
passwordStrengthMessage={passwordStrengthMessage}
generateStrongPassword={generatePassword}
/>
}
/>
</FormControl>
</FormItemLayout>

View File

@@ -5,7 +5,9 @@ import { AlertCircle, Search } from 'lucide-react'
import { useEffect, useRef, useState } from 'react'
import {
Card,
Input,
InputGroup,
InputGroupAddon,
InputGroupInput,
ShadowScrollArea,
Table,
TableBody,
@@ -79,16 +81,19 @@ export const Extensions = () => {
return (
<>
<div className="mb-4">
<Input
inputRef={searchInputRef}
size="tiny"
placeholder="Search for an extension"
value={filterString}
onChange={(e) => setFilterString(e.target.value)}
onKeyDown={onSearchInputEscape(filterString, setFilterString)}
className="w-52"
icon={<Search />}
/>
<InputGroup className="w-52">
<InputGroupInput
ref={searchInputRef}
size="tiny"
placeholder="Search for an extension"
value={filterString}
onChange={(e) => setFilterString(e.target.value)}
onKeyDown={onSearchInputEscape(filterString, setFilterString)}
/>
<InputGroupAddon>
<Search />
</InputGroupAddon>
</InputGroup>
</div>
{isPermissionsLoaded && !canUpdateExtensions && (
@@ -112,8 +117,8 @@ export const Extensions = () => {
<TableHead key="description">Description</TableHead>
<TableHead key="used-by">Used by</TableHead>
<TableHead key="links">Links</TableHead>
{/*
[Joshen] All these classes are just to make the last column sticky
{/*
[Joshen] All these classes are just to make the last column sticky
I reckon we can pull these out into the Table component where we can declare
sticky columns via props, but we can do that if we start to have more tables
in the dashboard with sticky columns

View File

@@ -3,7 +3,7 @@ import { includes, map as lodashMap, uniqBy } from 'lodash'
import { Search } from 'lucide-react'
import { parseAsBoolean, useQueryState } from 'nuqs'
import { useState } from 'react'
import { Input } from 'ui'
import { InputGroup, InputGroupAddon, InputGroupInput } from 'ui'
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
import { HooksListEmpty } from './HooksListEmpty'
@@ -47,14 +47,17 @@ export const HooksList = () => {
return (
<div className="w-full space-y-4">
<div className="flex items-center justify-between">
<Input
placeholder="Search for a webhook"
size="tiny"
icon={<Search />}
value={filterString}
className="w-52"
onChange={(e) => setFilterString(e.target.value)}
/>
<InputGroup className="w-52">
<InputGroupInput
size="tiny"
placeholder="Search for a webhook"
value={filterString}
onChange={(e) => setFilterString(e.target.value)}
/>
<InputGroupAddon>
<Search />
</InputGroupAddon>
</InputGroup>
<div className="flex items-center gap-x-2">
<DocsButton href={`${DOCS_URL}/guides/database/webhooks`} />
<ButtonTooltip

View File

@@ -4,7 +4,17 @@ import { DatabaseZap, Search } from 'lucide-react'
import { parseAsBoolean, parseAsJson, parseAsString, useQueryState } from 'nuqs'
import { useEffect, useRef, useState } from 'react'
import { toast } from 'sonner'
import { Card, Input, Table, TableBody, TableHead, TableHeader, TableRow } from 'ui'
import {
Card,
InputGroup,
InputGroupAddon,
InputGroupInput,
Table,
TableBody,
TableHead,
TableHeader,
TableRow,
} from 'ui'
import { EmptyStatePresentational } from 'ui-patterns'
import { GenericSkeletonLoader } from 'ui-patterns/ShimmeringLoader'
@@ -243,16 +253,19 @@ execute function function_name();`
onOpenChange={setSchemaSelectorOpen}
/>
</Shortcut>
<Input
inputRef={searchInputRef}
placeholder="Search for a trigger"
size="tiny"
icon={<Search />}
value={filterString}
className="w-full lg:w-52"
onChange={(e) => setFilterString(e.target.value)}
onKeyDown={onSearchInputEscape(filterString, setFilterString)}
/>
<InputGroup className="w-full lg:w-52">
<InputGroupInput
ref={searchInputRef}
size="tiny"
placeholder="Search for a trigger"
value={filterString}
onChange={(e) => setFilterString(e.target.value)}
onKeyDown={onSearchInputEscape(filterString, setFilterString)}
/>
<InputGroupAddon>
<Search />
</InputGroupAddon>
</InputGroup>
<ReportsSelectFilter
label="Table"
options={tables.map((type) => ({ label: type, value: type }))}