Skip to content

[Controls] Remove availableOptions from ES|QL values from query saved object#231690

Merged
Zacqary merged 12 commits intoelastic:mainfrom
Zacqary:231668-esql-remove-availableoptions
Aug 25, 2025
Merged

[Controls] Remove availableOptions from ES|QL values from query saved object#231690
Zacqary merged 12 commits intoelastic:mainfrom
Zacqary:231668-esql-remove-availableoptions

Conversation

@Zacqary
Copy link
Contributor

@Zacqary Zacqary commented Aug 13, 2025

Summary

Closes #231668

For VALUES_FROM_QUERY ES|QL controls, omit the availableOptions property from the control state before saving, from both the control editor and the dashboard. These controls always fetch their availableOptions on page load and dashboard refresh, and when the list is extremely long, saving it in a saved object has been causing serious performance issues for some users.

STATIC_VALUES controls are unaffected, and still save their availableOptions in the control state.

@Zacqary Zacqary requested review from a team as code owners August 13, 2025 19:07
@Zacqary Zacqary added release_note:fix Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas t// loe:small Small Level of Effort impact:critical This issue should be addressed immediately due to a critical level of impact on the product. Project:Controls Team:ESQL ES|QL related features in Kibana t// backport:version Backport to applied version labels v9.2.0 v9.1.3 v8.19.3 labels Aug 13, 2025
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-presentation (Team:Presentation)

@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-esql (Team:ESQL)

@Zacqary Zacqary enabled auto-merge (squash) August 13, 2025 19:07
Copy link
Contributor

@stratoula stratoula 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 good! Thanx for tackling this Zac

width?: ControlWidthOptions;
title: string;
availableOptions: string[];
availableOptions?: string[];
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a comment here mentioning the case that this is optional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure thing. At first I was hoping to make this more self-documenting by splitting this into type ESQLControlState = StaticESQLControlState | ValuesESQLControlState but then I would've had to put new complicated typeguards in a ton of places. Maybe some good tech debt to tackle later but in the interest of keeping this PR small and quick I didn't want to go through all that right now.

...selections.getLatestState(),
};

const rawState =
Copy link
Contributor

Choose a reason for hiding this comment

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

Can this logic be moved into selections.getLatestState?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No, the availableOptions state is still needed internally in order to display the list of available options. We just want to omit it before serializing, so that it's not saved.

The test logic in get_esql_control_factory.test.tsx documents how this is expected to work.

Copy link
Contributor

Choose a reason for hiding this comment

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

No, the availableOptions state is still needed internally in order to display the list of available options

availabeOptions is published with availableOptions$. Selections manager should expose availableOptions$ if availabeOptions are needed outside of the selection manager. selections.getLatestState() should not include availabeOptions if they are discarded during serialization

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're right, it actually does still work if I do this at the getLatestState level. Doesn't require any refactoring. Pushing a fix

});
});

