Skip to content

feat: move search box to header #717

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open

Conversation

nikochiko
Copy link
Member

@nikochiko nikochiko commented Jun 30, 2025

  • feat: show search bar in header
  • feat: add mobile friendly search
  • feat: add redirect from saved tab to go to /explore?workspace=...

Q/A checklist

  • I have tested my UI changes on mobile and they look acceptable
  • I have tested changes to the workflows in both the API and the UI
  • I have done a code review of my changes and looked at each line of the diff + the references of each function I have changed
  • My changes have not increased the import time of the server
How to check import time?

time python -c 'import server'

You can visualize this using tuna:

python3 -X importtime -c 'import server' 2> out.log && tuna out.log

To measure import time for a specific library:

$ time python -c 'import pandas'

________________________________________________________
Executed in    1.15 secs    fish           external
   usr time    2.22 secs   86.00 micros    2.22 secs
   sys time    0.72 secs  613.00 micros    0.72 secs

To reduce import times, import libraries that take a long time inside the functions that use them instead of at the top of the file:

def my_function():
    import pandas as pd
    ...

Legal Boilerplate

Look, I get it. The entity doing business as “Gooey.AI” and/or “Dara.network” was incorporated in the State of Delaware in 2020 as Dara Network Inc. and is gonna need some rights from me in order to utilize my contributions in this PR. So here's the deal: I retain all rights, title and interest in and to my contributions, and by keeping this boilerplate intact I confirm that Dara Network Inc can use, modify, copy, and redistribute my contributions, under its choice of terms.


Copy link

coderabbitai bot commented Jun 30, 2025

📝 Walkthrough

"""

Walkthrough

This change introduces two new FontAwesome icon variables (sign_in and search) and removes the "Explore" link and its icon from the header navigation. The /saved route is replaced with an authenticated route explore_in_current_workspace that redirects users to the explore page with workspace-scoped search filters serialized in the URL. The explore page route and layout are enhanced with a responsive search bar featuring mobile toggle functionality and JavaScript for UI control and redirect on search input changes. The SearchFilters model and related filter rendering functions are simplified to use empty strings by default, with new helpers for workspace filter value conversions. The workspace selector dropdown is refactored for improved layout and link rendering consistency, including adding a "Saved" link. Minor CSS and template adjustments support these UI changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~45 minutes

Possibly related PRs

  • fix: pressing Enter on search bar should submit the query #729: The main PR refactors and enhances the search bar rendering and behavior in widgets/workflow_search.py among other files, while the retrieved PR specifically adds a hidden submit button inside the render_search_bar function to enable form submission on pressing Enter; thus, both modify the same function in the same file with directly related changes to search bar form behavior.
  • fix: icon loading on 404 page #703: The main PR adds new icon variables with FontAwesome HTML strings and updates header link rendering to include icons, while the retrieved PR focuses on fixing icon loading and rendering issues on the 404 page by enabling FontAwesome and adding icons to header links; both modify icon usage and header link rendering with overlapping concerns on icon HTML and display.
  • fix: blur search bar on pressing enter #731: The main PR refactors render_search_bar to accept additional parameters and dynamic placeholder logic, while the retrieved PR adds an id parameter and changes submit button behavior; both modify the same function with related UI and form handling changes.

Suggested reviewers

  • devxpy
    """

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 86f6769 and 81015cd.

📒 Files selected for processing (2)
  • routers/root.py (9 hunks)
  • widgets/explore.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • widgets/explore.py
🧰 Additional context used
🧠 Learnings (1)
routers/root.py (1)

Learnt from: nikochiko
PR: #703
File: workspaces/widgets.py:161-166
Timestamp: 2025-06-16T11:43:04.972Z
Learning: In workspaces/widgets.py header links rendering, the gui.columns([2, 10]) layout should be maintained consistently even when no icon exists, leaving empty space in the first column for visual alignment purposes. This prioritizes consistent alignment over space optimization.

