Skip to content

Expand admin global search (⌘K) with provider-based architecture#338

Open
Copilot wants to merge 8 commits intomainfrom
copilot/expand-global-search-feature
Open

Expand admin global search (⌘K) with provider-based architecture#338
Copilot wants to merge 8 commits intomainfrom
copilot/expand-global-search-feature

Conversation

Copy link
Contributor

Copilot AI commented Feb 16, 2026

Enhanced Admin Global Search - Implementation Complete ✅

Summary

Successfully expanded the admin global search modal (⌘K / Ctrl+K) from only searching proposals to a unified search covering multiple data types and admin pages using a solid provider-based architecture.

Recent Updates

  • ✅ Fixed critical tRPC API usage issues identified by Greptile
  • ✅ Fixed type imports and property access in SponsorsSearchProvider
  • ✅ Removed unused useProposalSearch hook
  • ✅ Updated Storybook to demonstrate all 4 supported data types
  • ✅ All checks passing (pnpm check and pnpm test)

Implementation Checklist

  • 1. Create search abstraction layer
    • Define SearchProvider interface for pluggable search sources
    • Create base types for search results (category, item, metadata)
    • Implement provider registry pattern
  • 2. Implement search providers
    • ProposalsSearchProvider (existing functionality via API)
    • SpeakersSearchProvider (using tRPC speakers.search)
    • SponsorsSearchProvider (using tRPC sponsor.list)
    • AdminPagesSearchProvider (static navigation)
  • 3. Create unified search hook
    • Replace useProposalSearch with useUnifiedSearch
    • Support parallel queries for multiple providers
    • Handle loading states and errors per provider
    • Implement result grouping and categorization
    • Fix tRPC usage with api.useUtils().fetch()
  • 4. Update SearchModal component
    • Support multiple result categories with headers
    • Maintain keyboard navigation across groups
    • Update placeholder and empty state text
    • Add proper icons per category
    • Update Storybook stories with all data types
  • 5. Documentation
    • Create comprehensive architecture documentation (README.md)
    • Document how to add new providers
    • Include implementation patterns
    • Add troubleshooting guide
    • Create implementation summary document
  • 6. Code review
    • Address all Greptile review feedback
    • Fix critical tRPC API issues
    • Fix type imports and property names
    • Add clarifying comments
  • 7. Quality checks
    • Run CodeQL checker - 0 vulnerabilities found
    • Fix all knip issues (unused exports/files)
    • Pass all ESLint checks
    • Pass all TypeScript checks
    • Pass all tests (1531 tests)
    • Pass all formatting checks

Key Features

Extensible Architecture

  • Easy to add new search sources via SearchProvider interface
  • Each provider is isolated and can fail independently
  • Providers execute in parallel for fast results

Currently Searchable

  1. Admin Pages - Quick navigation (Dashboard, Proposals, Speakers, Sponsors, etc.)
  2. Proposals - Search talk/workshop titles, descriptions, speakers, topics
  3. Speakers - Search by name, title, email, bio
  4. Sponsors - Search by company name and website

User Experience

  • 300ms debounce prevents excessive API calls
  • Results grouped by category with clear section headers
  • Keyboard navigation maintained across all groups
  • Proper loading states and error handling
  • Dark mode support

Files Changed

  • Modified: src/lib/search/hooks/useUnifiedSearch.ts (fixed tRPC usage)
  • Modified: src/lib/search/providers/SponsorsSearchProvider.ts (fixed types)
  • Modified: src/components/admin/index.ts (removed unused export)
  • Modified: src/components/admin/SearchModal.stories.tsx (added Sponsors demo)
  • Deleted: src/components/admin/hooks/useProposalSearch.ts (replaced by useUnifiedSearch)

Testing

  • ✅ ESLint - No errors
  • ✅ TypeScript - No errors
  • ✅ Knip - No unused files/exports
  • ✅ Prettier - All files formatted
  • ✅ Tests - 1531 passing
  • ✅ CodeQL Security Scan - 0 vulnerabilities
Original prompt

This section details on the original issue you should resolve

<issue_title>Expand admin global search (⌘K) to cover more data types and pages</issue_title>
<issue_description>## Summary

