Part of https://github.com/elastic/kibana/issues/192005
Closes https://github.com/elastic/kibana/issues/176533
## Summary
This PR represents the first major cleanup task for the control group
embeddable refactor. The tasks included in this PR can be loosely
summarized as follows:
1. This PR removes the old, non-React version of controls
- Note that the new controls are still included under the
`react_controls` folder - I will address this in a follow up PR.
2. This PR removes **all** types associated with the old embeddable
system; i.e. any `*input*` or `*output*` types.
- As part of cleaning up these types, some of the types included in the
`public/react_controls` folder had to be moved to `common` to make them
available to server-side code.
- This resulted in an... unfortunate number of import changes 🫠 Hence
the rather large file change count. I took this opportunity to organize
the imports, too - so a significant chunk of these files are simply
import changes.
3. This PR removes the controls Storybook and all related mocks
- Since the controls storybooks have been broken for awhile, and since
we had plans to remove them but never got around to it, I just decided
to delete them as part of this PR and close
https://github.com/elastic/kibana/issues/176533 rather than spending
time to fix the types for non-operational stories
### Checklist
- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [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
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
PR replaces legacy embeddable control group implementation with react
control group implementation in DashboardContainer.
#### background
Work originally done in https://github.com/elastic/kibana/pull/190273.
https://github.com/elastic/kibana/pull/190273 was reverted by
https://github.com/elastic/kibana/pull/191993 because of dashboard
performance degradation. It was determined that degradation was because
new react embeddable controls fixed a regression where dashboard panels
are loading before control filters are created. This regression was
introduced by https://github.com/elastic/kibana/pull/187509.
The work around is that this PR keeps the currently broken behavior in
main and loads panels before control filters are ready. The thinking is
that the migration would replace like for like and not introduce any
performance changes. Then, at a later time, the regression could be
resolved.
#### reviewing
These are the same changes from
https://github.com/elastic/kibana/pull/190273 minus some work to
introduce a current regression in main. A full re-review is not needed.
---------
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Hannah Mudge <hannah.wright@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
#190273 introduced a performance regression. Reverting to move metrics to baseline again and create some time to identify root cause.
Co-authored-by: Thomas Neirynck <thomas@elastic.co>
closes https://github.com/elastic/kibana/issues/191137,
https://github.com/elastic/kibana/issues/190988,
https://github.com/elastic/kibana/issues/191155
PR replaces legacy embeddable control group implementation with react
control group implementation in DashboardContainer.
### Test instructions
1. Open dashboard via dashboard application or portable dashboard
2. Mess around with controls. There should be no changes in behavior
---------
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Hannah Mudge <Heenawter@users.noreply.github.com>
## Summary
This PR enforces ESLint rules in FTR tests, in particular:
- `no-floating-promises` rule to catch unawaited Promises in
tests/services/page objects
_Why is it important?_
- Keep correct test execution order: cleanup code may run before the
async operation is completed, leading to unexpected behavior in
subsequent tests
- Accurate test results: If a test completes before an async operation
(e.g., API request) has finished, Mocha might report the test as passed
or failed based on incomplete context.
```
198:11 error Promises must be awaited, end with a call to .catch, end with a call to .then
with a rejection handler or be explicitly marked as ignored with the `void` operator
@typescript-eslint/no-floating-promises
```
<img width="716" alt="Screenshot 2024-08-20 at 14 04 43"
src="https://github.com/user-attachments/assets/9afffe4c-4b51-4790-964c-c44a76baed1e">
- recommended rules from
[eslint-mocha-plugin](https://www.npmjs.com/package/eslint-plugin-mocha)
including:
-
[no-async-describe](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-async-describe.md)
-
[no-identical-title.md](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-identical-title.md)
-
[no-sibling-hooks.md](https://github.com/lo1tuma/eslint-plugin-mocha/blob/main/docs/rules/no-sibling-hooks.md)
and others
Note for reviewers: some tests were skipped due to failures after
missing `await` was added. Most likely is a "false positive" case when
test is finished before async operation is actually completed. Please
work on fixing and re-enabling it
---------
Co-authored-by: Tiago Costa <tiago.costa@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Closes https://github.com/elastic/kibana/issues/170396
Closes https://github.com/elastic/kibana/issues/135459
## Summary
This PR adds the option to **stop** selections from being auto-applied -
instead, authors can make it so that their selections are only applied
once the new apply button is clicked:
d785631c-0aa5-4e3f-81f9-2d1d0f582b70
### Brief Summary of Changes
- **Publishing Filters**
We used to publish the control group filters as soon as **any** child
changed its output - however, if the apply button is enabled, this logic
no longer works. So, we added an extra step to the publishing of
filters:
1. When a child's output changes, we check if the apply button is
enabled
2. If it is disabled, we publish the filters to the control group output
right away (like we used to); otherwise, we push the new filters to the
`unpublishedFilters` array.
3. Clicking the apply button will publish the `unpublishedFilters`
array.
- **Unsaved Changes**
We used to publish control group unsaved changes whenever **anything**
about the children panels' persistable input changed - however, this no
longer works with the apply button because we **don't** want selections
to trigger unsaved changes when it is enabled.
To get around this, we **no longer** take into account selections when
checking for unsaved changes - instead, we compare the **output
filters** from the control group to determine whether anything about the
children changed. As described above, if the control group has
"auto-apply selections" turned off, the control group waits to change
its output until the apply button is clicked - therefore, unsaved
changes will **also** not be triggered until the apply button is
clicked. This unsaved changes logic works **regardless** of if the apply
button is enabled or not.
- **Saved Object**
This required changes to the **dashboard** saved object because of how
we store the control group input as part of the dashboard SO - so, we
are now on a second version for the Dashboard SO. I've also made this
version **slightly less strict** by allowing unknown attributes in the
schema - that way, unknown attributes will no longer throw an error (as
they do on version 1).
### Checklist
- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [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] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [x] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Nick Peihl <nick.peihl@elastic.co>
## Summary
Closes#174542.
bb9e0297-a0a5-48e9-8424-457976ac3188
This adds a step interval option to the range slider control.
<img width="300" alt="Screenshot 2024-01-17 at 4 06 05 PM"
src="79984cc9-1b82-42e9-bb7f-7bb71307c894">
This step setting allows values greater than 0, including decimal step
intervals.
95247aab-045b-4c0c-9004-dce01f3a10b1
When a step interval is defined, the number fields still show the
absolute min/max range available as placeholders, but the range slider
in the popover will be rounded to the nearest min/max multiple of the
step interval.
<img width="400" alt="Screenshot 2024-01-17 at 4 05 26 PM"
src="cf9e17f7-75a6-4d37-97ff-8a54526615cf">
Even with a step interval defined, values that fall between the step
intervals can be entered directly in the number fields.
<img width="400" alt="Screenshot 2024-01-17 at 4 07 42 PM"
src="5af10454-5ce0-448b-8fda-075396e55b78">
### Checklist
Delete any items that are not applicable to this PR.
- [ ] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [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
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [ ] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [ ] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [ ] If a plugin configuration key changed, check if it needs to be
allowlisted in the cloud and added to the [docker
list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker)
- [ ] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [ ] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### Risk Matrix
Delete this section if it is not applicable to this PR.
Before closing this PR, invite QA, stakeholders, and other developers to
identify risks that should be tested prior to the change/feature
release.
When forming the risk matrix, consider some of the following examples
and how they may potentially impact the change:
| Risk | Probability | Severity | Mitigation/Notes |
|---------------------------|-------------|----------|-------------------------|
| Multiple Spaces—unexpected behavior in non-default Kibana Space.
| Low | High | Integration tests will verify that all features are still
supported in non-default Kibana Space and when user switches between
spaces. |
| Multiple nodes—Elasticsearch polling might have race conditions
when multiple Kibana nodes are polling for the same tasks. | High | Low
| Tasks are idempotent, so executing them multiple times will not result
in logical error, but will degrade performance. To test for this case we
add plenty of unit tests around this logic and document manual testing
procedure. |
| Code should gracefully handle cases when feature X or plugin Y are
disabled. | Medium | High | Unit tests will verify that any feature flag
or plugin combination still results in our service operational. |
| [See more potential risk
examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) |
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
## Summary
Refactoring general ui service to a kbn package.
Resolves an [Appex QA](https://github.com/elastic/appex-qa-team) issue.
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Closes https://github.com/elastic/kibana/issues/162985
## Summary
This PR re-adds UI for the filtering settings that allow authors to
determine whether or not they want the unified search bar / time picker
to sync with the control group.
To provide some context, we **used** to have these settings, but they
were deemed over complicated and the UI to control them was removed back
in `v8.3`. Here's a screenshot of what they used to look like:
<p align="center"><img width="700"
src="c84c4be0-a12e-46fa-b7b5-2e94682d8bbf"/></p>
> [!NOTE]
> These settings still existed in the code, even after `v8.3` - all we
did was remove the UI to control them.
After customer feedback, we decided to re-add the UI to control these
settings, with **some** simplification - specifically, after
investigating how other apps (Maps, Lens, etc.) handle unified search
bar settings, I noticed that the control group was the **only** place
that considered the query bar to be different than / seperate from
filter pills. Therefore, rather than having **three** toggles like we
did previously (filter pills, query bar, and time picker), I combined
the filter pills + query bar settings into a single "Apply global
filters" toggle. So now, our unified search bar settings have only
**two** toggles, like so:
<p align="center"><img width="500"
src="ba8d3a8f-ee0c-48c6-8d35-6068571013b3"/></p>
This is not only simpler than it was in versions less than `v8.3.0`, it
is also more consistent with how other apps do it.
> [!IMPORTANT]
> After some design feedback, I moved the old descriptions for the
"Validate user selections" and "Chain controls" settings into tooltips +
switched to a compressed `EuiSwitch` for all the settings.
>
> All of the screenshots in this PR description have been updated to
reflect this change, but some screenshots in the comments below may be
out of date.
### Summary of Control Group Settings by Version
| Version | Screenshot |
|--------|--------|
| Version <= `v8.2.0` | <img width="535"
src="c84c4be0-a12e-46fa-b7b5-2e94682d8bbf"/>
|
| `v8.3.0` <= version <= `v8.12.0` | <img width="535"
src="cb49f33e-ce7a-4a29-9830-2c3feafdcb23"/>
|
| This branch (`v8.13.0`) | <img width="535"
src="a76fc1f9-5b2d-4dc5-855a-6a284256e8c5"/>
|
### Checklist
- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [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] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
([Link](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/4638))

- [x] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
Closes https://github.com/elastic/kibana/issues/143587
Closes https://github.com/elastic/kibana/issues/126795
## Summary
This PR adds support for numeric options lists - i.e. options list
controls that are created with a numeric field. In order to make this
possible, I had to add support for fields to have multiple, overlapping
compatible control types (however, it is currently only number fields
where this applies). When selecting a field that is compatible with
multiple control types, the user is given the option to select which
control type they want, like so:
<p align="center"><img alt="GIF of multiple control types being
available for a single field"
src="9ebb6795-1206-47c4-aaef-32437d27cf59"/></p>
> [!NOTE]
> This system currently defaults to options list controls, since these
are the most common - this is backed up by our telemetry, which shows
that (in the last 30 days), clusters with at least one options list
control occured **ten times more often** than clusters with at least one
range slider control. However, if we decide to introduce more control
types (such as, for example, a date picker control), this assumption may
no longer be the case - at that point, we would need to reevaluate
whether the default should **always** be options list.
### Video
4a876c94-a041-4228-aab8-7c2c1c871071
### Exact Match Searching
Since numeric fields do not have a "prefix" query equivalent, the only
possibility for searching these fields is either (1) a range query or
(2) an exact match / equality query. In this PR, I added support for
equality search - i.e. in order to find a value in a numeric options
list, you must enter the *full*, exact term in order for it to be found;
in the future, we could extend this to include a range search. This is
the exact match searching in action:
<p align="center"><img alt="GIF of exact match searching example on
number field"
src="491feff3-031f-4367-8018-67aab9be55e3"/></p>
Since exact match searching is a generic search query that works for
**all** field types, I added this as an option for **all** field types
that support searching - i.e. keyword fields, number fields, IP fields,
etc. For example, here is the supported search techniques for a keyword
field:
<p align="center"><img alt="GIF of all available search techniques for
keyword field"
src="dbc12cef-d43e-4d9f-a779-a5fe9e75325c"/></p>
> [!TIP]
> Exact match / equality / term searching on float values can lead to
slightly unexpected results - refer to the [documentation on precision
loss](https://www.elastic.co/guide/en/elasticsearch/reference/current/number.html#_which_type_should_i_use)
for a description of why. Be mindful when using an options list control
for float values, and consider whether a range slider might be a better
solution!
Eventually, we should be able to add exact-match searching to date
fields, as well; however, due to [discrepancies that exist in the
unified search bar](https://github.com/elastic/kibana/issues/172097)
with respect to how searching date fields is handled, we should ideally
wait until this is resolved so that we can be consistent across all
three search experiences (query bar, filter pills, and controls).
Depending on how the author expects a given control to be used, this
search technique will return results **faster** than some of the other
search types since "search as you type" will, more often than not,
return zero results in this setting - that is why I chose to add it for
keyword fields, as well.
### Searching when `allowExpensiveQueries` setting is `false`
Previously, we had **two separate versions** of our options list search
queries - one for when `allowExpensiveQueries` was `true`, and the other
for when it was `false`. This was a significant amount of tech debt that
was time consuming to maintain, which made it difficult to justify
keeping this around considering **how much** of Kibana relies on this
setting to be `true` (searching for existing Dashboards by title on the
listing page, saving a brand new dashboard, etc.).
Therefore, while we still have **some** functionality when
`allowExpensiveQueries` is `false`, I have refactored this code
significantly to simplify the logic.
> [!IMPORTANT]
> Specifically, options list controls now only support **exact match
searching** when `allowExpensiveQueries` is `false`.
Since this query is the same regardless of the type of field or the
value of `allowExpensiveQueries`, this means we no longer have to
maintain two slightly different versions ("cheap" and "expensive") of
our search queries. This cleans up our tech debt significantly.
### Bundle Size Changes @elastic/kibana-operations
Changes to bundle size are primarily due to the changes I made to the
`OptionsListEditorOptions` component - since this component is directly
added to the options list factory (which is not async imported), this
impacts the bundle size.
### Checklist
- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [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] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
Closes https://github.com/elastic/kibana/issues/162978
## Summary
This PR removes the `labs:dashboard:dashboardControls` advanced UI
setting. The removal of this setting is **not** a breaking change, as it
hasn't functioned properly for quite some time; it is completely safe to
remove this setting **regardless** of the previous value. Telemetry
tracking for this setting is also no longer required.
### Checklist
- [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
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Closes https://github.com/elastic/kibana/issues/140135
Closes https://github.com/elastic/kibana/issues/159724
## Summary
### Changes to range slider
This PR migrates the range slider control to use the `EuiDualRange`
component, which both (a) removes a bunch of range slider code , thus
improving DX, and (b) improves the usability of the control by
simplifying the different states and making the slide animation much
smoother:
| Before | After |
|--------|--------|
| 
| 
|
Note that, due to the fact that migrating to the `EuiDualRange`
component means we no longer control the opening/closing of the popover,
this makes the "selections that extend beyond the current min/max of the
data" scenario slightly more difficult to handle. Specifically, we need
to decide the best time to recalculate the min/max of the slider as the
user's selections change.
The benefit of having control over the popover opening and closing was
that we could calculate the range slider's min/max values **when the
popover opened** and lock them in place so that they stayed static as
the user dragged:
<div align="center"><img width="500px"
src="1bf552d4-e70e-41ce-bf85-ab9ed0262398"
/></div><br/>
However, because the `EuiDualRange` handles the behaviour of the popover
and we therefore do not know when it opens/closes, it is not currently
possible to fully replicate this old behaviour. We have two main
options:
1. Recalculate the min/max of the range slider the user drags, which
gives a "sliding" effect:
<div align="center"><img width="500px"
src="4bb32b22-990e-40e9-a7df-78afca16bd27"
/></div>
2. Debounce this min/max calculation - with this, we avoid the "sliding"
effect shown above, and the min/max values **only get adjusted** when
the pin has been static for a long enough period of time (specifically,
`750ms`) or when the pin is dropped (i.e. the user lets go of the
mouse):
<div align="center"><img width="500px"
src="ac8943e6-4bcc-42dd-8cbb-1cdb627ba9f2"
/></div>
Ultimately, I went with option 2 in this PR. As a future enhancement, we
could replicate the old behaviour by adding some sort of
`onPopoverClosed` or `onPopoverOpened` logic to the `EuiDualRange`
component - however, this would need discussion with the EUI team to
ensure that this is the best way to handle it and not too specific to
our use case. Since EUI changes take awhile to propagate to KIbana, it's
not worth holding up this PR even further.
### Consistency with other control types
To keep things consistent, this PR also switches both the options list
and time slider controls to use the `EuiInputPopover` component and
removes the redundant control titles from the popover header:
| Before | After |
|--------|--------|
|

|

|
|

|

|
|

|

|
### Checklist
- [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] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- Technically, it does - but this will be resolved by the
@elastic/eui-team team adding an `aria-label` to the thumb `div`s
(https://github.com/elastic/eui/issues/7035). This is purely for the
sake of axe and/or automated `a11y` testing - it does not actually
impact `a11y` of the range slider, because the components missing an
`aria-label` are never accessible via the keyboard.
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: Jatin Kathuria <jatin.kathuria@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Closes https://github.com/elastic/kibana/issues/162777
flaky test runner
https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2811
Failure image shows options list is still open. PR updates
optionsListEnsurePopoverIsClosed with logic to prevent 2 possible issues
1) retry added to ensure missed click will attempt to close options list
again
2) check options list is open before clicking. This will resolve issue
where options list is closed and clicking actually opens it again

---------
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Closes https://github.com/elastic/kibana/issues/162697
## Summary
This PR adds a few tiny UI improvements to the control creation
elements, including...
**Data view picker:**
- Made the `Data view` form title respond to focus as expected
| <div align="center">Before</div> | <div align="center">After</div> |
|--------|--------|
| 
| 
|
- Switched to use `EuiInputPopover` rather than `EuiPopover`
- Removed the redundant popover title
| <div align="center">Before</div> | <div align="center">After</div> |
|--------|--------|
|

| 
|
**Field picker:**
- Made the `Field` form row title respond to focus as expected for all
of the inner form elements
| <div align="center">Before</div> | <div align="center">After</div> |
|--------|--------|
| 
| 
|
- Switched the `FieldTypeFilter` to use `EuiInputPopover` rather than
`EuiPopover`
- Removed the redundant title from the `FieldTypeFilter` popover
| <div align="center">Before</div> | <div align="center">After</div> |
|--------|--------|
|

|

|
- Made changes described in
https://github.com/elastic/eui/issues/6627#issuecomment-1452693611 so
that, when the field type filter is closed (either via `Esc` or through
the natural tab order), the focus returns to the search field
| <div align="center">Before</div> | <div align="center">After</div> |
|--------|--------|
| 
| 
|
- If provided, the initial selected field is now brought to the top of
the list
| <div align="center">Before</div> | <div align="center">After</div> |
|--------|--------|
|

|

|
**Controls display settings:**
- Surrounded the `Minimum width` row with a `div` so that it can receive
the `id` passed down from the `EuiFormRow` and respond to focus as
expected
| <div align="center">Before</div> | <div align="center">After</div> |
|--------|--------|
| 
| 
|
### Checklist
- [x] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: Jatin Kathuria <jatin.kathuria@elastic.co>
Closes https://github.com/elastic/kibana/issues/157157
Closes https://github.com/elastic/kibana/issues/152921
## Summary
The primary goal of this PR is to introduce an option for wildcard
("contains") searching to the options list control:
6847d0c5-014a-4322-8e59-308bc3ca27aa
### New Flyout Design
However, since this required adding a radio group to the custom options
list settings in the create/edit control flyout, I also made some
changes to the flyout design in order to better accommodate this (we
were previously using `EuiSwitch` components for the
control-type-specific settings, which did not work in this case because
I wanted to be able to add a tooltip to describe each search type):
| Before | After |
|--------|-------|
| 
| 
|
Note in the above GIFs that, since I was using an `EuiRadioGroup` for
the search technique setting, I decided it made more sense + was more
consistent for the "Allow multiple selections in dropdown" to also be
converted to a radio group rather than a switch. The "Ignore timeout for
results" setting is the only one that remained a switch in the new
design:
| Before | After |
|--------|-------|
|

|

|
### `EuiSwitch` with Tooltip Bug
As part of this redesign, I also fixed a very quick bug where, because
the old `SwitchWithTooltip` was defined **inside** the larger
`OptionsListEditorOptions` component, any state update on
`OptionsListEditorOptions` would cause `SwitchWithTooltip` to **also**
be re-rendered - this caused the "slide" animation to be interrupted on
click:
| Before | After |
|--------|-------|
|

|

|
### Title Bug Fix
And, since I was making so many changes to the flyout code as part of
refactoring the code (including the design changes above), I also fixed
a bug with control titles where things weren't getting set properly. To
test this, consider taking the following steps:
1. Create a new options list control, keeping the default title
2. Edit that options list control and change it to a range slider
control by selecting a number field
3. Notice that...
- Before this PR, the title gets completely cleared:
<br>
- After this PR, the default title gets updated to the range slider
field name:
<br>
4. Delete that range slider control and create a new control, keeping
the default title once again (options list or range slider, the type
doesn't matter).
5. Edit the control and change the field to a different field **of the
same type** (i.e. if your control from step 4 was an options list
control, select a field that keeps it as an options list control).
Before saving your changes, notice that the "default title" in the
`Label` input gets updated to the new field title:<br>
<img width="450"
src="0fabe2e3-7f83-4f2a-87e6-33253652972d"/><br>
6. After saving, notice that...
- Before this PR, the title doesn't actually get updated to the new
default title:
<br>
- After this PR, the title gets updated as expected:
<br>
### Flaky Test Runner
[test/functional/apps/dashboard_elements/controls/options_list/options_list_suggestions.ts](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2343):
<img
src="f2ed9d65-adcf-47af-bb00-ee11837c406b"/>
### Checklist
- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [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] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Closes https://github.com/elastic/kibana/issues/140175
Closes https://github.com/elastic/kibana/issues/143580
## Summary
Oh, boy! Get ready for a doozy of a PR, folks! Let's talk about the
three major things that were accomplished here:
### 1) Pagination
Originally, this PR was meant to add traditional pagination to the
options list control. However, after implementing a version of this, it
became apparent that, not only was UI becoming uncomfortably messy, it
also had some UX concerns because we were deviating from the usual
pagination pattern by showing the cardinality rather than the number of
pages:
<p align="center"><img
src="https://user-images.githubusercontent.com/8698078/214687041-f8950d3a-2b29-41d5-b656-c79d9575d744.gif"/></p>
So, instead of traditional pagination, we decided to take a different
approach (which was made possible by
https://github.com/elastic/kibana/pull/148420) - **load more options
when the user scrolls to the bottom!** Here it is in action:
<p align="center"><img
src="https://user-images.githubusercontent.com/8698078/214688854-06c7e8a9-7b8c-4dc0-9846-00ccf5e5f771.gif"/></p>
It is important that the first query remains **fast** - that is why we
still only request the top 10 options when the control first loads. So,
having a "load more" is the best approach that allows users to see more
suggestions while also ensuring that the performance of options lists
(especially with respect to chaining) is not impacted.
Note that it is **not possible** to grab every single value of a field -
the limit is `10,000`. However, since it is impractical that a user
would want to scroll through `10,000` suggestions (and potentially very
slow to fetch), we have instead made the limit of this "show more"
functionality `1,000`. To make this clear, if the field has more than
`1,000` values and the user scrolls all the way to the bottom, they will
get the following message:
<p align="center"><img
src="https://user-images.githubusercontent.com/8698078/214920302-1e3574dc-f2b6-4845-be69-f9ba04177e7f.png"/></p>
### 2) Cardinality
Previously, the cardinality of the options list control was **only**
shown as part of the control placeholder text - this meant that, once
the user entered their search term, they could no longer see the
cardinality of the returned options. This PR changes this functionality
by placing the cardinality in a badge **beside** the search bar - this
value now changes as the user types, so they can very clearly see how
many options match their search:
<p align="center"><img
src="https://user-images.githubusercontent.com/8698078/214689739-9670719c-5878-4e8b-806c-0b5a6f6f907f.gif"/></p>
> **Note**
> After some initial feedback, we have removed both the cardinality and
invalid selections badges in favour of displaying the cardinality below
the search bar, like so:
>
> <p align="center"><img
src="https://user-images.githubusercontent.com/8698078/216473930-e99366a3-86df-4777-a3d8-cf2d41e550fb.gif"/></p>
>
> So, please be aware that the screenshots above are outdated.
### 3) Changes to Queries
This is where things get.... messy! Essentially, our previous queries
were all built with the expectation that the Elasticsearch setting
`search.allow_expensive_queries` was **off** - this meant that they
worked regardless of the value of this setting. However, when trying to
get the cardinality to update based on a search term, it became apparent
that this was not possible if we kept the same assumptions -
specifically, if `search.allow_expensive_queries` is off, there is
absolutely no way for the cardinality of **keyword only fields** to
respond to a search term.
After a whole lot of discussion, we decided that the updating
cardinality was a feature important enough to justify having **two
separate versions** of the queries:
1. **Queries for when `search.allow_expensive_queries` is off**:
These are essentially the same as our old queries - however, since we
can safely assume that this setting is **usually** on (it defaults on,
and there is no UI to easily change it), we opted to simplify them a
bit.
First of all, we used to create a special object for tracking the
parent/child relationship of fields that are mapped as keyword+text -
this was so that, if a user created a control on these fields, we could
support case-insensitive search. We no longer do this - if
`search.allow_expensive_queries` is off and you create a control on a
text+keyword field, the search will be case sensitive. This helps clean
up our code quite a bit.
Second, we are no longer returning **any** cardinality. Since the
cardinality is now displayed as a badge beside the search bar, users
would expect that this value would change as they type - however, since
it's impossible to make this happen for keyword-only fields and to keep
behaviour consistent, we have opted to simply remove this badge when
`search.allow_expensive_queries` is off **regardless** of the field
type. So, there is no longer a need to include the `cardinality` query
when grabbing the suggestions.
Finally, we do not support "load more" when
`search.allow_expensive_queries` is off. While this would theoretically
be possible, because we are no longer grabbing the cardinality, we would
have to always fetch `1,000` results when the user loads more, even if
the true cardinality is much smaller. Again, we are pretty confident
that **more often than not**, the `search.allow_expensive_queries` is
on; therefore, we are choosing to favour developer experience in this
instance because the impact should be quite small.
2. **Queries for when `search.allow_expensive_queries` is on**:
When this setting is on, we now have access to the prefix query, which
greatly simplifies how our queries are handled - now, rather than having
separate queries for keyword-only, keyword+text, and nested fields,
these have all been combined into a single query! And even better -
⭐ now **all** string-based fields support case-insensitive search!
⭐ Yup, that's right - even keyword-only fields 💃
There has been [discussion on the Elasticsearch side
](https://github.com/elastic/elasticsearch/issues/90898) about whether
or not this setting is even **practical**, and so it is possible that,
in the near future, this distinction will no longer be necessary. With
this in mind, I have made these two versions of our queries **completely
separate** from each other - while this introduces some code
duplication, it makes the cleanup that may follow much, much easier.
Well, that was sure fun, hey?
<p align="center"><img
src="https://user-images.githubusercontent.com/8698078/214921985-49058ff0-42f2-4b01-8ae3-0a4d259d1075.gif"/></p>
## How to Test
I've created a quick little Python program to ingest some good testing
data for this PR:
```python
import random
import time
import pandas as pd
from faker import Faker
from elasticsearch import Elasticsearch
SIZE = 10000
ELASTIC_PASSWORD = "changeme"
INDEX_NAME = 'test_large_index'
Faker.seed(time.time())
faker = Faker()
hundredRandomSentences = [faker.sentence(random.randint(5, 35)) for _ in range(100)]
thousandRandomIps = [faker.ipv4() if random.randint(0, 99) < 50 else faker.ipv6() for _ in range(1000)]
client = Elasticsearch(
"http://localhost:9200",
basic_auth=("elastic", ELASTIC_PASSWORD),
)
if(client.indices.exists(index=INDEX_NAME)):
client.indices.delete(index=INDEX_NAME)
client.indices.create(index=INDEX_NAME, mappings={"properties":{"keyword_field":{"type":"keyword"},"id":{"type":"long"},"ip_field":{"type":"ip"},"boolean_field":{"type":"boolean"},"keyword_text_field":{"type":"text","fields":{"keyword":{"type":"keyword"}}},"nested_field":{"type":"nested","properties":{"first":{"type":"text","fields":{"keyword":{"type":"keyword"}}},"last":{"type":"text","fields":{"keyword":{"type":"keyword"}}}}},"long_keyword_text_field":{"type":"text","fields":{"keyword":{"type":"keyword"}}}}})
print('Generating data', end='')
for i in range(SIZE):
name1 = faker.name();
[first_name1, last_name1] = name1.split(' ', 1)
name2 = faker.name();
[first_name2, last_name2] = name2.split(' ', 1)
response = client.create(index=INDEX_NAME, id=i, document={
'keyword_field': faker.country(),
'id': i,
'boolean_field': faker.boolean(),
'ip_field': thousandRandomIps[random.randint(0, 999)],
'keyword_text_field': faker.name(),
'nested_field': [
{ 'first': first_name1, 'last': last_name1},
{ 'first': first_name2, 'last': last_name2}
],
'long_keyword_text_field': hundredRandomSentences[random.randint(0, 99)]
})
print('.', end='')
print(' Done!')
```
However, if you don't have Python up and running, here's a CSV with a
smaller version of this data:
[testNewQueriesData.csv](10538537/testNewQueriesData.csv)
> **Warning**
> When uploading, make sure to update the mappings of the CSV data to
the mappings included as part of the Python script above (which you can
find as part of the `client.indices.create` call). You'll notice,
however, that **none of the CSV documents have a nested field**.
Unfortunately, there doesn't seem to be a way to able to ingest nested
data through uploading a CSV, so the above data does not include one -
in order to test the nested data type, you'd have to add some of your
own documents
>
> Here's a sample nested field document, for your convenience:
> ```json
> {
> "keyword_field": "Russian Federation",
> "id": 0,
> "boolean_field": true,
> "ip_field": "121.149.70.251",
> "keyword_text_field": "Michael Foster",
> "nested_field": [
> {
> "first": "Rachel",
> "last": "Wright"
> },
> {
> "first": "Gary",
> "last": "Reyes"
> }
> ],
> "long_keyword_text_field": "Color hotel indicate appear since well
sure right yet individual easy often test enough left a usually
attention."
> }
> ```
>
### Testing Notes
Because there are now two versions of the queries, thorough testing
should be done for both when `search.allow_expensive_queries` is `true`
and when it is `false` for every single field type that is currently
supported. Use the following call to the cluster settings API to toggle
this value back and forth:
```php
PUT _cluster/settings
{
"transient": {
"search.allow_expensive_queries": <value> // true or false
}
}
```
You should pay super special attention to the behaviour that happens
when toggling this value from `true` to `false` - for example, consider
the following:
1. Ensure `search.allow_expensive_queries` is either `true` or
`undefined`
2. Create and save a dashboard with at least one options list control
3. Navigate to the console and set `search.allow_expensive_queries` to
`false` - **DO NOT REFRESH**
4. Go back to the dashboard
5. Open up the options list control you created in step 2
6. Fetch a new, uncached request, either by scrolling to the bottom and
fetching more (assuming these values aren't already in the cache) or by
performing a search with a string you haven't tried before
7. ⚠️ **The options list control _should_ have a fatal error** ⚠️<br>The
Elasticsearch server knows that `search.allow_expensive_queries` is now
`false` but, because we only fetch this value on the first load on the
client side, it has not yet been updated - this means the options list
service still tries to fetch the suggestions using the expensive version
of the queries despite the fact that Elasticsearch will now reject this
request. The most graceful way to handle this is to simply throw a fatal
error.
8. Refreshing the browser will make things sync up again and you should
now get the expected results when opening the options list control.
### Flaky Test Runner
<a
href="https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1845"><img
src="https://user-images.githubusercontent.com/8698078/215894267-97f07e59-6660-4117-bda7-18f63cb19af6.png"/></a>
### Checklist
- [x] Any text added follows [EUI's writing
guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses
sentence case text and includes [i18n
support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)
- [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] Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard accessibility](https://webaim.org/techniques/keyboard/))
- [x] Any UI touched in this PR does not create any new axe failures
(run axe in browser:
[FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/),
[Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US))
> **Note**
> Technically, it actually does - however, it is due to an [EUI
bug](https://github.com/elastic/eui/issues/6565) from adding the group
label to the bottom of the list.
- [x] This renders correctly on smaller devices using a responsive
layout. (You can test this [in your
browser](https://www.browserstack.com/guide/responsive-testing-on-local-server))
- [x] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
---------
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Closes https://github.com/elastic/kibana/issues/147293
## Summary
Before this change, the Redux state `explicitInput` was getting out of
sync with the embeddable `explicitInput` in scenarios where the new
`explicitInput` was missing a key that the old `explicitInput` had -
therefore, because they were out of sync, the changes that **should**
have been discarded kept getting injected back into the embeddable
`explicitInput`, which made it impossible to actually discard anything
unless the key existed in both the before and after state.
This PR fixes this by replacing the entire Redux state `explicitInput`
with the embeddable `explicitInput` rather than spreading the new value.
It also fixes a bug with the time slider control where changes to the
embeddable's input were not reflected properly in the control's state,
so nothing could be discarded even after the initial bug was fixed.
#### Further Explanation
When a control is first created, all the optional properties of the
explicit input do not yet exist - for example, when creating an options
list control, the `selections` key does not exist in the `explicitInput`
until a selection is made. Therefore, imagine the following scenario:
1. You create an options list control (where the `selections` key does
not exist) and save the dashboard
2. You make some selections, which causes `unsaved changes` because the
`selections` key now exists and is equal to an array
3. You switch to view mode and choose to discard your changes, thus
(supposedly) removing the `selections` key from the `explicitInput`
object once again
Unfortunately, the Redux embeddable state for each control was **not**
accurately removing the `selections` key as expected - this was because,
when trying to update the `explicitInput` via the old
`updateEmbeddableReduxInput`, the new value was **spread** on top of the
older value rather than replacing it. In a simplified scenario, this
resulted in something like this:
```typescript
const oldExplicitInput = { id: 'test_id', selections: ['test selection'] };
const newExplicitInput = { id: 'test_id' }
const result = { ...oldExplicitInput, ...newExplicitInput };
```
In this code, because `newExplicitInput` does not have the `selections`
key, `result` will equal `{ id: 'test_id', selections: ['test
selection'] }` - this is not the behaviour we want! Instead, we wanted
to replace the entire old `explicitInput` with the new `explicitInput`.
Effectively, that is what this PR does.
Thanks to @ThomThomson for helping out with finding the root cause of
this after I got lost :)
### How to Test
For both options list and range slider controls,
1. Create a control of the desired type
2. Save the dashboard
3. Make some sort of change that causes unsaved changes - for example,
make a selection or, if an options list control, set `exclude` to `true`
4. Switch to view mode, discarding the changes
5. Ensure that the changes made in step 3 are no longer applied ✅
6. Switch back to edit mode
7. Ensure that there are no `unsaved changes` ✅
#### Flaky Test Runner
<a
href="https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1649"><img
src="https://user-images.githubusercontent.com/8698078/207701101-69cdfada-77c6-4510-b254-1fd1fa13af5c.png"/></a>
### Checklist
- [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] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
Closes https://github.com/elastic/kibana/issues/147140
## Summary
After discussion surrounding the "author" versus "analyst" experience
for the controls, we have come to the conclusion that a simpler create
experience is necessary to streamline our current process. This means
removing **all** options that are not absolutely necessary -
specifically, this PR removes the UX for the following "Additional
settings" toggles from the creating/editing flyout:
- Allow selections to be excluded (`hideExclude`)
- Allow exists query (`hideExists`)
- Allow dynamic sorting of suggestions (`hideSort`)
This will leave only two additional settings:
- Allow multiple selections in dropdown
- Ignore timeout for results
While the UX for the removed toggles will be removed, the logic is kept
- this means that, for the Control Group API that solutions will be
using, this functionality could still be exposed to the consumers.
### Migration
Consider a scenario where, in 8.6, a user creates an options list
control with `hideExists` set to `true`- that is, the `Exists` option is
not displayed in the options list suggestions. After upgrading to 8.7,
they realize that they want to turn the `Exists` query back on - but
they can't, because the toggle has been removed so `hideExists` is stuck
as `true`! Their only choice is to remove the control and start over.
In order to avoid this scenario, I added an 8.7 migration that goes
through all existing control group panels and, if a control is an
options list, it removes the `hideExclude` and `hideExists` keys from
the explicit input. This is effectively the same was setting these to
`false` since they are optional.
> **Note**
> Because the `hideExclude` and `hideExists` toggles were added back in
8.6.0 but `hideSort` was only added in 8.7.0 (which has not yet reached
feature freeze), that is why only the `hideExclude` and `hideExists`
keys are removed. There is no need to add a migration for `hideSort`
because there will be no customer impact from removing the "Allow
dynamic sorting of suggestions" toggle.
## How to test
For the sake of convenience, I have exported various dashboard saved
objects from 8.6 (all of which used the demo "Kibana Sample Data
eCommerce" data view) in order to test the migration to 8.7:
- `8.6_OneControlNoMigrations.ndjson`
This dashboard had a single options list control that should require
**no** migration because it was created with the default settings:

- `8.6_OneControlTogglesOff.ndjson`
This dashboard had a single options list control with **every single**
toggle turned off:

- `8.6_TwoOptionsListControls.ndjson`
This dashboard had two options list controls with the following
settings:

The first control also had the `exists` query selected with `exclude`
set to `true`, while the second control had non-default size settings,
and I made some selections and saved them as part of the dashboard.
- `8.6_MultipleControlTypes.ndjson`
This dashboard had four controls: two options list controls with the
following settings, a range slider control, and a time slider control:

These can each be found in the following ZIP file:
> **Warning**
>
[DashboardSavedObjectsForTestingMigration.zip](10180945/DashboardSavedObjectsForTestingMigration.zip)
In order to test this PR, you should (at minimum) download the previous
ZIP, individually import each dashboard into Kibana 8.7, and ensure
that:
1. the resulting JSON looks as expected, with no `hideExists` or
`hideExclude` keys present, and
2. the dashboard loads correctly and each options list control has the
ability to include/exclude, sort, and create an exists query regardless
of the previous state of `hideExists` or `hideExclude`
### Checklist
- [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] This was checked for [cross-browser
compatibility](https://www.elastic.co/support/matrix#matrix_browsers)
### For maintainers
- [ ] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
https://github.com/elastic/kibana/pull/140739 caused a regression with
timeslider control where `ControlGroupContainer` was not not firing
`updateOutput` on `output.timeslice` changes.
This PR resolves the regression and adds functional tests to ensure
interactions with timeslider properly flow to dashboard saved search
panel
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
* Mock first attempt at UI
* Add `exists` filter functionality
* Make `exists` selection change button
* Overwrite selections instead of disabling them
* Add support for negate to exists
* Add to diffing system
* Add toggle to disable `exists` query
* Clear `exists` selection when toggle is disabled + fix mocks
* Switch to tooltip instead of docs link
* Clean up popover logic
* Fix rendering through memoization
* Auto focus on search when popover opens
* Added Jest unit tests
* Beef up mock and add more Jest unit tests
* Add functional tests
* Split up popover in to smaller components
* Fix unit tests + functional test flakiness
* Fix flakiness a second time + add chaining tests
* Clean up code
* Add `exists` selection to validation
* Fix invalid bug
* Fix failing unit test
* More code clean up
* Add another functional test
* Apply styling changes
* Fix tests
* Fix a11y issues
* Remove validation
* Fix types
* Clean up `a11y` fix
* Fix jest test
* Address feedback
* Fix wording of tooltip
* Add buttons with no functionality
* Added basic negate functionality
* Add `NOT` text when negated
* Clean up
* Add jest and functional tests
* Fix merge conflicts
* Rename `negate` to `exclude`
* Fix `unsaved changes` bug
* Move erase button back to beside search
* Clean up
* Add chaining functional tests
* Fix other unsaved changes bug
* Fix mobile view of popover
* Add option to disable exclude/include toggle
* Prevent unsaved changes bug for options list settings
* Add tooltip to run past timeout setting
* Address review comments
* Rename variable
* Set `exclude` to `false` when footer is hidden
* Timeslider plugin boilerplate
* wire redux store
* add time range bounds to store
* range control
* set value in store
* previous next buttons
* Spacetime timeslider dash (#138553)
* wire redux store
* add time range bounds to store
* range control
* set value in store
* previous next buttons
* push timeslice to Dashboard input
* Wire up timeslice (#138570)
* wire redux store
* add time range bounds to store
* range control
* set value in store
* previous next buttons
* push timeslice to Dashboard input
* cleanup
* Spacetime timeslider dash (#138573)
* wire redux store
* add time range bounds to store
* range control
* set value in store
* previous next buttons
* push timeslice to Dashboard input
* cleanup
* play button
* Notify control group when all panels loaded (#138674)
* get play button working
* play button (#138681)
* wire redux store
* add time range bounds to store
* range control
* set value in store
* previous next buttons
* push timeslice to Dashboard input
* cleanup
* play button
* get play button working
* cleanup
* clean up
* clean up wrap logic
* Spacetime timeslider dash -clean up wrap logic (#138822)
* wire redux store
* add time range bounds to store
* range control
* set value in store
* previous next buttons
* push timeslice to Dashboard input
* cleanup
* play button
* get play button working
* cleanup
* clean up wrap logic
* Add waitForPanelsToLoad$ observable (#138950)
* fix import
* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'
* sync range slider width on popover panel resize
* fix styling
* update embeddables to support time slice
* [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix'
* change file structure
* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'
* disable add button when control group contains timeslider
* hide edit button for timeslider control
* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'
* force timeslider width to be large
* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'
* use timeslice to filter other controls
* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'
* skip timeslider control in control chaining
* [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix'
* cleanup
* fix initial timeRange
* [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix'
* clear button
* [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix'
* render prepend
* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'
* remove unused code
* Container.getAnyChildOutputChange$
* play observable
* tslint
* tslint
* clean up
* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'
* fix lint
* fix import
* fix plugin size and other clean up
* fix 'unsaved changes' issue
* [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix'
* fix Dragging UI Nit
* fix Label position Above Nit
* [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix'
* support relative time ranges
* fix issue where clear not propogated to panels
* time slider functional test
* clean up functional test
* [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix'
* tslint
* fix time_slider functional test
* fix time slider not expanding after creating non-expanding control
Co-authored-by: Nick Peihl <nick.peihl@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Greg Thompson <thompson.glowe@gmail.com>
Co-authored-by: Joe Reuter <johannes.reuter@elastic.co>
* Field first *creation*
* Field first *editing*
* Add support for custom control options
* Add i18n
* Make field picker accept predicate again + clean up imports
* Fix functional tests
* Attempt 1 at case sensitivity
* Works both ways
* [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix'
* Clean up code
* Use React useMemo to calculate field registry
* Fix functional tests
* Fix default state + control settings label
* Fix functional tests
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
* Decouple control auto sizing and control width
* Add grow control setting to control group settings flyout
* Set min-width style for each control size
* Remove width settings from control group settings
* Add media query to remove min-widths in small viewport
* Fix grow state management
* Fix i18n errors
* Fix control group settings functional tests
* Updated control width label and move tooltip icon
* Use euiBreakpoints for media queries
* Removed tooltip
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
* Replace is half working
* Child embeddable listens for change in type
* Fix control order on replace
* Fix factory & remove duplicated onPanelAdded/Removed
* Comments + clean up code
* Set invalid editor state on type change
* Add functional tests and clean test code
* Comment out time slider tests
* Remove getReplacementPanelState
* Fix promise syntax
* Fix mutation
* Fix flaky test
* Fix conflicts
* Move control type selection in to flyout
* Set default icon type if getIconType undefined
* Fix create control functional tests
* Fix factories for multiple types
* Show only selected type icon when editing
* Add optional tooltip support
* Rename promise variable
* Fix imports
* Fix nits
* Edit tooltip text for options list control
* Add controls button to toolbar
* Add dismiss button
* Add style to toolbar controls button
* Clean up unnecessary isControlsEnabled check
* Make toolbar controls button conditional once callout dismissed
* Move add and edit controls to toolbar dropdown
* Remove icon buttons
* Add each control seperately to toolbar dropdown
* Remove unused code
* Fix close popover on click
* Remove unnecessary dark theme check
* Make closePopover optional for creating controls
* Fix control group strings
* Fix alignment of toolbar popover items
* Functional tests - create controls from new menu button
* Hide controls callout for empty dashboards
* Add tooltips to control types + i18n support.
* Move callout render logic to dashboard viewport
* Add controls callout functional tests
* Fix bundle size by lazy importing controls callout
* Get create control button in callout via passed function
* Fix mobile view of callout
* Add documentation and cleaned code based on Devon's feedback
* Moved the 'add to library' and 'controls' buttons in to extra