🔇 Additional comments (9)
routers/root.py (9)

8-8: LGTM! Import additions are appropriate.

All new imports are properly used throughout the file for the search functionality implementation.

Also applies to: 38-38, 50-51


252-254: Good simplification using empty strings as defaults.

This change improves API consistency by eliminating the need for null checking and aligns with the SearchFilters model design.


261-262: Proper integration of search functionality.

The changes correctly pass search_filters to the necessary components and prevent duplicate search bars with show_search_bar=False.

Also applies to: 265-267


704-718: Well-implemented search redirect functionality.

The function correctly handles search input changes and redirects with clean URLs using exclude_defaults=True. The logic flow is sound.


720-739: Clean mobile search toggle implementation.

The JavaScript functions properly implement the mobile overlay pattern with appropriate CSS class manipulation and good UX (focus on input).


742-750: Appropriate function signature enhancement.

The new parameters are properly typed and have sensible defaults. The search_filters parameter enables header search integration.


759-781: Good responsive layout adjustments.

The layout changes properly support the mobile search overlay and improve responsive breakpoints for the logo visibility.


813-837: Improved header navigation consistency.

The conditional "Explore" link and consistent use of render_header_link provide better navigation UX. The "Saved" link addition for authenticated users is a good enhancement.


866-866: Excellent consistency improvements.

The use of helper functions render_link_in_dropdown and render_header_link eliminates code duplication and provides consistent styling across the navigation.

Also applies to: 876-889, 891-897

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch search-box-in-header

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
routers/root.py (1)

726-745: Consider adding error handling to JavaScript functions.

The mobile search toggle functions work but could be more robust. Consider:

  • Adding null checks before accessing elements
  • Using CSS classes for display changes instead of inline styles
  • Defining class names as constants to avoid hardcoding

Example improvement:

-hide_on_mobile_search.forEach(el => el.style.setProperty('display', 'flex'));
-show_on_mobile_search.forEach(el => el.style.setProperty('display', 'none'));
+hide_on_mobile_search.forEach(el => el?.classList.remove('d-none'));
+show_on_mobile_search.forEach(el => el?.classList.add('d-none'));
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42d6d9e and 264678b.

📒 Files selected for processing (7)
  • daras_ai_v2/icons.py (1 hunks)
  • daras_ai_v2/settings.py (2 hunks)
  • routers/account.py (2 hunks)
  • routers/root.py (7 hunks)
  • widgets/explore.py (2 hunks)
  • widgets/workflow_search.py (9 hunks)
  • workspaces/widgets.py (3 hunks)
🧰 Additional context used
🧠 Learnings (4)
daras_ai_v2/icons.py (1)
Learnt from: nikochiko
PR: GooeyAI/gooey-server#703
File: daras_ai_v2/settings.py:309-309
Timestamp: 2025-06-16T11:40:10.683Z
Learning: The FontAwesome icon `fa-magnifying-glass` is available in both `fa-solid` and `fa-regular` styles. The user nikochiko confirmed this with documentation link https://fontawesome.com/icons/magnifying-glass?f=classic&s=regular
workspaces/widgets.py (1)
Learnt from: nikochiko
PR: GooeyAI/gooey-server#703
File: workspaces/widgets.py:161-166
Timestamp: 2025-06-16T11:43:04.972Z
Learning: In workspaces/widgets.py header links rendering, the gui.columns([2, 10]) layout should be maintained consistently even when no icon exists, leaving empty space in the first column for visual alignment purposes. This prioritizes consistent alignment over space optimization.
daras_ai_v2/settings.py (1)
Learnt from: nikochiko
PR: GooeyAI/gooey-server#703
File: daras_ai_v2/settings.py:301-308
Timestamp: 2025-06-16T11:42:40.993Z
Learning: In daras_ai_v2/settings.py, when using a localhost frontend with api.gooey.ai backend deployment, hard-coded "/explore/" paths work correctly as relative URLs, but EXPLORE_URL computed from APP_BASE_URL may point to the wrong domain (localhost instead of api.gooey.ai).
routers/root.py (1)
Learnt from: nikochiko
PR: GooeyAI/gooey-server#703
File: workspaces/widgets.py:161-166
Timestamp: 2025-06-16T11:43:04.972Z
Learning: In workspaces/widgets.py header links rendering, the gui.columns([2, 10]) layout should be maintained consistently even when no icon exists, leaving empty space in the first column for visual alignment purposes. This prioritizes consistent alignment over space optimization.
🧬 Code Graph Analysis (4)
workspaces/widgets.py (2)
workspaces/models.py (2)
  • html_icon (404-411)
  • display_name (392-402)