The global search modal (⌘K / Ctrl+K) in the admin interface currently only searches proposals. It should be expanded to search across all major data types and link to relevant admin pages.

Current Behavior

  • SearchModal (src/components/admin/SearchModal.tsx) only queries proposals via /admin/api/proposals/search
  • Results show proposal title, speaker names, status, and link to the proposal detail page
  • Several admin pages have their own isolated inline search (speakers, orders, sponsors) but these are not accessible from the global search

Proposed Behavior

The global search should return results across multiple data types, grouped by category:

Data types to add

Data Type Fields to Search Link Target
Speakers Name, title, email, company /admin/speakers (or anchor/highlight)
Sponsors Company name, contact names, contract status /admin/sponsors
Ticket Orders Order ID, attendee name, email, company /admin/tickets/orders
Workshops Workshop title, attendee name, email /admin/workshops
Volunteers Name, email /admin/volunteers
Schedule Slots Talk title, speaker name, room/track /admin/schedule

Admin pages as search targets

In addition to data, the search should match admin page names so users can quickly navigate:

  • Dashboard, Proposals, Speakers, Schedule, Sponsors, Sponsor CRM, Sponsor Tiers, Sponsor Templates, Tickets, Orders, Ticket Types, Discount Codes, Workshops, Volunteers, Marketing, Gallery, Settings

Typing "spon" should show a "Pages" section with links to Sponsors, Sponsor CRM, Sponsor Tiers, etc.

Design Considerations

  • Group results by category (Pages, Proposals, Speakers, Sponsors, etc.) with section headers
  • Show a maximum of 3-5 results per category with a "View all" link
  • Keep keyboard navigation working across groups (arrow keys, Enter to select)
  • Maintain the existing 300ms debounce for server queries
  • Page results can be filtered client-side (static list); data results should query the server
  • Consider a unified tRPC procedure or parallel queries per data type

Technical Notes

  • Current search hook: src/components/admin/hooks/useProposalSearch.ts
  • Current modal: src/components/admin/SearchModal.tsx
  • Speakers are already loaded client-side in SpeakerTable — could reuse that pattern or add a tRPC search procedure
  • Sponsors have a tRPC router (sponsorsRouter) that could be extended with a search procedure
  • Orders search logic exists in OrdersTableWithSearch as client-side filtering</issue_description>

<agent_instructions>Admin pages has a search bar in the top navigation, currently it only searches proposals and spekaers but we want to extend this to search other conference data types. This needs to be implemented with a solid abstraction/interface so that it is easy to add more search sources in the future and integrating in the search result. Sponsors is at least one search source that we would like to have here. Maybe others?</agent_instructions>

Comments on the Issue (you are @copilot in this section)


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.


PR Type

Enhancement


Description

  • Implement provider-based search architecture for admin global search (⌘K)

  • Expand search from proposals-only to pages, proposals, speakers, and sponsors

  • Create unified search hook coordinating parallel queries across all providers

  • Update SearchModal component with grouped results and category headers


Diagram Walkthrough

flowchart LR
  SearchModal["SearchModal<br/>Component"]
  useUnifiedSearch["useUnifiedSearch<br/>Hook"]
  AdminPages["AdminPages<br/>Provider"]
  Proposals["Proposals<br/>Provider"]
  Speakers["Speakers<br/>Provider"]
  Sponsors["Sponsors<br/>Provider"]
  
  SearchModal -- "uses" --> useUnifiedSearch
  useUnifiedSearch -- "coordinates" --> AdminPages
  useUnifiedSearch -- "coordinates" --> Proposals
  useUnifiedSearch -- "coordinates" --> Speakers
  useUnifiedSearch -- "coordinates" --> Sponsors
  
  AdminPages -- "client-side<br/>filtering" --> Pages["Admin Pages"]
  Proposals -- "server API" --> ProposalData["Proposal Data"]
  Speakers -- "tRPC mutation" --> SpeakerData["Speaker Data"]
  Sponsors -- "tRPC mutation" --> SponsorData["Sponsor Data"]
Loading

File Walkthrough

