Skip to content

[Discover] Persist query mode to local storage#250388

Merged
AlexGPlay merged 20 commits intoelastic:mainfrom
AlexGPlay:200765-persist-esql-or-classic-mode-to-localstorage
Feb 9, 2026
Merged

[Discover] Persist query mode to local storage#250388
AlexGPlay merged 20 commits intoelastic:mainfrom
AlexGPlay:200765-persist-esql-or-classic-mode-to-localstorage

Conversation

@AlexGPlay
Copy link
Copy Markdown
Contributor

@AlexGPlay AlexGPlay commented Jan 26, 2026

Summary

Closes #200765

When changing between classic and ES|QL mode we persist it in local storage so the next default session uses that preference.


Before (Example with ESQL)

before.default.query.mov

After (Example with ESQL)

after.default.query.mov

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.

@AlexGPlay AlexGPlay changed the title Persist query mode to local storage [Discover] Persist query mode to local storage Jan 26, 2026
@AlexGPlay AlexGPlay self-assigned this Jan 28, 2026
@AlexGPlay AlexGPlay added release_note:enhancement backport:skip This PR does not require backporting Team:DataDiscovery Discover, search (data plugin and KQL), data views, saved searches. For ES|QL, use Team:ES|QL. t// labels Jan 28, 2026
@AlexGPlay AlexGPlay marked this pull request as ready for review January 28, 2026 14:05
@AlexGPlay AlexGPlay requested review from a team as code owners January 28, 2026 14:05
@elasticmachine
Copy link
Copy Markdown
Contributor

Pinging @elastic/kibana-data-discovery (Team:DataDiscovery)

@kertal kertal added the Feature:Discover Discover Application label Jan 28, 2026
@davismcphee
Copy link
Copy Markdown
Contributor

@jughosta could you please take the review on this one?

@davismcphee davismcphee requested a review from jughosta January 30, 2026 03:44
} else {
dispatch(transitionFromESQLToDataView({ dataViewId: currentDataView?.id ?? '' }));
}
services.storage.set(DISCOVER_QUERY_MODE_KEY, 'classic');
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.

I would suggest to clear the previously saved value then so when we continue with #250038 it would not interfere.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

do you mean to instead of save which of the modes was the last one we just store if the last one was ESQL? i guess the problem then is going to be that once ESQL is the default in #250201 if someone switches back to classic it won't use it as the next default

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.

Okay, good point! Then we just need to keep in mind that if users had switched to classic before we enabled ES|QL by default then they will continue using the classic mode without noticing the change in Discover cc @kertal

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

thx for raising, yes, also didn't think about this. so it makes sense, to store it with classic, but I think further down the road, we might think of solving it differently, because as @jughosta highlighted, one we generally enable ES|QL as default, those users still would see classic ... worth a comment in the code, so it doesn't get lost

Comment thread src/platform/test/functional/apps/discover/query_mode/_update_query_mode.ts Outdated
) {
dispatch(internalStateActions.setIsESQLToDataViewTransitionModalVisible(true));
} else {
dispatch(transitionFromESQLToDataView({ dataViewId: currentDataView?.id ?? '' }));
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.

Since the transition modal to Classic can be dismissed, the value should not change to classic in this case.

Screenshot 2026-02-03 at 13 36 29

Then a single place in the code, where to move services.storage.set(DISCOVER_QUERY_MODE_KEY, 'classic'); to, might be inside transitionFromESQLToDataView action. Or better as a redux listener to the action.

For consistency we could apply a similar change to transitionFromESQLToDataView.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

that makes sense, i thought of that at first but i wasn't sure if we wanted to introduce a side-effect in the redux actions

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

updated to redux listener in 5a4c68b - it seems to be working but it's my first time doing one redux listener so I hope it's the way it should be

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.

I meant listeners for transitionFromESQLToDataView and transitionFromDataViewToESQL actions. We still want to capture only the manual changes to the mode.

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.

Thanks for looking into it!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i think i got it now a135bf0 🙈

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.

i wasn't sure if we wanted to introduce a side-effect in the redux actions

Just wanted to say this is totally fine to do in thunks and middleware, often preferable even. It keeps the logic consolidated and makes it easy to test.

Personally in your case I'd put the logic directly in the thunk to avoid the extra actions indirection, but middleware works too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i'm happy with either, i've seen now that i can access the storage in the thunks - no strong opinion from my side

@AlexGPlay AlexGPlay requested a review from jughosta February 5, 2026 07:21
Copy link
Copy Markdown
Contributor

@jughosta jughosta left a comment

Choose a reason for hiding this comment

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

Works well and LGTM 👍
Sorry for the delay!

await common.navigateToApp('discover', { path: '' });
await testSubjects.existOrFail('discover-dataView-switch-link');
});
});
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.

Would be nice to also add a test when the path is not empty.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i think the unit tests are kind of covering this scenario, but i can follow up in the feature flag PR with more tests if it doesn't look that way

@elasticmachine
Copy link
Copy Markdown
Contributor

💚 Build Succeeded

Metrics [docs]

Async chunks

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

id before after diff
discover 1.6MB 1.6MB +953.0B

Page load bundle

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

id before after diff
discover 25.1KB 25.2KB +39.0B

History

cc @AlexGPlay

@AlexGPlay AlexGPlay merged commit 35f1f24 into elastic:main Feb 9, 2026
16 checks passed
Dosant pushed a commit to Dosant/kibana that referenced this pull request Feb 9, 2026
## Summary

Closes elastic#200765

When changing between classic and ES|QL mode we persist it in local
storage so the next default session uses that preference.

---

Before (Example with ESQL)


https://github.com/user-attachments/assets/a689c0f9-ff69-4bcb-a8da-108d4693cb56



After (Example with ESQL)


https://github.com/user-attachments/assets/bebc03db-a860-4ec9-9843-5e1f0e53f585




### 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.
AlexGPlay added a commit that referenced this pull request Feb 10, 2026
)

## Summary

Closes #250201

Follow up to #250388 - now on top
of storing the last used query mode, if there's nothing stored as the
last one, and if possible, ES|QL will be the default when the
`isEsqlDefault` feature flag is set to true.

> [!TIP]
> To test it set `feature_flags.overrides.discover.isEsqlDefault` to
true in your `kibana.dev.yml`

### 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 Feature:Discover Discover Application release_note:enhancement Team:DataDiscovery Discover, search (data plugin and KQL), data views, saved searches. For ES|QL, use Team:ES|QL. t// v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Discover] Persist local storage when user selects ES|QL or Classic Mode

7 participants