workspaces/admin.py (1)
  • display_name (132-133)
widgets/explore.py (1)
widgets/workflow_search.py (2)
  • SearchFilters (26-32)
  • render_search_filters (35-66)
routers/account.py (4)
daras_ai_v2/fastapi_tricks.py (2)
  • get_app_route_url (68-74)
  • get_route_path (77-80)
widgets/workflow_search.py (2)
  • SearchFilters (26-32)
  • get_filter_value_from_workspace (144-145)
workspaces/widgets.py (1)
  • get_current_workspace (184-195)
routers/root.py (1)
  • explore_page (252-273)
widgets/workflow_search.py (3)
workspaces/models.py (3)
  • Workspace (105-449)
  • display_html (47-57)
  • display_html (387-390)
app_users/models.py (2)
  • AppUser (90-262)
  • cached_workspaces (242-249)
daras_ai_v2/all_pages.py (1)
  • normalize_slug (109-110)
🪛 Pylint (3.3.7)
widgets/workflow_search.py

[refactor] 26-26: Too few public methods (1/2)

(R0903)


[refactor] 108-108: Consider using '{"resize": 'none', "paddingLeft": '2.7rem', "paddingRight": '2.7rem', ... }' instead of a call to 'dict'.

(R1735)

⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Analyze (python)
  • GitHub Check: test (3.10.12, 1.8.3)
🔇 Additional comments (17)
daras_ai_v2/icons.py (1)

49-49: LGTM! Clean addition of search icon.

The new search icon follows the established pattern and uses an appropriate FontAwesome solid style for search functionality.

daras_ai_v2/settings.py (2)

25-25: LGTM! Proper import addition.

The icons module import is correctly added to support the updated HEADER_ICONS mapping.


309-311: LGTM! Header navigation update aligns with PR objectives.

The replacement of "Explore" with "Saved" in the header navigation makes sense given that search functionality is moving to the header and the saved route now redirects to explore with appropriate filters.

widgets/explore.py (2)

2-2: LGTM! Proper import for avoiding side effects.

The copy module import supports the defensive copying of search_filters to prevent unintended modifications.


28-36: LGTM! Improved search filter handling with better defensive programming.

The changes implement several good practices:

  • Always initializing search_filters prevents None reference issues
  • Using copy(search_filters) prevents side effects when passing to render_search_filters
  • Simplified redirect condition improves readability
  • model_dump(exclude_defaults=True) creates cleaner URLs by omitting empty values
routers/account.py (2)

16-16: LGTM! Proper import addition for URL construction.

The get_app_route_url import is needed for building the redirect URL with query parameters.


146-161: LGTM! Well-implemented redirect functionality that aligns with PR objectives.

The refactored saved_route correctly implements the stated objective of redirecting from the saved tab to /explore with workspace query parameters. The implementation includes:

  • Proper authentication checks with login redirect
  • Current workspace retrieval for filter context
  • Clean URL construction using model_dump(exclude_defaults=True)
  • Appropriate use of helper functions for workspace filter values
workspaces/widgets.py (3)

2-2: LGTM! Proper import for HTML escaping.

The html module import supports secure rendering of user-generated content in workspace names.


55-58: LGTM! Improved workspace display structure and security.

