G
YouTube TikTok Games
Skip to content

feat(rod): make user allocation chips clickable to filter by author - #1647

Draft
janzak-dev wants to merge 4 commits into
feat/rod-queue-jobs-filteringfrom
feat/rod-clickable-author-chips
Draft

janzak-dev wants to merge 4 commits into
feat/rod-queue-jobs-filteringfrom
feat/rod-clickable-author-chips

Conversation

@janzak-dev

@janzak-dev janzak-dev commented Nov 12, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Make user chips in the "Who holds <resource>?" breakdown bar clickable so users can filter the QueueJobsTable by 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

  • Interactive User Chips: Converted li.allocation-chip in queue_user_allocation_bar into semantic <button type="button" class="allocation-chip"> elements with [class.selected], [attr.aria-pressed], and :focus-visible states, emitting authorSelect.
  • Table Integration & Non-Teardown Refresh: Wired (authorSelect) and [selectedAuthor]="author()" in QueueJobsTable with onAuthorChipClick toggle logic; inherits isRefreshing + <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, Tests & Harnesses: Documented chip-click filtering in docs/flows/metrics_and_observability.md, added clickUserChip / isUserChipSelected (matching exact .chip-user text) to QueueUserAllocationBarHarness, and added unit tests in queue_user_allocation_bar_test.ts and queue_jobs_table_test.ts.

Assumptions

  • Repeat-click toggles off the author filter (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 in onAuthorChipClick.
  • Exact string match (selectedAuthor() === seg.user) for chip highlight — highlights the chip only when author matches the full chip user identifier — Impact if wrong: substring or case-insensitive highlight would require normalizing/matching against seg.user.
  • Clicking a user chip preserves any active status filter — allows combining a user chip click with the Status dropdown — Impact if wrong: clearing status on chip click is a one-line change in onAuthorChipClick.

Verification & Testing

  • Commands Executed:
    • 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

@janzak-dev
janzak-dev added this pull request to stack #1648 November 12, 2026 10:44

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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.

Comment on lines +204 to +206
protected onAuthorChipClick(author: string): void {
this.onAuthorChange(this.author() === author ? '' : author);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

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.

Suggested change
protected onAuthorChipClick(author: string): void {
this.onAuthorChange(this.author() === author ? '' : author);
}
protected onAuthorChipClick(author: string): void {
this.onAuthorChange(this.author().toLowerCase() === author.toLowerCase() ? '' : author);
}

Comment on lines +49 to +50
[class.selected]="selectedAuthor() === seg.user"
[attr.aria-pressed]="selectedAuthor() === seg.user"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

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()"

Comment on lines +88 to +90
&:hover {
background-color: #f1f3f4;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Since the allocation chips have been converted from static list items to interactive buttons, they should have a visible focus indicator to ensure keyboard accessibility (a11y).

  &:hover {
    background-color: #f1f3f4;
  }

  &:focus-visible {
    outline: 2px solid #1a73e8;
    outline-offset: 2px;
  }

Comment on lines +77 to +84
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`);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

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.

Suggested change
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`);
}

@janzak-dev
janzak-dev removed this pull request from stack #1648 November 12, 2026 12:07
@janzak-dev
janzak-dev added this pull request to stack #1649 November 12, 2026 12:07
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
@janzak-dev
janzak-dev force-pushed the feat/rod-clickable-author-chips branch from 77bd9df to 4b8da30 Compare November 12, 2026 13:04

This branch has not been deployed

No deployments
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.

1 participant