Skip to content

fix: make the workflow job selector show and switch the right job - #760

Open
blaipr wants to merge 2 commits into
ctrliq:mainfrom
blaipr:fix/workflow-job-selector
Open

fix: make the workflow job selector show and switch the right job#760
blaipr wants to merge 2 commits into
ctrliq:mainfrom
blaipr:fix/workflow-job-selector

Conversation

@blaipr

@blaipr blaipr commented Aug 26, 2026

Copy link
Copy Markdown
Contributor
SUMMARY

Fixes the workflow job selector in the job tab bar. Closes #742.

The report is two symptoms, and they turned out to have three separate causes, only one of them in the selector's own code.

The counter was the literal 1. WorkflowOutputNavigation rendered t`Workflow Job 1/${relevantResults.length}` , and relevantResults filtered out the job you were looking at, so the total was short by one too. A four task workflow read 1/3 on every one of its tasks. It now counts every node that ran a job, the current one included, and reports where in that list the job on screen sits.

Picking a task did nothing, and that is not a bug in the selector. The selector is registered in Job.js as a tab with link: undefined, so that it can sit in the tab bar:

tabsArray.push({
  name: <WorkflowOutputNavigation parentRef={ref} relatedJobs={relatedJobs} />,
  link: undefined,
  id: 2,
  hasstyle: 'margin-left: auto',
});

A click inside it bubbles up to the PatternFly tab, RoutedTabs.handleTabSelect matched tab id 2, and ran navigate(undefined). That resolves to the current url, so it landed you back where you were and undid the navigation the selector had just performed. RoutedTabs now leaves a tab with no link alone.

