Skip to content

[UII] Save agent list table state using session storage#228875

Merged
jen-huang merged 12 commits intoelastic:mainfrom
jen-huang:spacetime/save-table-state
Nov 7, 2025
Merged

[UII] Save agent list table state using session storage#228875
jen-huang merged 12 commits intoelastic:mainfrom
jen-huang:spacetime/save-table-state

Conversation

@jen-huang
Copy link
Contributor

@jen-huang jen-huang commented Jul 21, 2025

Summary

Resolves https://github.com/elastic/ingest-dev/issues/5213.

This PR makes Fleet's agent list table state be saved using session storage. The state of the table includes:

  • Pagination (rows per page and page #)
  • Sort field and direction
  • Text search bar
  • All other filters (status, tags, agent policy, has upgrade)

Using session storage means that this state will be saved within a window/tab session. Saving the state this way suffices to manage agents without losing context and clears up the state for new tabs/sessions.

When some state is declared using URL query params (i.e. &kuery= and &showInactive=), the session storage state is overridden with defaults plus state from query params. This is so that referral pages that apply filters (like from Agent policy > click into count of Unprivileged agents) do not run into unexpected filtering from the user's session storage.

Because the filter state is now persistent, I changed Clear filters button to Reset filters and updated the behavior accordingly: clicking it resets back to initial filter state rather than clearing every filter (i.e. clicking it resets back to 5 active agent statuses, rather than clearing all statuses which causes inactive agents to be shown).

Testing

I recommend using node scripts/create_agents (from Fleet directory) to create large number of agents and playing around with filtering the list UI and navigating between pages.

Release note

Fleet agent list table now persists state of filters while navigating within a session.

To-do

  • Make this behave nicely with kuery & other URL query params

Checklist

Check the PR satisfies following conditions.

Reviewers should verify this PR satisfies this list as well.

  • Unit or functional tests were updated or added to match the most common scenarios
  • The PR description includes the appropriate Release Notes section, and the correct release_note:* label is applied per the guidelines
  • Review the backport guidelines and apply applicable backport:* labels.
@jen-huang jen-huang self-assigned this Jul 21, 2025
@jen-huang jen-huang changed the title [WIP][UII] Save agent list table state using session storage Jul 31, 2025
@jen-huang jen-huang marked this pull request as ready for review July 31, 2025 19:55
@jen-huang jen-huang requested a review from a team as a code owner July 31, 2025 19:55
setInactiveAgentsCalloutHasBeenDismissed: (val: boolean) => void;
}> = ({ children, isOpen, setInactiveAgentsCalloutHasBeenDismissed }) => (
<EuiTourStep
title={
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this tour looked weird without a title (a lot of blank space on top of the popover), so I added one

@botelastic botelastic bot added the Team:Fleet Team label for Observability Data Collection Fleet team label Jul 31, 2025
@elasticmachine
Copy link
Contributor

Pinging @elastic/fleet (Team:Fleet)

agentPolicies={agentPolicies}
/>
<EuiFilterButton
isToggle
Copy link
Contributor Author

Choose a reason for hiding this comment

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

upgradable filter button previously didn't have a clear "active" state

@jen-huang jen-huang added release_note:skip Skip the PR/issue when compiling release notes backport:skip This PR does not require backporting labels Jul 31, 2025
Copy link
Contributor

@MichelLosier MichelLosier left a comment

Choose a reason for hiding this comment

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

This looks and works great, really nice to be able to go deep and come back to my original search context.

One thing to consider, if navigating back to the agents list from another view and I had a kuery param, which is also persisted in the url, it would be nice to have that repopulate so its in a shareable state when it first loads. Otherwise if I add another filter it shows back up as expected.

@jen-huang jen-huang marked this pull request as draft November 3, 2025 20:05
@jen-huang jen-huang added release_note:enhancement backport:version Backport to applied version labels v9.3.0 and removed release_note:skip Skip the PR/issue when compiling release notes backport:skip This PR does not require backporting labels Nov 5, 2025
@jen-huang jen-huang marked this pull request as ready for review November 5, 2025 21:38
@jen-huang
Copy link
Contributor Author

jen-huang commented Nov 5, 2025

@MichelLosier Thanks for the review! (months ago.. 😄) Finally got back to cleaning up this PR. I adjusted it based on your review and also added these changes:

Because the filter state is now persistent, I changed Clear filters button to Reset filters and updated the behavior accordingly: clicking it resets back to initial filter state rather than clearing every filter (i.e. clicking it resets back to 5 active agent statuses, rather than clearing all statuses which causes inactive agents to be shown).

Do you mind giving this PR another test?

Copy link
Contributor

@MichelLosier MichelLosier left a comment

Choose a reason for hiding this comment

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

LGTM thanks for following up with that improvement!

} = sessionState;

// If URL params are used, reset the table state to defaults with the param options
useEffect(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: There maybe opportunity here to separate out into its own hook the search session state, with url syncing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

agreed, I started a refactor to pull this out but ran into issues. didn't have confidence I could finish it & test thoroughly before leave 😅 so merged as-is

@jen-huang jen-huang enabled auto-merge (squash) November 7, 2025 19:17
@jen-huang jen-huang merged commit 96ffcd7 into elastic:main Nov 7, 2025
12 checks passed
@kibanamachine kibanamachine added backport:skip This PR does not require backporting and removed backport:version Backport to applied version labels labels Nov 7, 2025
@elasticmachine
Copy link
Contributor

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
fleet 1368 1369 +1

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
fleet 2.1MB 2.1MB +1.7KB

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
fleet 176.6KB 176.6KB +79.0B
Unknown metric groups

ESLint disabled line counts

id before after diff
fleet 45 46 +1

Total ESLint disabled count

id before after diff
fleet 57 58 +1

History

cc @jen-huang

eokoneyo pushed a commit to eokoneyo/kibana that referenced this pull request Dec 2, 2025
## Summary

Resolves elastic/ingest-dev#5213.

This PR makes Fleet's agent list table state be saved using session
storage. The state of the table includes:
- Pagination (rows per page and page #)
- Sort field and direction
- Text search bar
- All other filters (status, tags, agent policy, has upgrade)

Using session storage means that this state will be saved _within_ a
window/tab session. Saving the state this way suffices to manage agents
without losing context and clears up the state for new tabs/sessions.

When some state is declared using URL query params (i.e. `&kuery=` and
`&showInactive=`), the session storage state is overridden with defaults
*plus* state from query params. This is so that referral pages that
apply filters (like from Agent policy > click into count of Unprivileged
agents) do not run into unexpected filtering from the user's session
storage.

Because the filter state is now persistent, I changed `Clear filters`
button to `Reset filters` and updated the behavior accordingly: clicking
it resets back to initial filter state rather than clearing every filter
(i.e. clicking it resets back to 5 active agent statuses, rather than
clearing all statuses which causes inactive agents to be shown).

## Testing
I recommend using `node scripts/create_agents` (from Fleet directory) to
create large number of agents and playing around with filtering the list
UI and navigating between pages.

## Release note
Fleet agent list table now persists state of filters while navigating
within a session.

## To-do
- [x] Make this behave nicely with kuery & other URL query params

### Checklist

Check the PR satisfies following conditions. 

Reviewers should verify this PR satisfies this list as well.

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
- [x] Review the [backport
guidelines](https://docs.google.com/document/d/1VyN5k91e5OVumlc0Gb9RPa3h1ewuPE705nRtioPiTvY/edit?usp=sharing)
and apply applicable `backport:*` labels.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting release_note:enhancement Team:Fleet Team label for Observability Data Collection Fleet team v9.3.0

4 participants