The refactored workspace display implements several improvements:

  • Structured layout with proper container and CSS classes
  • Security enhancement with html.escape() to prevent XSS in workspace names
  • Responsive design that hides display name on smaller screens
  • Better separation of concerns for icon, text, and chevron elements

149-149: LGTM! Responsive breakpoint adjustment supports mobile-friendly design.

Changing from d-lg-none to d-xl-none keeps header links hidden on larger screens, providing more space for the mobile-friendly search interface mentioned in the PR objectives.

routers/root.py (4)

252-256: Good change: Consistent empty string defaults.

Using empty strings instead of None for search filter parameters provides a more consistent API and simplifies downstream handling.


709-724: Well-implemented search bar with redirect logic.

The function properly handles search state management and triggers redirects when the search query changes. Good use of the framework's redirect mechanism.


783-803: Verify state synchronization between mobile and desktop search bars.

Having two separate search bars with different keys (mobile_search_query vs default) could lead to inconsistent state when switching between mobile and desktop views. Consider synchronizing their values or using a single search bar with responsive styling.


816-821: Breakpoint change from lg to xl may affect tablet users.

The change from d-lg-block to d-xl-block means header links will be hidden on devices up to 1200px width (instead of 992px). This might negatively impact users on smaller laptops or tablets. Was this intentional?

widgets/workflow_search.py (3)

26-33: Good simplification of the SearchFilters model.

Changing from optional fields to required fields with empty string defaults simplifies the model and eliminates the need for the validator. This is a cleaner approach.


144-157: Well-designed helper functions for workspace filtering.

These helper functions provide a clean abstraction for converting between workspace objects and filter values, handling both ID and handle name cases appropriately.


69-111: Good enhancement to render_search_bar flexibility.

Adding **props support and responsive styling (max-width: 500px, flex-grow: 1) makes the search bar more reusable and adaptable to different contexts.

routers/root.py Outdated
Comment on lines 726 to 739
def get_js_hide_mobile_search():
return dedent("""
event.preventDefault();
const hide_on_mobile_search = document.querySelectorAll('.hide_on_mobile_search');
const show_on_mobile_search = document.querySelectorAll('.show_on_mobile_search');
hide_on_mobile_search.forEach(el => el.style.setProperty('display', 'flex'));
show_on_mobile_search.forEach(el => el.style.setProperty('display', 'none'));
""")


def get_js_show_mobile_search():
return dedent("""
event.preventDefault();
const hide_on_mobile_search = document.querySelectorAll('.hide_on_mobile_search');
const show_on_mobile_search = document.querySelectorAll('.show_on_mobile_search');
hide_on_mobile_search.forEach(el => el.style.setProperty('display', 'none'));
show_on_mobile_search.forEach(el => el.style.setProperty('display', 'flex'));
document.querySelector('#search_bar').focus();
""")
Copy link
Member Author

Choose a reason for hiding this comment

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

this .setProperty works OK across different screens because bootstrap adds !important when we add e.g. d-md-flex. bigger screens won't be affected by this style change.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
routers/root.py (1)

726-744: Consider preserving original display values instead of hardcoding 'flex'.

The JavaScript functions assume all elements should use display: flex, which might not be appropriate for all elements. Consider storing and restoring the original display values.

Here's a more flexible approach:

-hide_on_mobile_search.forEach(el => el.style.setProperty('display', 'flex'));
-show_on_mobile_search.forEach(el => el.style.setProperty('display', 'none'));
+hide_on_mobile_search.forEach(el => el.style.removeProperty('display'));
+show_on_mobile_search.forEach(el => el.style.setProperty('display', 'none'));

And similarly for the show function. This lets CSS control the display property when visible.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 264678b and d605458.

📒 Files selected for processing (1)
  • routers/root.py (7 hunks)
