Skip to content

Fix quick filters in the network page #789

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

Closed
wants to merge 2 commits into from

Conversation

mpourismaiel
Copy link
Collaborator

I hadn't considered quick filters when fixing an issue with location input. The only fix I could think of to avoid a regression was to add another 1-way bound variable.

With this the setup is as follows:

  • overrideLocation passes value to location-input
  • location receives value from location-input

And these are used as:

  • location for updating url and filtersSet
  • overrideLocation for passing the quick filters changes and initial url variables to location-input

Copy link

coderabbitai bot commented Jul 8, 2025

Walkthrough

This change introduces a new reactive property, overrideValue, to the location-input component, along with an observer that synchronizes its value to the existing value property and updates filtered results and completion state when changed. In the globalping network page, a new overrideLocation property is added and used to manage location-related state, replacing direct updates to the location property. The c-location-input component now receives overrideValue from overrideLocation, and several methods and computed properties are updated to use this new property for location management.

Possibly related PRs

  • draft: Redesign network page #763: Redesigns the network page and modifies usage of overrideValue in the network page, which directly relates to the introduction and handling of overrideValue in the location-input component in this PR.

Suggested reviewers

  • MartinKolarik

Poem

A new override takes the stage,
Syncing values as we engage.
Locations now in twofold view,
One for input, one for you.
With probes that filter, states align—
Reactive magic by design!
🌍✨


📜 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 2baf5f5 and ac99d7a.