test('should load availableOptions but not serialize them', async () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

How about moving this test to src/platform/plugins/shared/controls/public/controls/esql_control/esql_control_selections.test.ts since initializeESQLControlSelections is responsible for managing this subscription.

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 is more of an integration test. The component always uses the availableOptions state internally to render the list of available options in the UI regardless of whether it's a Values From Query or Static Values control. We only want to serialize and save it for Static Values control types, and only fetch at runtime for Values From Query.

This does make it a bit confusing, but since this is a high-priority fix and we're planning on cleaning up this logic with the Data/ESQL control factory unification, I opted not to refactor here.

Copy link
Contributor

Choose a reason for hiding this comment

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

This does make it a bit confusing, but since this is a high-priority fix and we're planning on cleaning up this logic with the Data/ESQL control factory unification, I opted not to refactor here.

Even if its a high priority fix, we should add the test at the right abstraction layer. selections manger getLatestState should drop availableOptions. Then the test should just test selections manager getLatestState.


const onCreateControl = useCallback(async () => {
if (controlState && controlState.availableOptions.length) {
if (controlState && controlState.availableOptions?.length) {
Copy link
Contributor

Choose a reason for hiding this comment

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

how about moving controlState.availableOptions logic into src/platform/plugins/shared/controls/public/controls/esql_control/get_esql_control_factory.tsx onSaveControl so serialize implementation details do not leak into the UI.

Copy link
Contributor

@nreese nreese left a comment

Choose a reason for hiding this comment

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

Now that ESQL options are fetched on load, I think we need to implement PublishesDataLoading to show users when ESQL options are getting fetched.

…availableoptions

# Conflicts:
#	src/platform/plugins/shared/controls/public/controls/esql_control/get_esql_control_factory.tsx
#	src/platform/plugins/shared/esql/public/triggers/esql_controls/control_flyout/index.tsx
@Zacqary Zacqary requested a review from nreese August 25, 2025 16:23
return {
selectedOptions: selectedOptions$.getValue() ?? [],
availableOptions: availableOptions$.getValue() ?? [],
...(controlType$.getValue() === EsqlControlType.STATIC_VALUES
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add 2 unit tests for getLatestState, one with static values and one with valuesFromQuery?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I was screaming at this comment like "I DID" but turns out I forgot to git add -A

It is very Monday today

Copy link
Contributor

@nreese nreese left a comment

Choose a reason for hiding this comment

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

kibana-presentation changes LGTM
code review and tested in chrome

@Zacqary Zacqary merged commit 56cfa2b into elastic:main Aug 25, 2025
12 checks passed
@kibanamachine
Copy link
Contributor

Starting backport for target branches: 8.19, 9.1

https://github.com/elastic/kibana/actions/runs/17220527442

@elasticmachine
Copy link
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
controls 484.8KB 485.0KB +217.0B
esql 265.4KB 265.5KB +144.0B
total +361.0B

History

@kibanamachine
Copy link
Contributor

💔 All backports failed

Status Branch Result
8.19 Backport failed because of merge conflicts
9.1 Backport failed because of merge conflicts

Manual backport

To create the backport manually run:

node scripts/backport --pr 231690

Questions ?

Please refer to the Backport tool documentation

Zacqary added a commit to Zacqary/kibana that referenced this pull request Aug 26, 2025
… object (elastic#231690)

## Summary

Closes elastic#231668

For `VALUES_FROM_QUERY` ES|QL controls, omit the `availableOptions`
property from the control state before saving, from both the control
editor and the dashboard. These controls always fetch their
`availableOptions` on page load and dashboard refresh, and when the list
is extremely long, saving it in a saved object has been causing serious
performance issues for some users.

`STATIC_VALUES` controls are unaffected, and still save their
`availableOptions` in the control state.

(cherry picked from commit 56cfa2b)

# Conflicts:
#	src/platform/plugins/shared/controls/public/controls/esql_control/types.ts
@Zacqary
Copy link
Contributor Author

Zacqary commented Aug 26, 2025

💚 All backports created successfully

Status Branch Result
9.1
8.19

Note: Successful backport PRs will be merged automatically after passing CI.

Questions ?

Please refer to the Backport tool documentation

Zacqary added a commit to Zacqary/kibana that referenced this pull request Aug 26, 2025
… object (elastic#231690)

## Summary

Closes elastic#231668

For `VALUES_FROM_QUERY` ES|QL controls, omit the `availableOptions`
property from the control state before saving, from both the control
editor and the dashboard. These controls always fetch their
`availableOptions` on page load and dashboard refresh, and when the list
is extremely long, saving it in a saved object has been causing serious
performance issues for some users.

`STATIC_VALUES` controls are unaffected, and still save their
`availableOptions` in the control state.

(cherry picked from commit 56cfa2b)

# Conflicts:
#	src/platform/plugins/shared/controls/public/controls/esql_control/types.ts
Zacqary added a commit that referenced this pull request Aug 26, 2025
… saved object (#231690) (#232989)

# Backport

This will backport the following commits from `main` to `9.1`:
- [[Controls] Remove availableOptions from ES|QL values from query saved
object (#231690)](#231690)

<!--- Backport version: 10.0.1 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Zac
Xeper","email":"Zacqary@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-08-25T20:55:19Z","message":"[Controls]
Remove availableOptions from ES|QL values from query saved object
(#231690)\n\n## Summary\n\nCloses #231668 \n\nFor `VALUES_FROM_QUERY`
ES|QL controls, omit the `availableOptions`\nproperty from the control
state before saving, from both the control\neditor and the dashboard.
These controls always fetch their\n`availableOptions` on page load and
dashboard refresh, and when the list\nis extremely long, saving it in a
saved object has been causing serious\nperformance issues for some
users.\n\n`STATIC_VALUES` controls are unaffected, and still save
their\n`availableOptions` in the control
state.","sha":"56cfa2b8c214cb7d3d01a8487e85754bf45815e5","branchLabelMapping":{"^v9.2.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:Presentation","loe:small","impact:critical","Project:Controls","Team:ESQL","backport:version","v9.2.0","v9.1.3","v8.19.3"],"title":"[Controls]
Remove availableOptions from ES|QL values from query saved
object","number":231690,"url":"https://github.com/elastic/kibana/pull/231690","mergeCommit":{"message":"[Controls]
Remove availableOptions from ES|QL values from query saved object
(#231690)\n\n## Summary\n\nCloses #231668 \n\nFor `VALUES_FROM_QUERY`
ES|QL controls, omit the `availableOptions`\nproperty from the control
state before saving, from both the control\neditor and the dashboard.
These controls always fetch their\n`availableOptions` on page load and
dashboard refresh, and when the list\nis extremely long, saving it in a
saved object has been causing serious\nperformance issues for some
users.\n\n`STATIC_VALUES` controls are unaffected, and still save
their\n`availableOptions` in the control
state.","sha":"56cfa2b8c214cb7d3d01a8487e85754bf45815e5"}},"sourceBranch":"main","suggestedTargetBranches":["9.1","8.19"],"targetPullRequestStates":[{"branch":"main","label":"v9.2.0","branchLabelMappingKey":"^v9.2.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/231690","number":231690,"mergeCommit":{"message":"[Controls]
Remove availableOptions from ES|QL values from query saved object
(#231690)\n\n## Summary\n\nCloses #231668 \n\nFor `VALUES_FROM_QUERY`
ES|QL controls, omit the `availableOptions`\nproperty from the control
state before saving, from both the control\neditor and the dashboard.
These controls always fetch their\n`availableOptions` on page load and
dashboard refresh, and when the list\nis extremely long, saving it in a
saved object has been causing serious\nperformance issues for some
users.\n\n`STATIC_VALUES` controls are unaffected, and still save
their\n`availableOptions` in the control
state.","sha":"56cfa2b8c214cb7d3d01a8487e85754bf45815e5"}},{"branch":"9.1","label":"v9.1.3","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.19","label":"v8.19.3","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
@kibanamachine kibanamachine added the backport missing Added to PRs automatically when the are determined to be missing a backport. label Aug 27, 2025
@kibanamachine
Copy link
Contributor

Looks like this PR has backport PRs but they still haven't been merged. Please merge them ASAP to keep the branches relatively in sync.
cc: @Zacqary

Zacqary added a commit that referenced this pull request Aug 28, 2025
…y saved object (#231690) (#232990)

# Backport

This will backport the following commits from `main` to `8.19`:
- [[Controls] Remove availableOptions from ES|QL values from query saved
object (#231690)](#231690)

<!--- Backport version: 10.0.1 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT [{"author":{"name":"Zac
Xeper","email":"Zacqary@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-08-25T20:55:19Z","message":"[Controls]
Remove availableOptions from ES|QL values from query saved object
(#231690)\n\n## Summary\n\nCloses #231668 \n\nFor `VALUES_FROM_QUERY`
ES|QL controls, omit the `availableOptions`\nproperty from the control
state before saving, from both the control\neditor and the dashboard.
These controls always fetch their\n`availableOptions` on page load and
dashboard refresh, and when the list\nis extremely long, saving it in a
saved object has been causing serious\nperformance issues for some
users.\n\n`STATIC_VALUES` controls are unaffected, and still save
their\n`availableOptions` in the control
state.","sha":"56cfa2b8c214cb7d3d01a8487e85754bf45815e5","branchLabelMapping":{"^v9.2.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","Team:Presentation","loe:small","impact:critical","Project:Controls","Team:ESQL","backport:version","v9.2.0","v9.1.3","v8.19.3"],"title":"[Controls]
Remove availableOptions from ES|QL values from query saved
object","number":231690,"url":"https://github.com/elastic/kibana/pull/231690","mergeCommit":{"message":"[Controls]
Remove availableOptions from ES|QL values from query saved object
(#231690)\n\n## Summary\n\nCloses #231668 \n\nFor `VALUES_FROM_QUERY`
ES|QL controls, omit the `availableOptions`\nproperty from the control
state before saving, from both the control\neditor and the dashboard.
These controls always fetch their\n`availableOptions` on page load and
dashboard refresh, and when the list\nis extremely long, saving it in a
saved object has been causing serious\nperformance issues for some
users.\n\n`STATIC_VALUES` controls are unaffected, and still save
their\n`availableOptions` in the control
state.","sha":"56cfa2b8c214cb7d3d01a8487e85754bf45815e5"}},"sourceBranch":"main","suggestedTargetBranches":["9.1","8.19"],"targetPullRequestStates":[{"branch":"main","label":"v9.2.0","branchLabelMappingKey":"^v9.2.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/231690","number":231690,"mergeCommit":{"message":"[Controls]
Remove availableOptions from ES|QL values from query saved object
(#231690)\n\n## Summary\n\nCloses #231668 \n\nFor `VALUES_FROM_QUERY`
ES|QL controls, omit the `availableOptions`\nproperty from the control
state before saving, from both the control\neditor and the dashboard.
These controls always fetch their\n`availableOptions` on page load and
dashboard refresh, and when the list\nis extremely long, saving it in a
saved object has been causing serious\nperformance issues for some
users.\n\n`STATIC_VALUES` controls are unaffected, and still save
their\n`availableOptions` in the control
state.","sha":"56cfa2b8c214cb7d3d01a8487e85754bf45815e5"}},{"branch":"9.1","label":"v9.1.3","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.19","label":"v8.19.3","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->
@kibanamachine kibanamachine removed the backport missing Added to PRs automatically when the are determined to be missing a backport. label Aug 28, 2025
KodeRad pushed a commit to KodeRad/kibana that referenced this pull request Aug 28, 2025
… object (elastic#231690)

## Summary

Closes elastic#231668 

For `VALUES_FROM_QUERY` ES|QL controls, omit the `availableOptions`
property from the control state before saving, from both the control
editor and the dashboard. These controls always fetch their
`availableOptions` on page load and dashboard refresh, and when the list
is extremely long, saving it in a saved object has been causing serious
performance issues for some users.

`STATIC_VALUES` controls are unaffected, and still save their
`availableOptions` in the control state.
stratoula added a commit that referenced this pull request Oct 16, 2025
…ble control (#239315)

## Summary

Regression caused from this PR
#231690

When you have an existing control and edit it, the query doesnt run to
get the available options. As a result the UX is kinda broken.

### Checklist

- [ ] [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
kibanamachine pushed a commit to kibanamachine/kibana that referenced this pull request Oct 16, 2025
…ble control (elastic#239315)

## Summary

Regression caused from this PR
elastic#231690

When you have an existing control and edit it, the query doesnt run to
get the available options. As a result the UX is kinda broken.

### Checklist

- [ ] [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

(cherry picked from commit 84ad1f3)
kibanamachine added a commit that referenced this pull request Oct 17, 2025
… variable control (#239315) (#239350)

# Backport

This will backport the following commits from `main` to `9.2`:
- [[ES|QL] Displays the available options when editing an existing
variable control
(#239315)](#239315)

<!--- Backport version: 9.6.6 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sorenlouv/backport)

<!--BACKPORT
[{"author":{"name":"Stratou","email":"efstratia.kalafateli@elastic.co"},"sourceCommit":{"committedDate":"2025-10-16T13:19:40Z","message":"[ES|QL]
Displays the available options when editing an existing variable control
(#239315)\n\n## Summary\n\nRegression caused from this
PR\nhttps://github.com//pull/231690\n\nWhen you have an
existing control and edit it, the query doesnt run to\nget the available
options. As a result the UX is kinda broken.\n\n### Checklist\n\n- [ ]
[Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common
scenarios","sha":"84ad1f31553c96fd09f9baa8bc74ba6a6a17eea6","branchLabelMapping":{"^v9.3.0$":"main","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["regression","release_note:fix","Feature:ES|QL","Team:ESQL","backport:version","v9.2.0","v9.3.0"],"title":"[ES|QL]
Displays the available options when editing an existing variable
control","number":239315,"url":"https://github.com/elastic/kibana/pull/239315","mergeCommit":{"message":"[ES|QL]
Displays the available options when editing an existing variable control
(#239315)\n\n## Summary\n\nRegression caused from this
PR\nhttps://github.com//pull/231690\n\nWhen you have an
existing control and edit it, the query doesnt run to\nget the available
options. As a result the UX is kinda broken.\n\n### Checklist\n\n- [ ]
[Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common
scenarios","sha":"84ad1f31553c96fd09f9baa8bc74ba6a6a17eea6"}},"sourceBranch":"main","suggestedTargetBranches":["9.2"],"targetPullRequestStates":[{"branch":"9.2","label":"v9.2.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.3.0","branchLabelMappingKey":"^v9.3.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/239315","number":239315,"mergeCommit":{"message":"[ES|QL]
Displays the available options when editing an existing variable control
(#239315)\n\n## Summary\n\nRegression caused from this
PR\nhttps://github.com//pull/231690\n\nWhen you have an
existing control and edit it, the query doesnt run to\nget the available
options. As a result the UX is kinda broken.\n\n### Checklist\n\n- [ ]
[Unit or
functional\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\nwere
updated or added to match the most common
scenarios","sha":"84ad1f31553c96fd09f9baa8bc74ba6a6a17eea6"}}]}]
BACKPORT-->

Co-authored-by: Stratou <efstratia.kalafateli@elastic.co>
nickpeihl pushed a commit to nickpeihl/kibana that referenced this pull request Oct 23, 2025
…ble control (elastic#239315)

## Summary

Regression caused from this PR
elastic#231690

When you have an existing control and edit it, the query doesnt run to
get the available options. As a result the UX is kinda broken.

### Checklist

- [ ] [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
NicholasPeretti pushed a commit to NicholasPeretti/kibana that referenced this pull request Oct 27, 2025
…ble control (elastic#239315)

## Summary

Regression caused from this PR
elastic#231690

When you have an existing control and edit it, the query doesnt run to
get the available options. As a result the UX is kinda broken.

### Checklist

- [ ] [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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:version Backport to applied version labels impact:critical This issue should be addressed immediately due to a critical level of impact on the product. loe:small Small Level of Effort Project:Controls release_note:fix Team:ESQL ES|QL related features in Kibana t// Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas t// v8.19.3 v9.1.3 v9.2.0

5 participants