href={!tab.hasstyle && #${tab.link}} is false for that tab, and React rejects false as an href value. It was logging Received 'false' for a non-boolean attribute 'href' on every job page.

Two more came out of writing the tests:

  • With a status filter applied, the toggle rendered a Label with onClose, which is a close <button> inside the toggle's own <button>. Invalid HTML, and that close button was unclickable for the same bubbling reason. The filter is cleared by picking the same status again.
  • The menu seeded useState from the first render, so after moving between jobs it still offered the list belonging to the page you came from.

ad_hoc_command was also missing from the type to url-segment map, which would have built /jobs/undefined/<id>/output for an ad hoc command node.

ISSUE TYPE
  • Bug, Docs Fix or other nominal change
COMPONENT NAME
  • UI
ASCENDER VERSION
25.5.1
ADDITIONAL INFORMATION

On the tests. The existing WorkflowOutputNavigation.test.js mocked out the component under test and asserted against the mock, so it exercised none of this code and passed throughout. It is replaced by twelve tests against the real component, plus two on RoutedTabs for tabs that host a control.

Worth knowing for review: jsdom passes the navigation case that a real browser fails. The bug lives in event bubbling through nested buttons, which jsdom does not model faithfully, so the jest test for "picking a job navigates" went green against the broken code. I only found the real cause by driving a headless browser against a running instance. That is the argument for end-to-end coverage, raised in #761 and built in #762, whose regression specs are cover for exactly this bug: they fail five ways against this branch's parent and pass once it lands.

Verified against a running instance, workflow job 951, four job nodes:

counter on job 952: "Workflow Job 1/4"
counter on job 953: "Workflow Job 2/4"
counter on job 954: "Workflow Job 3/4"
counter on job 955: "Workflow Job 4/4"
navigate 1 -> node3:            #/jobs/playbook/954/output
counter follows:                "Workflow Job 3/4"
navigate again without reload:  #/jobs/playbook/953/output
filter chip shown, all 4 still listed under Successful
console errors during interaction: none

RoutedTabs is used by 46 screens, so tab navigation was checked in the browser too, and none of it changes:

PASS  job: Output -> Details          PASS  workflow job: Output -> Details
PASS  job: Details -> Output          PASS  workflow job: Details -> Output
PASS  templates list loads            PASS  job: Back to Jobs (persistentFilterKey path)

Full UI suite after the change:

npm --prefix awx/ui run test -- --watchAll=false
  Test Suites: 552 passed, 552 total
  Tests:       2949 passed, 2949 total

npm --prefix awx/ui run lint
  clean

Not fixed here, and worth a follow-up. Rendering a control inside a tab's <button> is invalid HTML whatever else is done, and it is the reason these clicks misbehaved in the first place. Only Job.js does it, one hasstyle usage in the whole tree, so moving that control out of the tab list would remove the whole class rather than guarding each symptom. I kept this change to the reported bug.

The selector in the job tab bar always read "Workflow Job 1/X", whatever
task you were on, and picking another task did nothing.

Closes ctrliq#742.

Three separate defects, only the first of which was in the selector's own
counter:

- The position was the literal 1, and the list it counted excluded the job
  on screen, so a four task workflow read 1/3 on every one of its tasks.
  Count every node that ran a job, the current one included, and report
  where in that list the job on screen sits.

- Picking a task did nothing because the selector is registered in Job.js
  as a tab with no link, so that it sits in the tab bar. The click bubbles
  to the PatternFly tab, and RoutedTabs called navigate(undefined) for it,
  landing back on the current url and undoing the navigation the selector
  had just performed. RoutedTabs now leaves link-less tabs alone.

- RoutedTabs passed href={!tab.hasstyle && `#${tab.link}`}, which is the
  boolean false for exactly that tab. React rejects false as an href.

Two more found while testing the above:

- With a status filter applied, the toggle rendered a Label with a close
  button inside the toggle's own button. Nested buttons are invalid, and
  that close button was unclickable for the same bubbling reason. The
  filter is cleared by picking the same status again.

- The menu seeded useState from the first render, so after moving between
  jobs it still offered the list belonging to the page you came from. The
  list is derived now.

The old component test mocked out the component under test and asserted
against the mock, which is why none of this was caught. It is replaced by
twelve tests against the real component, plus two on RoutedTabs covering
tabs that host a control.
@blaipr
blaipr force-pushed the fix/workflow-job-selector branch from 129812b to fd7f92d Compare August 26, 2026 20:40
The selector's label changed, so its message id changed with it, and a
production build renders an id it has no catalog entry for. The tab read
"-t1kzb" rather than "Workflow Job 2/4" until the catalogs were extracted
again. The jest suite does not see this, and neither does the development
server, which compiles catalogs on the way up; only a built UI shows it.

The two new messages are named rather than positional,
"Workflow Job {currentPosition}/{total}" instead of leaving translators a
bare {0}.

Extraction also picks up three messages that were already in the source
and missing from the catalogs, and refreshes the source line references
throughout, which is what makes the diff large. The Spanish, French and
other translations of the old "Workflow Job 1/{0}" are dropped, as they
have to be: that string no longer exists.
@cigamit
cigamit requested a lite review from Copilot August 27, 2026 02:55
@cigamit cigamit self-assigned this Aug 27, 2026
@cigamit cigamit added the bug Something isn't working label Aug 27, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes the “workflow job selector” control shown in the Job output tab bar so it (a) reports the correct position/total for the workflow job nodes, (b) correctly navigates when selecting a different node, and (c) stops generating console errors caused by invalid href values / link-less tabs triggering navigate(undefined). It does so by correcting the selector’s node counting and selection model, and by hardening RoutedTabs to treat tabs with no link as non-navigational (so embedded controls don’t get overridden by tab selection).

Changes:

  • Fix WorkflowOutputNavigation to count all navigable workflow job nodes (including the current one), compute the correct on-screen position, and navigate using a stable node identifier/value rather than label text.
  • Update RoutedTabs to ignore selection of tabs that have no link, and avoid passing invalid href values.
  • Replace the previous mocked selector test with a comprehensive set of real component tests; add coverage for the new RoutedTabs behavior.

Reviewed changes

Copilot reviewed 4 out of 22 changed files in this pull request and generated no comments.

Show a summary per file
File Description
awx/ui/src/locales/en/messages.js Updates extracted/en locale messages to include the new/updated selector strings.
awx/ui/src/components/WorkflowOutputNavigation/WorkflowOutputNavigation.js Corrects workflow node counting/positioning, selection handling, filtering behavior, and URL construction.
awx/ui/src/components/WorkflowOutputNavigation/WorkflowOutputNavigation.test.js Replaces mock-based tests with real behavioral tests covering counting, navigation, filtering, and selection state.
awx/ui/src/components/RoutedTabs/RoutedTabs.js Prevents navigate(undefined) by treating link-less tabs as non-navigational; fixes href to never be false.
awx/ui/src/components/RoutedTabs/RoutedTabs.test.js Adds regression tests ensuring link-less “control tabs” don’t navigate while normal tabs still do.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@cigamit

cigamit commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Seems to be a linter issue. The other 2 failures weren't caused by this PR, but some earlier ones.

The only other thing I notice is that when selecting a filter (click failed) the menu shrinks to the size of the input box, which itself shrunk. This makes some of the text truncate off the screen. We should probably set that input box to minimum width.

image

@cigamit cigamit added the Needs triage When a Issue needs to be researched or a PR has an issue that needs fixing before merging label Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working Needs triage When a Issue needs to be researched or a PR has an issue that needs fixing before merging

Development

Successfully merging this pull request may close these issues.

Unable to switch different workflow task using upperright workflow-task-selector

3 participants