Repository navigation
feat(rod): make user allocation chips clickable to filter by author - #1647
janzak-dev wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
Code Review
This pull request makes the user allocation chips interactive, allowing users to filter the queue jobs table by clicking on a user's chip and toggle the filter off on a subsequent click. The changes include updating the templates, adding button styles, implementing the click handler logic, and expanding the test coverage and harnesses. The review feedback suggests several improvements: using case-insensitive comparisons for author filtering and highlighting to handle casing mismatches, adding a :focus-visible style to the new buttons for keyboard accessibility, and refining the test harness to use exact string matching instead of startsWith to prevent incorrect prefix matches.
| protected onAuthorChipClick(author: string): void { | ||
| this.onAuthorChange(this.author() === author ? '' : author); | ||
| } |
There was a problem hiding this comment.
To ensure that filtering and toggling behave correctly regardless of casing (e.g., if a user types a mixed-case email in the input field but clicks a lowercase chip), perform a case-insensitive comparison.
| protected onAuthorChipClick(author: string): void { | |
| this.onAuthorChange(this.author() === author ? '' : author); | |
| } | |
| protected onAuthorChipClick(author: string): void { | |
| this.onAuthorChange(this.author().toLowerCase() === author.toLowerCase() ? '' : author); | |
| } |
| [class.selected]="selectedAuthor() === seg.user" | ||
| [attr.aria-pressed]="selectedAuthor() === seg.user" |
There was a problem hiding this comment.
To ensure the selected chip is correctly highlighted even if the user typed the email with different casing in the input field, use case-insensitive comparison.
[class.selected]="selectedAuthor().toLowerCase() === seg.user.toLowerCase()"
[attr.aria-pressed]="selectedAuthor().toLowerCase() === seg.user.toLowerCase()"
| &:hover { | ||
| background-color: #f1f3f4; | ||
| } |
There was a problem hiding this comment.
| private async findUserChip(user: string): Promise<TestElement> { | ||
| for (const btn of await this.chipButtons()) { | ||
| if ((await btn.text()).trim().startsWith(user)) { | ||
| return btn; | ||
| } | ||
| } | ||
| throw new Error(`User chip for ${user} not found`); | ||
| } |
There was a problem hiding this comment.
Using startsWith on the full button text can lead to incorrect matches if one user's email is a prefix of another (e.g., alice@example.com matching alice@example.com.au). Instead, locate the exact user element using the .chip-user class.
| private async findUserChip(user: string): Promise<TestElement> { | |
| for (const btn of await this.chipButtons()) { | |
| if ((await btn.text()).trim().startsWith(user)) { | |
| return btn; | |
| } | |
| } | |
| throw new Error(`User chip for ${user} not found`); | |
| } | |
| private async findUserChip(user: string): Promise<TestElement> { | |
| const users = await this.chipUsers(); | |
| for (let i = 0; i < users.length; i++) { | |
| if ((await users[i].text()).trim() === user) { | |
| return (await this.chipButtons())[i]; | |
| } | |
| } | |
| throw new Error(`User chip for ${user} not found`); | |
| } |
Convert user chips in QueueUserAllocationBar into interactive buttons with selected/aria-pressed states and wire clicks to toggle the QueueJobsTable author filter. TAG=agy CONV=f8f406d7-33e0-4730-8e36-563ae34797bb
TAG=agy CONV=f8f406d7-33e0-4730-8e36-563ae34797bb
TAG=agy CONV=f8f406d7-33e0-4730-8e36-563ae34797bb
77bd9df to
4b8da30
Compare
Summary
Make user chips in the "Who holds
<resource>?" breakdown bar clickable so users can filter theQueueJobsTableby author and toggle/clear the selection on repeat click.Motivation & Context
Allows users inspecting dominant resource allocation per user in the Resource Observability Dashboard (ROD) to click directly on a user chip to isolate that user's jobs in the table below.
Key Changes
li.allocation-chipinqueue_user_allocation_barinto semantic<button type="button" class="allocation-chip">elements with[class.selected],[attr.aria-pressed], and:focus-visiblestates, emittingauthorSelect.(authorSelect)and[selectedAuthor]="author()"inQueueJobsTablewithonAuthorChipClicktoggle logic; inheritsisRefreshing+<xmc-loading-bar [isRefreshing]="true" />from PR feat(rod): sort queue jobs server-side before pagination #1645/feat(rod): filter queue jobs server-side before pagination #1646 so clicking a chip keeps<xmc-queue-user-allocation-bar>and<table mat-table matSort>mounted.docs/flows/metrics_and_observability.md, addedclickUserChip/isUserChipSelected(matching exact.chip-usertext) toQueueUserAllocationBarHarness, and added unit tests inqueue_user_allocation_bar_test.tsandqueue_jobs_table_test.ts.Assumptions
this.author() === author ? '' : author) — provides quick one-click return to the unfiltered queue without moving to Clear filters — Impact if wrong: making chip clicks idempotent (onAuthorChange(author)only) is a one-line change inonAuthorChipClick.selectedAuthor() === seg.user) for chip highlight — highlights the chip only whenauthormatches the full chip user identifier — Impact if wrong: substring or case-insensitive highlight would require normalizing/matching againstseg.user.statusfilter — allows combining a user chip click with the Status dropdown — Impact if wrong: clearingstatuson chip click is a one-line change inonAuthorChipClick.Verification & Testing
bazel test //cmd/ui:ui_unit_tests(PASSED)cd cmd/ui && npm run build && npm run test:screenshot(11/11 Playwright screenshot tests PASSED)./.githooks/pre-commit(PASSED on docs commit)Related Issues / Bugs
Part of #1514
TAG=agy
CONV=f8f406d7-33e0-4730-8e36-563ae34797bb