🧰 Additional context used
🧠 Learnings (1)
routers/root.py (1)
Learnt from: nikochiko
PR: GooeyAI/gooey-server#703
File: workspaces/widgets.py:161-166
Timestamp: 2025-06-16T11:43:04.972Z
Learning: In workspaces/widgets.py header links rendering, the gui.columns([2, 10]) layout should be maintained consistently even when no icon exists, leaving empty space in the first column for visual alignment purposes. This prioritizes consistent alignment over space optimization.
🧬 Code Graph Analysis (1)
routers/root.py (2)
daras_ai_v2/fastapi_tricks.py (1)
  • get_app_route_url (68-74)
widgets/workflow_search.py (2)
  • SearchFilters (26-32)
  • render_search_bar (69-119)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Analyze (python)
  • GitHub Check: test (3.10.12, 1.8.3)
🔇 Additional comments (3)
routers/root.py (3)

254-256: Good simplification of default parameters.

The change from Optional[str] = None to str = "" aligns well with the SearchFilters model that now uses empty strings as defaults, making the code more consistent.


709-724: Well-implemented search bar with redirect logic.

The function correctly handles search input changes and redirects with updated query parameters. Good use of gui.RedirectException for the redirect flow.


811-811: Breakpoint adjusted for better responsive layout.

The change from d-lg-block to d-xl-block provides more space for the search bar on medium-large screens (992px-1200px). This is a reasonable adjustment for the new header layout.

@nikochiko nikochiko force-pushed the search-box-in-header branch from 16b09ee to 3a4436a Compare June 30, 2025 08:44
@nikochiko nikochiko requested a review from devxpy June 30, 2025 08:53
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
routers/account.py (1)

137-138: Consider moving imports to module level for better performance.

Function-level imports can impact performance if this route is called frequently. Unless there are circular import constraints, consider moving these imports to the top of the file.

+from widgets.workflow_search import SearchFilters, get_filter_value_from_workspace

Move to the top with other imports, and remove from the function:

def saved_route(request: Request):
-    from widgets.workflow_search import SearchFilters, get_filter_value_from_workspace
-
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3a4436a and 544dbd7.

