Extract agent session filtered search bar into shared component

What does this MR do and why?

Extracts the filtered search bar, sort listbox, time-range filter, and getFlowTypes Apollo query out of DuoAgentsPlatformIndex and into a new shared component AgentFlowFilteredSearch. No visual or behavioural change; no feature flag.

The motivation is #616493 (closed) (tabbed Duo panel session inbox), which needs to reuse this exact search/sort surface. The extraction makes that a drop-in rather than a copy-paste.

State split: AgentFlowFilteredSearch owns currentSort, currentFilters, timeRangeFilter, flowTypes, and the updatedAfter derivation. It emits search-variables-updated with { sort, filters, updatedAfter } — no pagination key. The index owns pagination, caches the last child payload in searchVariables, and merges before re-emitting query-variables-updated to both namespace hosts unchanged. A filter-then-next-page sequence carries the filter and sort into the pagination request; the index spec has a named regression test for exactly this scenario.

Two declared deviations from a verbatim move:

  1. :initial-sort="initialSort" is dropped from the <filtered-search-bar> call. FilteredSearchBar (filtered_search_bar_root.vue) declares initialSortBy and has no initialSort prop, so the binding fell through to a stray DOM attribute. It is absent after this MR. Measured live: the attribute appears on master and is absent on this branch. The :initial-sort-by binding is real and stays.

  2. getFlowTypes now fires from the child instead of the index. Mount timing is unchanged and the query remains unconditional: hasInitialWorkflows is a prop rather than a parent-level v-if guard, so the query fires even when the bar is hidden on an empty account — identical to today's behaviour.

Both namespace host components (UserAgentsPlatformIndex, ProjectAgentsPlatformIndex) and their specs require no changes. The MSW panel handler stubs getFlowTypes at the network layer and is unaffected by which Vue component issues the query.

References

Screenshots or screen recordings

No visual change. The rendered search bar, sort listbox, and time-range filter are identical before and after. I recorded the duoWorkflowWorkflows GraphQL request variables on this branch and on master for the filter, next-page, sort, and time-range interactions: they match key for key, the only difference being the wall-clock timestamp inside updatedAfter.

One gap worth stating: the Duo side panel surface is not verified. DuoChatPanel::Component#render? returns false on my GDK, so the panel cannot be opened there. It renders the same user-host → index → child chain, and the only panel-specific input is the isSidePanelView inject, which this MR does not touch.

How to set up and validate locally

  1. Sign in as a user who has at least one agent session (the search bar only renders when hasInitialWorkflows is true).
  2. Navigate to any project's agent sessions page, e.g. http://gdk.test:3000/<group>/<project>/-/automate/agent-sessions.
  3. Confirm the filtered search bar renders and the flow-name token dropdown lists real flow names (proves getFlowTypes fires from the new owner).
  4. Filter by a status (e.g. Paused), then click Next page — the request must still carry statusGroup: "PAUSED" and the current sort with only the cursor changing. This is the main regression to guard.
  5. Run the Jest suite:
    yarn jest ee/spec/frontend/ai/duo_agents_platform
    56 suites, 1169 tests, all passing.

As there is no user-facing change, no changelog entry is included.

MR acceptance checklist

  • No visual change — no screenshots required
  • Jest coverage: 56 suites / 1169 tests pass; filter, sort, time-range, and pagination cases all present in migrated or new specs
  • ESLint and Prettier clean on all changed files
  • No new strings — locale/gitlab.pot is unaffected
  • No feature flag — pure structural refactor, zero user-visible change
  • Namespace host specs (user_agents_platform_index_spec.js, project_agents_platform_index_spec.js) unchanged and passing
  • Rebased onto master after !250386 (merged) hyphenated the FilteredSearchBar events: the extracted component listens on @on-filter / @on-sort and needs no vue/v-on-event-hyphenation suppression
Edited by Andrew Fontaine

Merge request reports

Loading
Loading