Skip to content

Comments

search input (automagik-forge)#295

Open
GALI3600 wants to merge 5 commits intodevfrom
forge/9f85-search-input
Open

search input (automagik-forge)#295
GALI3600 wants to merge 5 commits intodevfrom
forge/9f85-search-input

Conversation

@GALI3600
Copy link
Contributor

@GALI3600 GALI3600 commented Dec 4, 2025

✨ Feature: Add Text Input to Search Projects by Name
Summary

This pull request introduces a text input field in the Projects menu, enabling users to quickly search and filter projects by name.

Details

Added a search input component to the Projects menu UI.

Implemented dynamic filtering logic that updates the project list as the user types.

Ensures improved usability for users managing large numbers of projects.

No breaking changes; existing functionality remains intact.

Why This Matters

Previously, users had to manually scroll through the entire list of projects. This enhancement streamlines navigation and significantly improves productivity.

searchInput

…s what I implemented:

## Changes Made:

**In `frontend/src/components/projects/project-list.tsx`:**
1. Added `Input` component import from UI library
2. Added `Search` icon from lucide-react
3. Added `searchQuery` state to track the search input
4. Updated the `sortedProjects` memo to filter projects by name before sorting (case-insensitive match)
5. Added search input UI next to the sort filters with a search icon

**In `frontend/src/i18n/locales/en/projects.json`:**
1. Added translation key `search.placeholder` with value "Search projects..."

## How it works:
- The search input appears before the sort dropdown and direction toggle button
- Filtering happens on the frontend only (no API calls)
- Search is case-insensitive and matches partial project names
- Projects are filtered first, then sorted according to the selected sort field and direction
- The search icon appears on the left side of the input field for better UX

The feature is now ready to use! Type in the search box to filter projects by name in real-time.
…ook was using `sortedProjects` in its dependency array. This meant that every time you typed or deleted text in the search input, the filtered/sorted project list changed, triggering the effect and causing a re-render that lost the input focus.

**The fix:**
Changed the dependency from `sortedProjects` to `projects` - now the effect only runs when the actual project data changes (like when initially loaded), not when the filtered view changes due to search input.

The search input should now maintain focus while you type and delete text!
1. **Added a `ref` to the Input component** - This helps React maintain the identity of the input element across re-renders
2. **Changed the dependency from `projects` to `projects.length`** - This prevents the effect from triggering when the projects array reference changes (which happens with `setProjects(result)`), and only triggers when the actual number of projects changes

The key issue was that `projects` is a new array reference every time `setProjects()` is called, which would trigger the effect even though the content might be the same. By using `projects.length` instead, we only react to actual changes in the number of projects.

The input should now maintain focus consistently when you type or delete text!
1. **Added `useCallback` for the onChange handler** - This ensures the handler function reference stays stable across re-renders
2. **Added a stable `key` prop** to the input container div - This tells React to preserve this specific DOM element across re-renders
3. **Added "No results" state** - Now when you filter and get no results, it shows a helpful message instead of nothing

The combination of these changes should help maintain focus. The `key` prop is especially important because it tells React "this is the same element, don't recreate it" even when sibling elements change dramatically (like when the project grid appears/disappears).

Try it now - the input should maintain focus consistently when you type or delete text!
**The fix:**
- After updating the search query state, it uses `requestAnimationFrame` to check if focus was lost during the re-render
- If the input no longer has focus, it programmatically restores it
- The `requestAnimationFrame` ensures this happens after React has finished all DOM updates

This approach is more robust because:
1. It detects when focus is actually lost (not just assumes it will be)
2. It only restores focus if it was actually lost to another element
3. It waits for the render cycle to complete before checking

The input should now maintain focus consistently while you type, even when the filtered results change dramatically (like going from many results to zero or vice versa)!
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @GALI3600, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant user experience improvement by adding a search capability to the projects list. Users can now easily find specific projects by typing into a new search bar, which filters the displayed projects in real-time. This enhancement makes navigating and managing projects more efficient, especially for users with a large number of projects.

Highlights

  • Search Functionality Added: A new search input field has been integrated into the projects list, allowing users to filter projects by name.
  • Dynamic Project Filtering: The project list now dynamically filters projects based on the search query, applying the search filter before any existing sorting logic.
  • User Interface Enhancements: A dedicated search input component with an icon has been added, along with a 'No results found' message card that displays when a search yields no matching projects.
  • Internationalization Support: New internationalization keys have been introduced for the search placeholder, no results message, and description, ensuring multi-language support for the new feature.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request adds a search input to the projects list, allowing users to filter projects by name. The implementation is solid, including updates to internationalization files and a dedicated 'no results' state. I've provided a few suggestions to improve user experience, performance, and code clarity, mainly regarding focus handling and optimization of the new search input. Overall, this is a great addition to the projects page.

Comment on lines +120 to +128
const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
setSearchQuery(e.target.value);
// Restore focus after state update
requestAnimationFrame(() => {
if (document.activeElement !== searchInputRef.current) {
searchInputRef.current?.focus();
}
});
}, []);
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The handleSearchChange function uses requestAnimationFrame to force focus back to the search input after every change. This can lead to a poor user experience, as it prevents the user from clicking away from the input field. If the user clicks on another element, focus will be immediately snapped back to the search input, which is unexpected and disruptive. If there is an underlying issue with the input losing focus during re-renders, it should be addressed at its root rather than with this workaround.

  const handleSearchChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    setSearchQuery(e.target.value);
  }, []);

let sorted = [...projects];

// First filter by search query
if (searchQuery.trim()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The current implementation filters the project list on every keystroke. For a large number of projects, this could lead to performance degradation and a sluggish user interface. Consider debouncing the search input. This would execute the filtering logic only after the user has stopped typing for a short period (e.g., 300ms), which is a common and effective optimization for search functionality.

<p className="text-muted-foreground">{t('subtitle')}</p>
</div>
<div className="flex flex-wrap items-center gap-3">
<div key="search-input" className="relative w-[200px]">
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The key prop on this div is unnecessary. The key prop is a special attribute used by React to identify which items in a list have changed, are new, or were removed. Since this element is not part of a dynamically generated list (e.g., from an array map), this key serves no purpose and can be removed to improve code clarity.

          <div className="relative w-[200px]">

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant