Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
WalkthroughUsersSearch was rewritten to use internal query-state and telemetry. New props (telemetryProps, telemetryGroups, onSelectFilterColumn) replace external setters. Search input is stored raw and normalized only on submit; submissions emit an Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UsersV2
participant UsersSearch
participant TelemetryAPI
User->>UsersSearch: Type search input (onChange stores raw)
User->>UsersSearch: Submit search (Enter / click)
UsersSearch->>UsersSearch: normalize (trim, toLowerCase) & validate by column
UsersSearch->>UsersV2: onSelectFilterColumn (if column changed)
UsersSearch->>TelemetryAPI: useSendEventMutation(auth_users_search_submitted { trigger, keywords, telemetryGroups })
TelemetryAPI-->>UsersSearch: ack
UsersSearch-->>User: show results / update UI
Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🎭 Playwright Test ResultsDetails
Flaky testsFeatures › index-advisor.spec.ts › Index Advisor › Enable Index Advisor › should enable Index Advisor via Database > Extensions page Skipped testsFeatures › sql-editor.spec.ts › SQL Editor › snippet favourite works as expected |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/studio/components/interfaces/Auth/Users/UsersSearch.tsx (1)
122-122: LGTM! The change correctly preserves spaces in search input.Allowing spaces in the search input is appropriate for name searches. The implementation correctly maintains spaces during typing while still normalizing case.
However, there's a minor inconsistency with line 125: this line uses
toLowerCase()while line 125 usestoLocaleLowerCase(). For consistency and locale-aware behavior, consider using the same method throughout.♻️ Suggested consistency improvement
- onChange={(e) => setSearch(e.target.value.toLowerCase())} + onChange={(e) => setSearch(e.target.value.toLocaleLowerCase())}Note: Since
searchis now lowercased on input, thetoLocaleLowerCase()call on line 125 becomes redundant, but keeping it doesn't cause issues and serves as defensive coding.
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
apps/studio/components/interfaces/Auth/Users/UsersSearch.tsx
🧰 Additional context used
📓 Path-based instructions (2)
apps/studio/**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursor/rules/studio-best-practices.mdc)
apps/studio/**/*.{ts,tsx}: Assign complex conditions to descriptive variables instead of using multiple conditions in a single expression
Use consistent naming conventions for boolean variables:isprefix for state/identity,hasprefix for possession,canprefix for capability/permission,shouldprefix for conditional behavior
Derive boolean state from existing state instead of storing it separately
Use early returns for guard clauses instead of deeply nested conditionals
Extract complex logic into custom hooks when logic becomes reusable or complex
Return objects from custom hooks instead of arrays for better extensibility and clearer API
Use discriminated unions for complex state management instead of multiple independent state fields
Avoid type casting (e.g.,as any,as Type); instead validate values at runtime using zod schemas
Files:
apps/studio/components/interfaces/Auth/Users/UsersSearch.tsx
apps/studio/**/*.tsx
📄 CodeRabbit inference engine (.cursor/rules/studio-best-practices.mdc)
apps/studio/**/*.tsx: Components should ideally be under 200-300 lines; break down large components with multiple distinct UI sections, complex conditional rendering, or multiple unrelated useState hooks
Extract repeated JSX patterns into reusable components instead of copying similar JSX blocks
Use consistent loading/error/success pattern: handle loading state first with early returns, then error state, then empty state, then render success state
Keep state as local as possible and only lift up when needed
Group related state using objects or reducers instead of multiple useState calls, preferring react-hook-form for form state management
Name event handlers consistently: useonprefix for prop callbacks andhandleprefix for internal handlers
Avoid inline arrow functions for expensive operations; use useCallback to maintain stable function references
Use appropriate conditional rendering patterns: && for simple show/hide, ternary for binary choice, early returns or extracted components for multiple conditions
Avoid nested ternaries in JSX; use separate conditions or early returns instead
Use useMemo for expensive computations when the computation is genuinely expensive and the value is passed to memoized children
Define prop interfaces explicitly for React components with proper typing of props and callback handlers
Files:
apps/studio/components/interfaces/Auth/Users/UsersSearch.tsx
🧠 Learnings (3)
📚 Learning: 2025-12-11T17:04:40.037Z
Learnt from: CR
Repo: supabase/supabase PR: 0
File: .cursor/rules/studio-ui.mdc:0-0
Timestamp: 2025-12-11T17:04:40.037Z
Learning: Applies to apps/studio/components/**/*.{ts,tsx} : Use Input_Shadcn_ with type='password' for password input form fields
Applied to files:
apps/studio/components/interfaces/Auth/Users/UsersSearch.tsx
📚 Learning: 2025-12-12T05:20:17.409Z
Learnt from: joshenlim
Repo: supabase/supabase PR: 41258
File: apps/studio/pages/project/[ref]/storage/vectors/buckets/[bucketId].tsx:9-9
Timestamp: 2025-12-12T05:20:17.409Z
Learning: In apps/studio/**/*.{ts,tsx}, use named imports for DefaultLayout: import { DefaultLayout } from 'components/layouts/DefaultLayout' instead of default import. This is the new practice being adopted across the studio app.
Applied to files:
apps/studio/components/interfaces/Auth/Users/UsersSearch.tsx
📚 Learning: 2026-01-02T05:58:55.226Z
Learnt from: meGauravJain
Repo: supabase/supabase PR: 41658
File: apps/studio/components/interfaces/Connect/content/prisma/content.tsx:70-85
Timestamp: 2026-01-02T05:58:55.226Z
Learning: In Prisma configuration or related connection setup code, prefer the environment variable name DIRECT_URL for direct/non-pooled database connections instead of DATABASE_URL_UNPOOLED, per Prisma documentation. Update code that reads database connection strings to use DIRECT_URL where applicable, and document why this is preferred (explicit, documented behavior). Ensure your environment provides DIRECT_URL when using direct connections and fallback handling if needed.
Applied to files:
apps/studio/components/interfaces/Auth/Users/UsersSearch.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
- GitHub Check: test (1)
- GitHub Check: test
- GitHub Check: typecheck
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@apps/studio/components/interfaces/Auth/Users/UsersSearch.tsx`:
- Around line 52-75: UsersSearch initializes local state variable search from
filterKeywords but never updates it on query-state changes; add a useEffect
inside UsersSearch that watches filterKeywords and calls
setSearch(filterKeywords) (only when filterKeywords !== search) so the input
stays in sync with URL query changes (ensure the effect lists filterKeywords and
search or uses a safe comparison to avoid an infinite loop).
| export const UsersSearch = ({ | ||
| search, | ||
| searchInvalid, | ||
| specificFilterColumn, | ||
| setSearch, | ||
| setFilterKeywords, | ||
| setSpecificFilterColumn, | ||
| improvedSearchEnabled = false, | ||
| telemetryProps, | ||
| telemetryGroups, | ||
| onSelectFilterColumn, | ||
| }: UsersSearchProps) => { | ||
| const [_, setSelectedId] = useQueryState( | ||
| 'show', | ||
| parseAsString.withOptions({ history: 'push', clearOnDefault: true }) | ||
| ) | ||
| const [filterKeywords, setFilterKeywords] = useQueryState('keywords', { defaultValue: '' }) | ||
| const [specificFilterColumn] = useQueryState<SpecificFilterColumn>( | ||
| 'filter', | ||
| parseAsStringEnum<SpecificFilterColumn>([ | ||
| 'id', | ||
| 'email', | ||
| 'phone', | ||
| 'name', | ||
| 'freeform', | ||
| ]).withDefault('email') | ||
| ) | ||
|
|
||
| const [search, setSearch] = useState(filterKeywords) | ||
| const { mutate: sendEvent } = useSendEventMutation() |
There was a problem hiding this comment.
Sync local search when the query param changes.
search is initialized from filterKeywords but never updated if the query-state changes (e.g., back/forward navigation or external updates), which can leave the input stale.
🔧 Suggested fix
-import { useState } from 'react'
+import { useEffect, useState } from 'react'
...
const [search, setSearch] = useState(filterKeywords)
+
+useEffect(() => {
+ setSearch(filterKeywords)
+}, [filterKeywords])📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| export const UsersSearch = ({ | |
| search, | |
| searchInvalid, | |
| specificFilterColumn, | |
| setSearch, | |
| setFilterKeywords, | |
| setSpecificFilterColumn, | |
| improvedSearchEnabled = false, | |
| telemetryProps, | |
| telemetryGroups, | |
| onSelectFilterColumn, | |
| }: UsersSearchProps) => { | |
| const [_, setSelectedId] = useQueryState( | |
| 'show', | |
| parseAsString.withOptions({ history: 'push', clearOnDefault: true }) | |
| ) | |
| const [filterKeywords, setFilterKeywords] = useQueryState('keywords', { defaultValue: '' }) | |
| const [specificFilterColumn] = useQueryState<SpecificFilterColumn>( | |
| 'filter', | |
| parseAsStringEnum<SpecificFilterColumn>([ | |
| 'id', | |
| 'email', | |
| 'phone', | |
| 'name', | |
| 'freeform', | |
| ]).withDefault('email') | |
| ) | |
| const [search, setSearch] = useState(filterKeywords) | |
| const { mutate: sendEvent } = useSendEventMutation() | |
| import { useEffect, useState } from 'react' | |
| export const UsersSearch = ({ | |
| improvedSearchEnabled = false, | |
| telemetryProps, | |
| telemetryGroups, | |
| onSelectFilterColumn, | |
| }: UsersSearchProps) => { | |
| const [_, setSelectedId] = useQueryState( | |
| 'show', | |
| parseAsString.withOptions({ history: 'push', clearOnDefault: true }) | |
| ) | |
| const [filterKeywords, setFilterKeywords] = useQueryState('keywords', { defaultValue: '' }) | |
| const [specificFilterColumn] = useQueryState<SpecificFilterColumn>( | |
| 'filter', | |
| parseAsStringEnum<SpecificFilterColumn>([ | |
| 'id', | |
| 'email', | |
| 'phone', | |
| 'name', | |
| 'freeform', | |
| ]).withDefault('email') | |
| ) | |
| const [search, setSearch] = useState(filterKeywords) | |
| useEffect(() => { | |
| setSearch(filterKeywords) | |
| }, [filterKeywords]) | |
| const { mutate: sendEvent } = useSendEventMutation() |
🤖 Prompt for AI Agents
In `@apps/studio/components/interfaces/Auth/Users/UsersSearch.tsx` around lines 52
- 75, UsersSearch initializes local state variable search from filterKeywords
but never updates it on query-state changes; add a useEffect inside UsersSearch
that watches filterKeywords and calls setSearch(filterKeywords) (only when
filterKeywords !== search) so the input stays in sync with URL query changes
(ensure the effect lists filterKeywords and search or uses a safe comparison to
avoid an infinite loop).
joshenlim
left a comment
There was a problem hiding this comment.
Verified changes preview and locally
Braintrust eval report
|
Allow for spaces in queries in the name filter. Previously they would be stripped on input change.
Summary by CodeRabbit
New Features
Bug Fixes
✏️ Tip: You can customize this high-level summary in your review settings.