Add an advanced filter panel to the jobs view - #9787
Open
camd wants to merge 29 commits into
Open
Conversation
✅ Deploy Preview for treeherder ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #9787 +/- ##
===========================================
+ Coverage 69.15% 83.56% +14.40%
===========================================
Files 637 648 +11
Lines 38505 38830 +325
Branches 3466 3543 +77
===========================================
+ Hits 26630 32447 +5817
+ Misses 11481 5986 -5495
- Partials 394 397 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
camd
force-pushed
the
camd/advanced-filter-panel
branch
from
August 22, 2026 17:24
c5be746 to
20a9e46
Compare
- PrimaryNavBar's memo comparator now compares isFilterPanelOpen and classificationTypes so the panel can actually open in the app. - SecondaryNavBar ignores Overlay rootClose events that originate on the trigger button, so the trigger toggles open/closed instead of the two handlers canceling each other out. - AdvancedFilterPanel moves focus into the popover when it opens and restores focus to the trigger when it closes. - Advanced-filter badge uses Bootstrap 5 classes; trigger button gets aria-controls/aria-haspopup; PresetsSection falls back to thDefaultRepo; FieldFilterSection's remove button gets a matching aria-label. - Adds regression tests for the memo/re-render bug and the trigger open/close toggle bug.
The panel now renders full-width between the navbars and the push list, so opening it pushes the pushes down instead of overlaying them. The job view root becomes a flex column so the banner takes natural height and the push-list/details panels split the remainder. Sections flow left-to-right across the banner and wrap on narrow viewports, with Presets moved to the end of the row so it sits at the right edge of the window. Escape closes the banner; outside clicks no longer do, since it is persistent chrome rather than a transient popover.
Holding more than that can crash the browser. fetchPushes now refuses to fetch past the cap (with a notification pointing at the filter panel), and caps each request's count to the remaining capacity. Polling stops pulling in new pushes at the cap but keeps fetching jobs for the pushes already loaded. As a safety net, addPushes truncates to the newest 500 in case a response overshoots the remaining capacity. PushModel.getList now respects an explicit caller count on range queries instead of silently bumping it to the per-request maximum, and clamps any count to that maximum.
The Active Filters bar now renders between the navbars and the Advanced Filters banner instead of inside the push-list panel, and the banner header uses the same alert-info light blue as the Active Filters bar so the two read as one group. The header's Clear all and close controls switch to dark-on-light styling to stay legible.
Use a darker shade of the Active Filters alert-info blue as the background of the whole banner (header and the area behind the section cards) rather than matching it exactly, add a border between the Active Filters bar and the banner, and center the Advanced Filters title at the same 14px size as the Active Filters title with the Clear all / close controls pinned to the right edge.
The server orders pushes newest-first before applying count, so a range query (startdate/fromchange) now requests the full remaining capacity in a single call instead of 100 at a time: for a range of 2 to 10 days ago it loads the 500 pushes closest to the 2-days-ago end, or the whole range when it holds fewer. getList's clamp rises from the old per-request maximum to the overall push ceiling; the API itself caps counts at 1000.
Loading a wide push range (up to the 500-push cap) surfaced three problems: - Every Push component fired its jobs fetch on mount, so 500 mounted at once meant 500 concurrent API requests (502s from the server) and a burst of resolutions whose setState cascade tripped React's 'Maximum update depth exceeded' guard. A shared task limiter now runs at most 6 per-push jobs fetches at a time. - Each completed jobs fetch recalculated the store-wide unclassified counts, re-rendering every subscribed component per push. The recalculation is now debounced to coalesce bursts. - Polling fetched new jobs with one request listing every loaded push id; past ~440 ids the encoded query string exceeded the server's 4kB request-line limit (400 Bad Request). The ids are now chunked 100 per request.
…nding pill The Active Filters bar already shows which filters are set, so the count badge on the toolbar trigger is redundant; remove it along with the now-unused getActiveFilterCount helper. Give the banner header a min-height so the absolutely-centered Clear all button clears the top edge instead of touching it. Darken the result-status pending pill's outline color — the real pending gray is too faint on a white card — while keeping it lighter than running.
camd
force-pushed
the
camd/advanced-filter-panel
branch
from
August 22, 2026 17:24
20a9e46 to
e89c0b5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this adds
An Advanced Filters popover for the jobs view that brings every filter dimension into one place. It replaces the old one-field-at-a-time filter form that appeared under the secondary toolbar (that inline form is removed; the active-filter chips bar remains).
The panel is opened from a new sliders icon attached to the left edge of the "Filter platforms & jobs" quick-filter box, from Filters → Advanced Filters… in the top nav, or with the shift+f keyboard shortcut (documented in the
?shortcut overlay). The trigger shows a count badge when any non-default filters are active.Panel contents (top to bottom)
<datalist>typeahead sourced from the currently loaded jobs.failures/in progressgroup shortcuts. Pills use the same status colors as the toolbar chicklets (shared CSS tokens): filled when active, outlined when off.Everything "live" reads and writes through the existing
FilterModel, so the URL stays the single source of truth and the panel can never disagree with the toolbar chicklets, tier menu, or chips bar. Only the push-range section holds local state, and only until Apply.Discoverability
shift+fcompletes the existing family:ffocuses the quick filter,ctrl+shift+fclears it.Implementation notes
ui/job-view/headerbars/filter-panel/; the popover is a react-bootstrapOverlay/PopoverwithrootClose(outside click / Esc closes), focus moved into the panel on open and restored to the trigger on close.isFieldFilterVisibleplumbing throughApp→PrimaryNavBarwas repurposed asisFilterPanelOpen/toggleFilterPanelso both the trigger and the hotkey share one source of truth. ThePrimaryNavBarReact.memocomparator gained the new props (a miss there made the panel unopenable — now covered by a regression test through the memoized export).ActiveFiltersis chips-only now;startdate/enddateURL params (already supported by the fetch layer) finally have a UI.:roottokens used by both the toolbar chicklets and the panel pills.Testing
Follow-ups (out of scope here)
fromchange/tochangehave no panel UI yet (they still count toward the badge and clear with Clear all).