Relevant files
Enhancement
9 files
types.ts
Define search provider interface and types                             
+49/-0   
AdminPagesSearchProvider.ts
Implement static admin pages search provider                         
+189/-0 
ProposalsSearchProvider.ts
Implement proposals search via existing API                           
+84/-0   
SponsorsSearchProvider.ts
Implement sponsors search via tRPC mutation                           
+60/-0   
SpeakersSearchProvider.ts
Implement speakers search via tRPC mutation                           
+60/-0   
index.ts
Export all search providers                                                           
+4/-0     
useUnifiedSearch.ts
Create unified search hook coordinating providers               
+110/-0 
index.ts
Export search module public API                                                   
+3/-0     
SearchModal.tsx
Refactor to use unified search with grouped results           
+67/-124
Documentation
3 files
README.md
Document search architecture and extension guide                 
+251/-0 
SearchModal.stories.tsx
Update stories for multi-category search examples               
+48/-34 
ENHANCED_SEARCH_IMPLEMENTATION.md
Add comprehensive implementation summary document               
+148/-0 

Greptile Summary

This PR introduces a provider-based search architecture to expand the admin global search (⌘K) from proposals-only to pages, proposals, speakers, and sponsors. The architecture is well-designed with clean interfaces, but the PR has critical runtime/compile errors that must be fixed before merging.

  • Architecture: Clean SearchProvider interface with 4 implementations (AdminPagesSearchProvider, ProposalsSearchProvider, SponsorsSearchProvider, SpeakersSearchProvider) coordinated by a useUnifiedSearch hook
  • Critical: useUnifiedSearch.ts calls .useMutation() on sponsor.list and speakers.search, but both are defined as .query() procedures in their tRPC routers — this will fail at runtime. Every other usage in the codebase correctly uses .useQuery(). Consider using api.useUtils() with .fetch() for imperative calls
  • Critical: SponsorsSearchProvider.ts imports a non-existent Sponsor type from @/lib/sponsor/types (should be SponsorExisting) and accesses sponsor.url instead of the correct sponsor.website field
  • UI: SearchModal.tsx is cleaner and simpler after the refactor, with grouped results by category and consistent icon treatment

Confidence Score: 1/5

  • This PR will not compile or function correctly due to incorrect tRPC API usage and a non-existent type import.
  • Two critical issues prevent this from working: (1) useMutation() is called on tRPC query procedures, which will fail at runtime since tRPC does not expose .useMutation() on query procedures, and (2) the Sponsor type import in SponsorsSearchProvider.ts doesn't exist, causing a compile error. The architectural design is sound, but these implementation bugs need to be resolved first.
  • src/lib/search/hooks/useUnifiedSearch.ts (incorrect tRPC hook usage) and src/lib/search/providers/SponsorsSearchProvider.ts (non-existent type import and wrong property name)

Important Files Changed

Filename Overview
src/lib/search/hooks/useUnifiedSearch.ts Uses useMutation() for tRPC query procedures (sponsor.list, speakers.search), which will cause runtime failures. The useMemo dependency array may also cause unnecessary re-renders.
src/lib/search/providers/SponsorsSearchProvider.ts Imports non-existent Sponsor type (should be SponsorExisting) and accesses sponsor.url which should be sponsor.website. Both issues will cause compile/runtime errors.
src/lib/search/types.ts Well-structured type definitions for the provider-based search architecture. Clean interfaces with appropriate optional fields.
src/lib/search/providers/AdminPagesSearchProvider.ts Solid client-side static page search with keyword matching. Comprehensive coverage of 17 admin pages with appropriate icons and keywords.
src/lib/search/providers/ProposalsSearchProvider.ts Correctly delegates to existing adminSearchProposals() API with proper error handling and result mapping. Note: the status-based sorting from the old hook was lost.
src/lib/search/providers/SpeakersSearchProvider.ts Clean provider implementation using dependency injection for search function. Minor: all results link to /admin/speakers list rather than individual speaker pages.
src/components/admin/SearchModal.tsx Simplified component using the unified search hook with grouped results. Clean refactor from the previous proposal-only implementation.
src/components/admin/SearchModal.stories.tsx Updated stories reflecting the new multi-category search UI with appropriate mock data for pages, proposals, and speakers.

Flowchart