📒 Files selected for processing (1)
  • routers/account.py (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Analyze (python)
  • GitHub Check: test (3.10.12, 1.8.3)
🔇 Additional comments (3)
routers/account.py (3)

14-14: LGTM: Import addition supports new redirect functionality.

The addition of get_app_route_url is necessary for constructing the redirect URL with query parameters in the refactored saved_route.


139-142: LGTM: Authentication check is properly implemented.

The authentication logic correctly handles unauthenticated and anonymous users by redirecting to login with the appropriate next parameter.


144-152: No additional error handling required for workspace or filter serialization

  • get_current_workspace already catches KeyError and Workspace.DoesNotExist, falling back to a personal workspace and never returning None.
  • get_filter_value_from_workspace always produces a valid string.
  • SearchFilters is a Pydantic model, and model_dump(exclude_defaults=True) won’t raise errors on these inputs.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
widgets/workflow_search.py (1)

320-321: LGTM! Critical issue resolved.

The workspace filter is now properly applied with the queryset assignment, and using the helper function makes the code more maintainable. This resolves the critical issue identified in the previous review.

🧹 Nitpick comments (1)
widgets/workflow_search.py (1)

115-118: Minor optimization: Simplify dict construction.

The static analysis tool suggests a minor optimization for the style dictionary construction.

-            style=(
-                dict(resize="none", paddingLeft="2.7rem", paddingRight="2.7rem")
-                | props.pop("style", {})
-            ),
+            style=(
+                {"resize": "none", "paddingLeft": "2.7rem", "paddingRight": "2.7rem"}
+                | props.pop("style", {})
+            ),
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 544dbd7 and bb7b7a8.

📒 Files selected for processing (4)
  • routers/account.py (2 hunks)
  • routers/root.py (7 hunks)
  • widgets/workflow_search.py (9 hunks)
  • workspaces/widgets.py (6 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • workspaces/widgets.py
  • routers/account.py
  • routers/root.py
🧰 Additional context used
🪛 Pylint (3.3.7)
widgets/workflow_search.py

[refactor] 26-26: Too few public methods (1/2)

(R0903)


[refactor] 116-116: Consider using '{"resize": 'none', "paddingLeft": '2.7rem', "paddingRight": '2.7rem', ... }' instead of a call to 'dict'.

(R1735)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test (3.10.12, 1.8.3)
🔇 Additional comments (7)
widgets/workflow_search.py (7)

1-2: LGTM! Clean import organization.

The addition of typing imports and conditional imports for type hints follows Python best practices and avoids circular import issues.

Also applies to: 13-13, 22-24


27-29: LGTM! Model simplification improves consistency.

The change from optional strings to plain strings with empty defaults removes unnecessary complexity while maintaining the same functionality through the __bool__ method.


44-46: LGTM! Improved function efficiency.

The refactoring to directly update the passed SearchFilters instance instead of reconstructing it is more efficient and provides a cleaner API by returning the updated object.

Also applies to: 52-66


69-74: LGTM! Improved function signature for better API design.

The updated signature accepting a SearchFilters object and current_user provides better context for generating dynamic placeholders and enables more flexible styling.


132-162: LGTM! Excellent UX enhancement with dynamic placeholders.

The function provides contextual placeholder text that improves user experience by showing current filter context. The error handling for missing workflow pages and proper workspace display logic are well implemented.


186-201: LGTM! Well-designed helper functions improve maintainability.

These functions properly centralize the workspace filter conversion logic, handling both workspace handles and IDs correctly. The bidirectional conversion approach is clean and type-safe.


314-316: LGTM! Function signature improvement.

Making the user parameter required is appropriate since it's needed for workspace filter resolution, and the type annotation is now more accurate.

@devxpy devxpy assigned nikochiko and unassigned devxpy Jul 1, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
templates/google_one_tap_button.html (1)

23-25: Remove unsupported shape option for the mobile icon button

The Google Identity documentation states that when type: "icon" is used, shape, size, text, and width are ignored.
Passing shape: "rectangular" is unnecessary and may trigger console warnings in future SDK versions.

-        shape: "rectangular",
         type: "icon"
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb7b7a8 and 91d0ac9.

📒 Files selected for processing (2)
  • daras_ai_v2/base.py (1 hunks)
  • templates/google_one_tap_button.html (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • daras_ai_v2/base.py
🧰 Additional context used
🪛 HTMLHint (1.5.0)
templates/google_one_tap_button.html

[error] 1-1: Doctype must be declared before any non-comment content.

(doctype-first)

⏰ 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). (1)
  • GitHub Check: test (3.10.12, 1.8.3)

Comment on lines 1 to 4
<span class="pe-2" style="height: 44px; max-width: 200px" data-replace-login-spinner>
<span id="g_id_signin_desktop" class="d-none d-md-inline"></span>
<span id="g_id_signin_mobile" class="d-md-none"></span>
</span>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid embedding block-level content in an inline <span> container

google.accounts.id.renderButton injects a <div> inside the given node. Nesting a block element (<div>) inside an inline element (<span>) is invalid HTML and can break layouts in some browsers.
Replace the outer <span> with a semantic block container (div or span + d-inline-block) to keep the markup valid.

-<span class="pe-2" style="height: 44px; max-width: 200px" data-replace-login-spinner>
+<div class="pe-2 d-inline-block" style="height: 44px; max-width: 200px" data-replace-login-spinner>
     <span id="g_id_signin_desktop" class="d-none d-md-inline"></span>
     <span id="g_id_signin_mobile" class="d-md-none"></span>
-</span>
+</div>
🧰 Tools
🪛 HTMLHint (1.5.0)

[error] 1-1: Doctype must be declared before any non-comment content.

(doctype-first)

🤖 Prompt for AI Agents
In templates/google_one_tap_button.html lines 1 to 4, the outer <span> contains
block-level elements injected by google.accounts.id.renderButton, which is
invalid HTML. Replace the outer <span> with a <div> or a <span> styled with
d-inline-block to ensure the container is a valid block-level or inline-block
element, preventing layout issues.

Comment on lines 17 to 26
google.accounts.id.prompt();
google.accounts.id.renderButton(document.getElementById("g_id_signin"), {
google.accounts.id.renderButton(document.getElementById("g_id_signin_desktop"), {
shape: "rectangular",
width: 200,
text: "continue_with",
});
google.accounts.id.renderButton(document.getElementById("g_id_signin_mobile"), {
shape: "rectangular",
type: "icon"
});
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Prevent duplicate button rendering on repeated hydrated events

oneTapSignin() is executed on both DOMContentLoaded and every custom hydrated event, but it unconditionally calls renderButton.
When the event fires multiple times (e.g. client-side re-hydration), extra Google button iframes accumulate, causing unpredictable layout and duplicate IDs.

Guard the call, or clear the container before re-rendering:

 async function oneTapSignin() {
     google.accounts.id.prompt();
-    google.accounts.id.renderButton(document.getElementById("g_id_signin_desktop"), {
+    const desktop = document.getElementById("g_id_signin_desktop");
+    const mobile  = document.getElementById("g_id_signin_mobile");
+
+    // avoid duplicate children on re-hydration
+    desktop.replaceChildren();
+    mobile.replaceChildren();
+
+    google.accounts.id.renderButton(desktop, {
         shape: "rectangular",
         width: 200,
         text: "continue_with",
     });
-    google.accounts.id.renderButton(document.getElementById("g_id_signin_mobile"), {
-        shape: "rectangular",
-        type: "icon"
-    });
+    google.accounts.id.renderButton(mobile, {
+        type: "icon"          // 'icon' ignores shape/width
+    });
 }
📝 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.

Suggested change
google.accounts.id.prompt();
google.accounts.id.renderButton(document.getElementById("g_id_signin"), {
google.accounts.id.renderButton(document.getElementById("g_id_signin_desktop"), {
shape: "rectangular",
width: 200,
text: "continue_with",
});
google.accounts.id.renderButton(document.getElementById("g_id_signin_mobile"), {
shape: "rectangular",
type: "icon"
});
google.accounts.id.prompt();
const desktop = document.getElementById("g_id_signin_desktop");
const mobile = document.getElementById("g_id_signin_mobile");
// avoid duplicate children on re-hydration
desktop.replaceChildren();
mobile.replaceChildren();
google.accounts.id.renderButton(desktop, {
shape: "rectangular",
width: 200,
text: "continue_with",
});
google.accounts.id.renderButton(mobile, {
type: "icon" // 'icon' ignores shape/width
});
🤖 Prompt for AI Agents
In templates/google_one_tap_button.html around lines 17 to 26, the oneTapSignin
function calls google.accounts.id.renderButton unconditionally on each
DOMContentLoaded and hydrated event, causing duplicate Google sign-in buttons to
accumulate. To fix this, add a guard to check if the button container already
has child elements before rendering, or clear the container's contents before
calling renderButton again to prevent duplicate iframes and IDs.

@nikochiko nikochiko force-pushed the search-box-in-header branch from 14c59f9 to a95483b Compare July 7, 2025 15:52
@nikochiko nikochiko assigned devxpy and unassigned nikochiko Jul 7, 2025
@nikochiko nikochiko force-pushed the search-box-in-header branch from c27b40a to 00f0f80 Compare July 10, 2025 10:02
@nikochiko nikochiko force-pushed the search-box-in-header branch 4 times, most recently from e0c0eff to f8c5d85 Compare July 10, 2025 14:28
@nikochiko nikochiko force-pushed the search-box-in-header branch from f8c5d85 to cfc865e Compare July 10, 2025 14:29
@nikochiko nikochiko force-pushed the search-box-in-header branch from 53cf4a2 to cb14142 Compare July 23, 2025 11:59
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.

2 participants