-
Notifications
You must be signed in to change notification settings - Fork 3
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
base: master
Are you sure you want to change the base?
Conversation
📝 Walkthrough""" WalkthroughThis change introduces two new FontAwesome icon variables ( Estimated code review effort🎯 3 (Moderate) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (1)
🧰 Additional context used🧠 Learnings (1)routers/root.py (1)Learnt from: nikochiko 🔇 Additional comments (9)
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this 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
📒 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 torender_search_filters
- Simplified redirect condition improves readability
model_dump(exclude_defaults=True)
creates cleaner URLs by omitting empty valuesrouters/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
tod-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 fromlg
toxl
may affect tablet users.The change from
d-lg-block
tod-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
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(); | ||
""") |
There was a problem hiding this comment.
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.
There was a problem hiding this 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
📒 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
tostr = ""
aligns well with theSearchFilters
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
tod-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.
16b09ee
to
3a4436a
Compare
There was a problem hiding this 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
📒 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 refactoredsaved_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 catchesKeyError
andWorkspace.DoesNotExist
, falling back to a personal workspace and never returningNone
.get_filter_value_from_workspace
always produces a valid string.SearchFilters
is a Pydantic model, andmodel_dump(exclude_defaults=True)
won’t raise errors on these inputs.
544dbd7
to
464a197
Compare
There was a problem hiding this 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
📒 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 andcurrent_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.
There was a problem hiding this 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 unsupportedshape
option for the mobile icon buttonThe Google Identity documentation states that when
type: "icon"
is used,shape
,size
,text
, andwidth
are ignored.
Passingshape: "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
📒 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)
templates/google_one_tap_button.html
Outdated
<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> |
There was a problem hiding this comment.
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.
templates/google_one_tap_button.html
Outdated
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" | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
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.
14c59f9
to
a95483b
Compare
refactor: SearchFilters type now has defaults as "" instead of None
c27b40a
to
00f0f80
Compare
e0c0eff
to
f8c5d85
Compare
f8c5d85
to
cfc865e
Compare
use position-absolute instead of setting display: none
53cf4a2
to
cb14142
Compare
Q/A checklist
How to check import time?
You can visualize this using tuna:
To measure import time for a specific library:
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:
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.