flowchart TD
    SM["SearchModal<br/>(⌘K Dialog)"]
    UH["useUnifiedSearch<br/>Hook"]
    PA["Promise.all<br/>(parallel execution)"]
    
    SM -->|"query + 300ms debounce"| UH
    UH --> PA
    
    PA --> AP["AdminPagesSearchProvider<br/>priority: 1"]
    PA --> PP["ProposalsSearchProvider<br/>priority: 2"]
    PA --> SP["SponsorsSearchProvider<br/>priority: 3"]
    PA --> SK["SpeakersSearchProvider<br/>priority: 4"]
    
    AP -->|"client-side filter"| Pages["Static Admin Pages<br/>(17 pages)"]
    PP -->|"fetch /admin/api/..."| Proposals["Proposal Data"]
    SP -->|"tRPC sponsor.list"| Sponsors["Sponsor Data"]
    SK -->|"tRPC speakers.search"| Speakers["Speaker Data"]
    
    Pages --> GR["Group & Sort<br/>by priority"]
    Proposals --> GR
    Sponsors --> GR
    Speakers --> GR
    
    GR -->|"SearchResults"| SM

    style SP fill:#ff6b6b,stroke:#c0392b,color:#fff
    style SK fill:#ff6b6b,stroke:#c0392b,color:#fff
Loading

Last reviewed commit: 41b1b0b

Context used:

  • Context from dashboard - AGENTS.md (source)

@vercel
Copy link

vercel bot commented Feb 16, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cloudnativedays Ready Ready Preview, Comment Feb 16, 2026 0:17am

Request Review

- Created search abstraction layer with SearchProvider interface
- Implemented AdminPagesSearchProvider for static admin page navigation
- Implemented ProposalsSearchProvider using existing search API
- Implemented SponsorsSearchProvider using tRPC sponsor.list
- Implemented SpeakersSearchProvider using tRPC speakers.search
- Created useUnifiedSearch hook to coordinate multiple providers
- Updated SearchModal to use unified search with grouped results
- Updated placeholder and empty state text to reflect broader search scope

Co-authored-by: Starefossen <968267+Starefossen@users.noreply.github.com>
Copilot AI and others added 3 commits February 16, 2026 11:40
- Updated component description to reflect unified search
- Added new category examples (Pages, Speakers) to stories
- Updated placeholder text to include all searchable categories
- Updated empty state and error messages
- Fixed unused imports

Co-authored-by: Starefossen <968267+Starefossen@users.noreply.github.com>
- Created README.md explaining the search provider architecture
- Documented how to add new search providers
- Included implementation patterns and best practices
- Added troubleshooting guide
- Listed future enhancement ideas

Co-authored-by: Starefossen <968267+Starefossen@users.noreply.github.com>
- Added comments to SearchCategory documenting implemented vs planned categories
- Added clarifying comments in SponsorsSearchProvider and SpeakersSearchProvider
  explaining that navigation goes to list pages where users can filter
- This is intentional as the pages don't support direct ID-based navigation

Co-authored-by: Starefossen <968267+Starefossen@users.noreply.github.com>
- Created comprehensive implementation summary document
- Documents all components of the enhanced search system
- Includes technical details, testing results, and future enhancements
- Provides overview of files changed and impact

Co-authored-by: Starefossen <968267+Starefossen@users.noreply.github.com>
Copilot AI changed the title [WIP] Expand admin global search to cover more data types Expand admin global search (⌘K) with provider-based architecture Feb 16, 2026
Copilot AI requested a review from Starefossen February 16, 2026 11:51
@Starefossen Starefossen marked this pull request as ready for review February 16, 2026 11:57
@Starefossen Starefossen requested a review from a team as a code owner February 16, 2026 11:57
@qodo-code-review
Copy link

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Error Isolation

The hook intends “independent error handling per provider”, but using Promise.all means a single thrown rejection will fail the entire unified search and show a global error, discarding successful provider results. Consider switching to Promise.allSettled (or catching per-provider inside the map) so one provider failing doesn’t prevent other categories from rendering.