📒 Files selected for processing (1)
  • src/views/pages/globalping/network.html (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/views/pages/globalping/network.html
⏰ 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: build (24.x)

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 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: 4

🧹 Nitpick comments (2)
src/views/components/location-input.html (1)

58-60: Avoid duplicating overrideValue into value; link instead

overrideValue is always forwarded verbatim to value. Ractive already supports one-way linking:

this.link('overrideValue', 'value', { mode: 'oneWay' });

Using link eliminates the extra state, the observer, and the risk of the two props diverging.

src/views/pages/globalping/network.html (1)

637-643: Duplicate conditional branches—extract helper

setFilterRule now repeats essentially the same branch three times, differing only in the value written. Inlining this many string concatenations makes future maintenance error-prone.

Extract a helper:

const writeLocation = (loc) => this.set('overrideLocation', loc);

Then call writeLocation(...) in each branch to keep logic DRY.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 01599de and 2baf5f5.

📒 Files selected for processing (2)
  • src/views/components/location-input.html (2 hunks)
  • src/views/pages/globalping/network.html (5 hunks)
🧰 Additional context used
🧠 Learnings (2)
src/views/components/location-input.html (2)
Learnt from: xbpcb
PR: jsdelivr/www.jsdelivr.com#775
File: src/views/components/show-more-list.html:40-48
Timestamp: 2025-06-26T16:13:51.058Z
Learning: In the show-more-list component at src/views/components/show-more-list.html, the list property is static and will not be updated dynamically, so observing list changes in the observer is not necessary.
Learnt from: xbpcb
PR: jsdelivr/www.jsdelivr.com#775
File: src/views/components/show-more-list.html:0-0
Timestamp: 2025-06-30T15:52:04.874Z
Learning: In RactiveJS, observers fire immediately by default when they are set up, unless explicitly configured with `{ init: false }` option. This means that when you call `this.observe('property', callback)`, the callback executes immediately with the current value of the property, ensuring proper initialization of dependent data.
src/views/pages/globalping/network.html (1)
Learnt from: PavelKopecky
PR: jsdelivr/www.jsdelivr.com#775
File: src/views/pages/globalping/network-tools.html:147-156
Timestamp: 2025-07-04T14:51:34.927Z
Learning: In the globalping network-tools.html file, the errorMessage variable displayed with triple mustaches {{{errorMessage}}} is safe from XSS because it's completely generated by internal code, not user input or untrusted external sources.
⏰ 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: build (24.x)
🔇 Additional comments (1)
src/views/pages/globalping/network.html (1)

55-56: Conflicting two-way & one-way bindings

Passing both value="{{location}}" (two-way) and overrideValue="{{overrideLocation}}" (one-way) to the same prop set means the component can receive two different truths. When the user types, only location changes; when quick filters fire, only overrideLocation changes. The observer inside the child tries to reconcile them, but the arrangement is fragile and easy to desynchronise.

Consolidate to a single source of truth (either drop value or move quick-filter writes to location).

⛔ Skipped due to learnings
Learnt from: xbpcb
PR: jsdelivr/www.jsdelivr.com#775
File: src/views/components/show-more-list.html:40-48
Timestamp: 2025-06-26T16:13:51.058Z
Learning: In the show-more-list component at src/views/components/show-more-list.html, the list property is static and will not be updated dynamically, so observing list changes in the observer is not necessary.

Comment on lines +629 to +636
this.observe('overrideValue', (value) => {
this.set('value', value);

if (!this.get('rawProbes') || !this.get('exposeProbes')) { return; }

filterProbesByCurrentParts(value);
this.set('completedValue', value);
});
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Observer risks needless churn and re-entrancy

  1. The observer fires immediately on setup, overwriting any value that the component has already normalised.
  2. Each external change bubbles back through the two-way binding, possibly causing an extra (identical) set('value') and a second render.

Guard and defer the update:

-this.observe('overrideValue', (value) => {
-    this.set('value', value);
+this.observe('overrideValue', (value) => {
+    if (value === this.get('value')) { return; }   // short-circuit identical values
+    this.set('value', value);
 }, { init: false });                               // avoid first overwrite

This keeps the DOM stable and prevents double work.

📝 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
this.observe('overrideValue', (value) => {
this.set('value', value);
if (!this.get('rawProbes') || !this.get('exposeProbes')) { return; }
filterProbesByCurrentParts(value);
this.set('completedValue', value);
});
this.observe('overrideValue', (value) => {
if (value === this.get('value')) { return; } // short-circuit identical values
this.set('value', value);
if (!this.get('rawProbes') || !this.get('exposeProbes')) { return; }
filterProbesByCurrentParts(value);
this.set('completedValue', value);
}, { init: false });
🤖 Prompt for AI Agents
In src/views/components/location-input.html around lines 629 to 636, the
observer on 'overrideValue' triggers immediately on setup and causes redundant
updates by setting 'value' repeatedly, leading to unnecessary renders. To fix
this, add a guard to check if the new 'overrideValue' differs from the current
'value' before setting it, and defer the update using a microtask or timeout to
avoid re-entrancy and double rendering. This will stabilize the DOM and prevent
redundant work.

Comment on lines +659 to 660
this.set('overrideLocation', updatedParts.join(','));
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

rmFilterRule leaves location stale

Removing a quick filter writes only overrideLocation. Until the child component propagates back, location (used by updateFiltersSet) contains the old value. Update both simultaneously or switch to a single authoritative field.

🤖 Prompt for AI Agents
In src/views/pages/globalping/network.html at lines 659-660, the rmFilterRule
method updates only overrideLocation but leaves location stale, causing
inconsistency in updateFiltersSet. Modify the code to update both
overrideLocation and location simultaneously with the new value, or refactor to
use a single authoritative field for location data to ensure consistency.

Comment on lines +361 to 363
this.set('overrideLocation', location.replace(/%/g, '+'));
this.set('locationCompletedValue', location.replace(/%/g, '+'));
},
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Indirect update relies on child side-effects

filter.set writes only overrideLocation, expecting the component observer to push the value back into location. If the component is not yet rendered (e.g. during SSR or in tests), location never updates and downstream observers miss the change.

Update both directly to avoid hidden coupling:

 this.set('overrideLocation', newLoc);
 this.set('location', newLoc);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/views/pages/globalping/network.html around lines 361 to 363, the code
updates only 'overrideLocation' and 'locationCompletedValue' but relies on a
component observer to update 'location', which may not run during SSR or tests,
causing missed updates. To fix this, update 'location' directly alongside
'overrideLocation' and 'locationCompletedValue' by setting 'location' explicitly
with the replaced value to avoid indirect coupling and ensure all observers
receive the change.

@MartinKolarik MartinKolarik temporarily deployed to gh-750-quick-filters - globalping.io PR #789 July 8, 2025 15:57 — with Render Destroyed
@jimaek jimaek temporarily deployed to gh-750-quick-filters - www.jsdelivr.com PR #789 July 8, 2025 15:57 — with Render Destroyed
@jimaek
Copy link
Member

jimaek commented Jul 8, 2025

FYI it's still buggy. e.g. the X to remove a filter stops working after a while.

Also I think we should not move the order of quick filters. When clicking on a filter it moves to the front and its confusing as the whole list changes. Just enable them in place.

@MartinKolarik
Copy link
Member

Too complicated and breaks after removing a filter via the X button. Fixed in fd58a44.

@MartinKolarik
Copy link
Member

Also I think we should not move the order of quick filters. When clicking on a filter it moves to the front and its confusing as the whole list changes. Just enable them in place.

It is a bit annoying, but it's how it worked before, and they'd move even if we kept them in place because of the extra "X" that appears when a filter is active.

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.

3 participants