try {
  const results = await Promise.all(
    providers.map((provider) => provider.search(query)),
  )

  const groups = results
    .filter((result) => result.items.length > 0)
    .sort((a, b) => {
      const providerA = providers.find((p) => p.category === a.category)
      const providerB = providers.find((p) => p.category === b.category)
      return (providerA?.priority || 0) - (providerB?.priority || 0)
    })

  const totalCount = groups.reduce(
    (sum, group) => sum + group.items.length,
    0,
  )

  setSearchResults({ groups, totalCount })

  const errors = results.filter((r) => r.error).map((r) => r.error)
  if (errors.length > 0) {
    console.warn('Search errors:', errors)
  }
} catch (error) {
  console.error('Unified search error:', error)
  setSearchError('Failed to perform search')
  setSearchResults({ groups: [], totalCount: 0 })
} finally {
  setIsSearching(false)
}
Performance

Group sorting repeatedly calls providers.find(...) inside the comparator, which can become unnecessarily expensive as providers grow. Precompute a Map<SearchCategory, number> (category → priority) once and sort using constant-time lookups.

const groups = results
  .filter((result) => result.items.length > 0)
  .sort((a, b) => {
    const providerA = providers.find((p) => p.category === a.category)
    const providerB = providers.find((p) => p.category === b.category)
    return (providerA?.priority || 0) - (providerB?.priority || 0)
  })
Type Safety

The Combobox onChange handler checks for 'id' in item and then casts to SearchResultItem. This still allows mismatched shapes at runtime and weakens type guarantees. Prefer typing the Combobox value generically to SearchResultItem | null (or narrowing via a dedicated type guard) so the selection handler is type-safe without casts.

<Combobox
  onChange={(item) => {
    if (item && typeof item === 'object' && 'id' in item) {
      handleSelect(item as SearchResultItem)
    }
  }}
>

@qodo-code-review
Copy link

ⓘ You are approaching your monthly quota for Qodo. Upgrade your plan

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
High-level
Use tRPC queries for search

Refactor the search implementation for speakers and sponsors to use tRPC queries
(useQuery) instead of mutations (useMutation). This change aligns with best
practices for idempotent data fetching and enables performance benefits like
caching.

Examples:

src/lib/search/hooks/useUnifiedSearch.ts [23-42]
  const sponsorSearchMutation = api.sponsor.list.useMutation()
  const speakerSearchMutation = api.speakers.search.useMutation()

  const providers = useMemo<SearchProvider[]>(() => {
    return [
      new AdminPagesSearchProvider(),
      new ProposalsSearchProvider(),
      new SponsorsSearchProvider(async (query) => {
        const result = await sponsorSearchMutation.mutateAsync({ query })
        return result

 ... (clipped 10 lines)

Solution Walkthrough:

Before:

// src/lib/search/hooks/useUnifiedSearch.ts
function useUnifiedSearch() {
  const sponsorSearchMutation = api.sponsor.list.useMutation();
  const speakerSearchMutation = api.speakers.search.useMutation();

  const providers = useMemo(() => [
    new SponsorsSearchProvider(async (query) => {
      const result = await sponsorSearchMutation.mutateAsync({ query });
      return result;
    }),
    new SpeakersSearchProvider(async (query) => {
      const result = await speakerSearchMutation.mutateAsync({ query });
      return result;
    }),
    // ...
  ], [sponsorSearchMutation, speakerSearchMutation]);

  const search = async (query) => {
    // ... imperatively calls provider.search(query) which triggers mutateAsync
  };
  // ...
}

After:

// src/lib/search/hooks/useUnifiedSearch.ts
function useUnifiedSearch() {
  const [query, setQuery] = useState('');

  const { data: sponsors } = api.sponsor.list.useQuery({ query }, { enabled: !!query });
  const { data: speakers } = api.speakers.search.useQuery({ query }, { enabled: !!query });

  useEffect(() => {
    // Logic to process results from useQuery hooks (sponsors, speakers)
    // and combine them with results from other providers.
    // This replaces the imperative `Promise.all(providers.map(p => p.search(query)))`
  }, [sponsors, speakers, /* other provider results */]);

  const search = (newQuery: string) => {
    // Debounced call
    setQuery(newQuery);
  };
  // ...
}
Suggestion importance[1-10]: 8

__

Why: The suggestion correctly identifies a significant design flaw in using tRPC mutations for what should be idempotent query operations, which prevents leveraging caching and is a misuse of the data-fetching library.

Medium
General
Ignore outdated searches

Implement a request tracking mechanism using a ref to prevent race conditions
where stale search results could overwrite fresh ones.

src/lib/search/hooks/useUnifiedSearch.ts [44-88]

+import { useRef, useCallback } from 'react'
+// ...
+const requestId = useRef(0)
 const search = useCallback(
   async (query: string) => {
+    requestId.current += 1
+    const currentId = requestId.current
     setIsSearching(true)
     setSearchError(null)
     try {
       const results = await Promise.all(
         providers.map((provider) => provider.search(query)),
       )
+      if (currentId !== requestId.current) return
       setSearchResults({ groups, totalCount })
     } catch (error) {
+      if (currentId !== requestId.current) return
       setSearchError('Failed to perform search')
       setSearchResults({ groups: [], totalCount: 0 })
     } finally {
-      setIsSearching(false)
+      if (currentId === requestId.current) {
+        setIsSearching(false)
+      }
     }
   },
   [providers],
 )

[To ensure code accuracy, apply this suggestion manually]

Suggestion importance[1-10]: 8

__

Why: This suggestion addresses a potential race condition where slower, older search results could overwrite newer ones, which is a critical bug fix for ensuring UI consistency and correctness in an async search component.

Medium
Optimize search result sorting logic

Optimize the search result sorting logic in useUnifiedSearch by using a priority
property on the result objects, instead of repeatedly finding the provider to
get its priority during the sort.

src/lib/search/hooks/useUnifiedSearch.ts [60-66]

 const groups = results
   .filter((result) => result.items.length > 0)
-  .sort((a, b) => {
-    const providerA = providers.find((p) => p.category === a.category)
-    const providerB = providers.find((p) => p.category === b.category)
-    return (providerA?.priority || 0) - (providerB?.priority || 0)
-  })
+  .sort((a, b) => a.priority - b.priority)
  • Apply / Chat
Suggestion importance[1-10]: 6

__

Why: This suggestion correctly identifies a performance bottleneck in the sorting logic and proposes an effective optimization by avoiding repeated lookups, which improves efficiency as the number of search providers increases.

Low
  • More

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

12 files reviewed, 4 comments

Edit Code Review Agent Settings | Greptile

@Starefossen
Copy link
Member

@copilot tests are failing, make sure to use pnpm check and pnpm test before committing. Update the SearchModal results in Storybook to demo all of the supported data types. Fetch the review comments from Qodo and Greptile in this pull request.

- Fix tRPC usage: use api.useUtils().fetch() instead of useMutation()
- Fix SponsorsSearchProvider: use SponsorExisting type and website field
- Remove unused useProposalSearch hook and export
- Update SearchModal stories to demo all 4 supported data types (Pages, Proposals, Speakers, Sponsors)
- Fix React hooks exhaustive-deps warning

Co-authored-by: Starefossen <968267+Starefossen@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 16, 2026

@copilot tests are failing, make sure to use pnpm check and pnpm test before committing. Update the SearchModal results in Storybook to demo all of the supported data types. Fetch the review comments ...

Fixed all issues in commit a78d016:

Greptile Review Feedback:

  • ✅ Fixed tRPC usage: replaced .useMutation() with api.useUtils().fetch() for query procedures
  • ✅ Fixed SponsorsSearchProvider: changed Sponsor to SponsorExisting type
  • ✅ Fixed property access: changed sponsor.url to sponsor.website
  • ✅ Fixed React hooks dependency array

Quality Checks:

  • ✅ Removed unused useProposalSearch hook (knip issue)
  • pnpm check passes (lint, typecheck, knip, format)
  • pnpm test passes (1531 tests)

Storybook:

  • ✅ Updated SearchModal stories to demonstrate all 4 supported data types (Pages, Proposals, Speakers, Sponsors)
  • ✅ Storybook builds successfully

All tests and checks passing. Ready for review.

@Starefossen
Copy link
Member

@copilot why is the search result displayed so narrow in Storbyook preview? Screenshot 2026-02-16 at 13 36 15

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Expand admin global search (⌘K) to cover more data types and pages

2 participants