Commit graph

33 commits

Author SHA1 Message Date
Hannah Mudge
eea3b1b8f4
[Controls] Fix flaky time slider test (#169553)
Closes https://github.com/elastic/kibana/issues/169404

## Summary

The `Pin start` tooltip has a tendency to get in the way of the
`timeSlider-nextTimeWindow` button:


![image](dc4855ab-6c59-4003-83f1-de778f97b0f8)

To prevent this, I've made it so that the popover is closed **before**
the `next` button is pressed.


### [Flaky Test
Runner](https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/3681)


![image](d339d256-dced-4bbd-b287-e04cd1268835)

### 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: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
2023-10-23 13:57:51 -06:00
Hannah Mudge
b7f1bb9c18
[Controls] Remove labs:dashboard:dashboardControls UI setting (#168997)
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>
2023-10-17 08:41:27 -06:00
Hannah Mudge
75d27adffc
[Controls] Migrate range slider to EuiDualRange and make styling consistent across all controls (#162651)
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 |
|--------|--------|
| ![Aug-02-2023
09-19-26](08efbfb8-3aff-4c44-acb3-79442d3fc831)
| ![Aug-03-2023
09-10-30](8f62936f-c15d-4ede-9925-d1b314c7a9c9)
|

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 |
|--------|--------|
|
![image](dce0fc28-0714-48ce-a6df-3aed2e9749d8)
|
![image](0619a19a-073f-4d2e-ae40-1d77e9f9a7ae)
|
|
![image](c7ff43ba-b94f-402a-b61a-ee238065acb4)
|
![image](07e95ef5-5db8-490e-9bc8-7f9df4513da5)
|
|
![image](20a30dd9-2f0c-49f5-a035-37f827c5c1a2)
|
![image](64acea5a-5120-4d88-bac3-14f45be98b0d)
|

### 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>
2023-08-16 11:27:14 -06:00
Nathan Reese
36f260593e
unskip Failing test: Dashboard Elements - Controls tests.test/functional/apps/dashboard_elements/controls/common/control_group_chaining·ts - Controls Dashboard control group hierarchical chaining Creating "does not exist" query from first control filters the second and third controls (#163350)
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


![image](06a6673c-e92f-4a45-8910-8a0a1a7c5776)

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
2023-08-07 15:57:37 -06:00
Hannah Mudge
3763a5a134
[Controls] [PresentationUtil] QoL improvements to control creation form (#162067)
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> |
  |--------|--------|
| ![Jul-28-2023
15-55-13](c287978d-a54a-4809-a806-5a2caa41cf5d)
| ![Jul-28-2023
15-56-24](8f403c2d-80a5-4fc1-989a-1ecceb056fc9)
|

- Switched to use `EuiInputPopover` rather than `EuiPopover`
- Removed the redundant popover title

  | <div align="center">Before</div> | <div align="center">After</div> |
  |--------|--------|
|
![image](013fc848-3a9a-4280-9b37-6c1f025f3597)
| ![Screenshot 2023-07-28 at 4 16 18
PM](22a2de30-cae1-49d4-9c33-d1537488d08d)
|

**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> |
  |--------|--------|
| ![Jul-28-2023
16-06-01](7dd845bc-0476-4b2a-b9b5-efce3c2e2844)
| ![Jul-28-2023
16-07-00](222a9199-e5c2-4180-9501-e31588020855)
|

- 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> |
  |--------|--------|
|
![image](007c61db-989b-4615-a36f-5f6307f04aaf)
|
![image](ed7aea0c-d852-4f1c-ae03-14933fa2888a)
|

- 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> |
  |--------|--------|
| ![Jul-28-2023
16-12-58](aea49501-1f61-4ae8-bc90-1bacbbc232e7)
| ![Jul-28-2023
16-13-54](8068b090-9cca-427f-bc36-2b9e6b2324f1)
|

- 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> |
  |--------|--------|
|
![image](2bdad643-d184-4c80-b940-5a73820dc8a5)
|
![image](cda382e2-0e15-48c0-bdbf-c530a77570b8)
|

**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> |
  |--------|--------|
| ![Jul-28-2023
16-31-56](125d2a75-bcec-452c-8682-85de3a44185b)
| ![Jul-28-2023
16-31-20](935a17f1-4adc-4b86-811b-334a42e4627e)
|


### 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>
2023-08-04 11:07:09 -06:00
Hannah Mudge
f1dc1e1869
[Controls] Move "clear selections" to hover action (#159526)
Closes https://github.com/elastic/kibana/issues/159395
Closes https://github.com/elastic/kibana/issues/153383

## Summary

This PR moves the "clear selections" button for all controls (options
list, range slider, and time slider) from inside their respective
popovers to a general hover action - this not only saves users a click
for this common interaction (which has actually been brought in user
feedback up as a downside of the current controls compared to the legacy
controls), it also allows us to fully move forward with migrating the
range slider control to the `EuiDualRange` component. This will be done
in a follow up PR, which should both (1) clean up our range slider code
significantly and (2) fix the [bug discussed
here](https://github.com/elastic/kibana/pull/159271#pullrequestreview-1477930356).
The related issue can be tracked
[here](https://github.com/elastic/kibana/issues/159724), since we might
not be able to get to it right away.

This "clear selections" action is available in both view and edit mode,
like so:

|  | Edit mode | View mode |
|--------|--------|--------|
| **Range slider** |
![image](83cb1e1a-0b20-43aa-a37b-14484b5f4945)
|
![image](0d28ce03-5242-4f3a-8a05-d447bca50ddb)
|
| **Options list** |
![image](066257f6-c0ce-4e33-a193-5bbc62e341a6)
|
![image](d1ec124c-f5ee-4137-9eb9-33e06d522435)
|
| **Time slider** |
![image](33b8bb80-fa0c-4281-ae81-f1e1b44086f3)
|
![image](bd7c41ae-706c-45f3-8b49-9bd4d259e5cf)
|

You may notice in the above screenshots that the "delete" action is now
represented with a red trash icon rather than a red cross, and the
tooltip text was also changed to use the word "Delete" rather than the
word "Remove" - these changes were both made to be more consistent with
the "Delete panel" action available on dashboards:

| Delete control - Before | Delete control - After | Delete panel |
|--------|--------|--------|
| ![Screenshot 2023-06-13 at 5 32 22
PM](2600b197-653b-43ea-a043-a50be7e6a796)
|
![image](5ef80380-2575-45fc-ba11-c59f3f252ac3)
| <img
src="a7f65777-45cf-44f2-96a7-f1042cb25e02"/>
|

Beyond these changes, I also made a few quick changes to the time slider
control, including:
1. Fixing the appearance so that the background is once again white, as
described
[here](https://github.com/elastic/kibana/pull/159526#discussion_r1229792071)
2. Adding comparison logic so that clearing selections no longer causes
unsaved changes unnecessarily, as described
[here](https://github.com/elastic/kibana/pull/159526#discussion_r1229789753)

### Videos

**Before**


96365c85-748e-4fd7-ae5d-589aa11a23ef


**After**


68352559-e71b-4b5e-8709-587016f0b35a



### 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>
2023-06-20 16:53:10 -06:00
Hannah Mudge
9b0f10629b
[Controls] Range slider a11y and performance improvements (#159271)
Closes https://github.com/elastic/kibana/issues/135466

## Summary

The main goal of this PR is to fix the serious "Buttons must have
discernible text" a11y failure - this is accomplished by switching from
building our own range slider button using `EuiFlexGroup` to instead
using `EuiFormControlLayoutDelimited`, which both resolves these a11y
issues and also fixes a rendering regression:

| Before | After |
|--------|-------|
|
![image](49ea1516-db74-46af-baa5-4ad0a31d5b5a)
|
![image](71bc61f2-f10d-4f8c-8ad2-2681f7faf921)
|

As part of this, I also took some time to clean up some of the range
slider code, which hasn't really been touched in awhile - this
includes...
- moving the debounce on range selections from the embeddable's `input$`
subscription to the component itself, as described
[here](https://github.com/elastic/kibana/pull/159271#discussion_r1226886857).
- fixing a bug where resetting the range slider would unnecessarily
cause unsaved changes, as described
[here](https://github.com/elastic/kibana/pull/159271#discussion_r1226885018).
- improving the `onClick` behaviour (with some notable limitations), as
described
[here](https://github.com/elastic/kibana/pull/159271#discussion_r1226934124).

As a follow up, we need to move the "clear selections" button [to a
hover action](https://github.com/elastic/kibana/issues/159395), which
will enable us to then fully move forward with our transition to the
`EuiDualRange` component.

### 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
- [ ] ~Any UI touched in this PR is usable by keyboard only (learn more
about [keyboard
accessibility](https://webaim.org/techniques/keyboard/))~
   > **Note**
> Details provided
[here](https://github.com/elastic/kibana/pull/159271#discussion_r1226934124)
on why only partial keyboard support is currently supported
- [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)
2023-06-15 10:58:11 -06:00
Hannah Mudge
8277665dbc
[Controls] Allow wildcard searching in options list (#158427)
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 |
|--------|-------|
| ![May-29-2023
09-04-02](e7a8dba8-0815-4460-b55a-f622300e40ac)
| ![May-29-2023
09-00-21](50fa6795-f7e1-4329-bac6-045f6f8464b3)
|

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 |
|--------|-------|
|
![image](53b1168c-b172-4cd0-8fbf-ce80a03964c0)
|
![image](60b174a6-635f-4b09-8f1a-fef1b0e7bb2c)
|


### `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 |
|--------|-------|
|
![image](03bebc7c-b529-463e-a042-7aa680c99eeb)
|
![image](db0fe6e7-d352-476a-8b77-d93d835c9942)
|




### 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:

![image](cdd9ecc2-c729-402c-8f69-018de3e60342)<br>
- After this PR, the default title gets updated to the range slider
field name:

![image](d56ec9f9-6961-4799-ba3b-623ae5f46d91)<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:

![image](b9262c67-9841-47f0-8d25-d5689fe408de)<br>
     - After this PR, the title gets updated as expected:

![image](1a2b3f19-a02c-4525-9d2c-8029c020a117)<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>
2023-06-06 08:32:10 -06:00
Hannah Mudge
b8f490a728
[Dashboard] [Controls] Prevent control group reload on output change (#154763)
Closes https://github.com/elastic/kibana/issues/154146

## Summary

This PR fixes a race condition for chained options list controls where
making changes to the output of the first control in the chain would
sometimes cause the chained controls to be stuck in an infinite loading
state. (Thanks to @ThomThomson for helping me narrow this down).

Basically, before this, **any** change to the control group output (for
example, by making a selection in an options list control) would cause
the dashboard to `forceRefresh` the entire control group:


682e2ed6ae/src/plugins/dashboard/public/dashboard_container/embeddable/integrations/controls/dashboard_control_group_integration.ts (L174-L185)

So, imagine you have a dashboard with two chained controls: control A
and control B. Making a selection in control A will cause the following
chain of events:
1. Make a selection in control A
2. Control B refetches its suggestions because hierarchical chaining is
turned on
3. At "the same time" (more-or-less), the subscription above fires due
to step 1 changing the control group output, and so the dashboard forces
a refresh of the control group
4. This causes both control A and control B to refetch their suggestions
unnecessarily, due to the `reload` logic of
`options_list_embeddable.tsx`.


682e2ed6ae/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx (L417-L421)

Because control B has now had two of the "same" requests sent to the
server, this caused a race condition where, depending on how fast things
completed and the state of the caching (which is cleared on `reload` but
is **not** cleared when a new selection is made), sometimes **both**
requests would get aborted and so the following early return would
prevent control B from setting its loading state to `false` (i.e. it
would get stuck in an infinite loading state):


682e2ed6ae/src/plugins/controls/public/options_list/embeddable/options_list_embeddable.tsx (L329-L337)


This PR prevents this race condition by only refreshing the
**dashboard's children** (i.e. the visualization embeddables) and not
the control group itself when the control group's output changes - as an
extra benefit, this makes the control group more efficient than it was
before since the unnecessary refresh is no longer slowing things down 💃

### Flaky Test Runner

<a
href="https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/2114"><img
src="https://user-images.githubusercontent.com/8698078/231301760-a0c16e9b-fa7e-426c-9483-077527d39faa.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)
2023-04-12 11:08:51 -06:00
Devon Thomson
eb9cc11a7c
[Controls] Use EUI Selectable for Field search (#151231)
## Summary
Replaces Control field selection list with EUISelectable.
2023-02-24 09:39:15 -06:00
Hannah Mudge
55b66e20fe
[Dashboard] [Controls] Load more options list suggestions on scroll (#148331)
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>
2023-02-06 16:13:28 -07:00
Hannah Mudge
53582e403d
[Controls] [Dashboard] Use EuiSelectable for options list suggestions (#148420)
Closes https://github.com/elastic/kibana/issues/147624
Closes https://github.com/elastic/kibana/issues/135470

## Summary
Previously, the suggestions/available options for the options list
control were manually built via individual `EuiFilterSelectItem`
components. While this worked well enough, it had a major `a11y` pitfall
- suggestions could only be navigated using `tab` rather than the up and
down arrow keys as expected.

This PR changes this behaviour to use `EuiSelectable` for managing and
displaying the suggestions instead, which has the following benefits:
1. Most importantly, `a11y` is significantly improved by allowing
navigation using the keyboard
2. A scrollbar is added to the options list popover - this makes it a
lot easier to manage since, between adding the footer to the popover and
adding the `exists` option, the popover was getting... rather unruly

![BeforeAndAfterVirtualization](https://user-images.githubusercontent.com/8698078/210903704-199f2953-e1e8-49c2-864d-4334f1da62a0.png)
3. The resulting `options_list_popover_suggestions.tsx` code is, in my
opinion, a bit easier to follow

This PR also fixes three small bugs:
1. The loading state was set to `false` for rejected requests, which
caused an early return of `No results` when typing quickly into the
search bar - see
https://github.com/elastic/kibana/pull/148420#discussion_r1064986896 for
more details.
2. When `singleSelect` was `true`, selecting `Exists` followed by a
different selection would not unselect `Exists`.
3. When `singleSelect` was `true`, selections could not be undone unless
`showOnlySelected` was `true`.

### Video of Keyboard Controls


https://user-images.githubusercontent.com/8698078/211362869-0b5f90ec-4784-4744-8de9-5c2881bfa7a9.mov


### Flaky Test Runners

-
`test/functional/apps/dashboard_elements/controls/options_list/options_list_dashboard_integration.ts`<br>
<a
href="https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1733"><img
src="https://user-images.githubusercontent.com/8698078/212110506-f05ba031-7328-4995-b929-d56c72d694ff.png"/></a>
This was the offending test suite that was causing all sorts of
flakiness, so I wanted to test it both on its own and as part of the
other controls tests - so, in combination with the below flaky test run,
this test suite was run 200 times successfully. Should **hopefully**
mean this thing is no longer flaky 🤞

- `test/functional/apps/dashboard_elements/controls/options_list/*`<br>
<a
href="https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1741"><img
src="https://user-images.githubusercontent.com/8698078/212143963-28856da0-d1ae-4b3f-801a-c96f8780e48b.png"/></a>

-
`test/functional/apps/dashboard_elements/controls/control_group_chaining.ts`<br>
<a
href="https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1744"><img
src="https://user-images.githubusercontent.com/8698078/212158041-a381ddb4-8b79-42b6-8b64-edd96cda262e.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] 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))

![BeforeAfterAxeFailures](https://user-images.githubusercontent.com/8698078/211360345-e9dea3c8-1068-41f7-bea3-921c9119afc2.png)
- [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>
2023-01-16 11:25:28 -07:00
Hannah Mudge
37a6636654
[Dashboard] [Controls] Show document count beside options list suggestions (#146241)
Closes https://github.com/elastic/kibana/issues/145039

## Summary

This PR adds a badge beside each options list suggestion that displays
how many document that value appears in.



https://user-images.githubusercontent.com/8698078/209020139-e0f16eae-6643-432b-9c40-f1a52fc7adf4.mov


Note that, in the above video, clicking `"Show only selected"` removes
the badge regardless of the validity of the selection. As described in
https://github.com/elastic/kibana/pull/144867#issuecomment-1320522731
and the related discussion, it is theoretically possible to still show
this badge, thus allowing sorting even when `"Show only selected"` is
`on`. However, my investigation into this took me on the following
journey:
1. Document count **should not** be stored as part of the
`explicitInput`, so `selections` should remain a string array
2. To get around this, the document count could be stored as part of the
`validSelections` instead, which is part of the component state. That
is, `validSelections` would be an `OptionsListSuggestions` object rather
than a string array
3. To make (2) happen, we would need to add a secondary API endpoint
specifically for translating the `explicitInput` selections array to the
`validSelections` object

After realizing (3), it became obvious that adding sorting support to
`"Show only selected"` was probably not worth the code complexity that
is required - so, at least until we get requests for this feature, I
opted to not include it as part of this PR. After all, `"Show only
selected"` is ultimately meant to make it easier to deselect/manage your
selections, so showing the document count + allowing sorting in this
case doesn't have much of an impact. For the same reasons, searching is
also disabled when `"Show only selected"` is `on`:

<p align="center"><img
src="https://user-images.githubusercontent.com/8698078/209021944-c57ea04f-1278-4b6d-ae65-88b2591ba9d6.gif"/></p>

> **Note**
> The above screenshots and videos are slightly out-of-date. Refer to
https://github.com/elastic/kibana/pull/146241#issuecomment-1370125632 to
see how the design of the document count was changed to reduce visual
clutter.


### Flaky Test Runner

- `control_group_chaining.ts`
<a
href="https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1669"><img
src="https://user-images.githubusercontent.com/8698078/209016909-cb2cebf4-b069-4270-977b-a64a320d398d.png"/></a>
- `options_list.ts`
<a
href="https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1670"><img
src="https://user-images.githubusercontent.com/8698078/209020916-f322bfdb-799d-4aab-9726-9f46e130e779.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))
- [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>
2023-01-03 16:05:21 -07:00
Hannah Mudge
7a6eac8d1b
[Dashboard] [Controls] Allow control changes to be discarded (#147482)
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)
2022-12-19 14:55:31 -07:00
Hannah Mudge
6a1b37e5fd
[Dashboard] [Controls] Remove options list "Allow <x>" toggles (#147216)
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:


![image](https://user-images.githubusercontent.com/8698078/206319266-84377dd8-8e53-4680-81f3-60e7b33ba15e.png)


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


![image](https://user-images.githubusercontent.com/8698078/206319041-bdb8d28f-4f70-4ac9-a2d2-87600b0db66b.png)


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

![TwoOptionsListControls](https://user-images.githubusercontent.com/8698078/206320381-4aad9c78-0bb0-4d30-b7f7-3dc3e6b7b2a2.png)
 
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:


![MultipleControlTypes](https://user-images.githubusercontent.com/8698078/206321542-8a9943ce-bf87-4de7-94fe-7ee370b92a23.png)


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>
2022-12-14 15:03:21 -07:00
Hannah Mudge
1ed31e1e76
[Dashboard] [Controls] Allow options list suggestions to be sorted (#144867)
Closes https://github.com/elastic/kibana/issues/140174
Closes https://github.com/elastic/kibana/issues/145040
Closes https://github.com/elastic/kibana/issues/146086 

## Summary

This PR adds two features to the options list control:
1. A button in the options list popover that gives users the ability to
change how the suggestions are sorted
    <p align="center">
<img
src="https://user-images.githubusercontent.com/8698078/203416853-58f9c909-8909-4902-adf3-59831018c96f.gif"/>
    </p>

2. A per-control setting that disables the ability to dynamically sort
which, if set to `false`, presents the author with the ability to select
one of the four sorting methods for that specific control to use
    <p align="center">
<img
src="https://user-images.githubusercontent.com/8698078/203417193-cd35f264-8c29-4c80-b88b-15da25a1f56c.gif"/>
    </p>

### Design considerations
@elastic/kibana-design 

As noted by Andrea when looking at the preliminary behaviour of this
feature, the `"Show only selected"` toggle has increased in importance
because of the new sorting mechanic - after all, when making selections
and then changing the sort method, your selections can appear to be
"lost" if you have enough unique values in the control's field.

In the original designs, the `"Clear all selections"` button was
**first** in the popover's action bar - however, I found that I kept
accidentally clicking this in my testing when switching between
searching, sorting, making selections, changing sorting, showing only
selected options, etc. etc. I found that the following design felt a lot
more natural for the placement of the `"Clear all selections"` button:


![image](https://user-images.githubusercontent.com/8698078/202318768-cf8a5668-40c4-482f-9eb0-023508866068.png)

Note that, once https://github.com/elastic/kibana/issues/143585 is
resolved, this will no longer be as much of a concern because we will be
moving, at the very least, the `"Clear all selections"` to be a floating
action. That being said, this new order for the actions is, in my
opinion, a good compromise in the mean time. Very much open to feedback,
though!

### Video 


https://user-images.githubusercontent.com/8698078/203422674-52aac87c-7295-4eb6-99a5-ee3ffba2756b.mov


### Testing Notes
There are a few things to consider when testing:
1. Does the dynamic sorting give you expected results when sorting
various field types?
- Note that IP fields only support document count sorting, so ensure
that "Alphabetical" sorting does not show up in the sorting list during
either creation or as part of the popover sorting.
2. When setting the `"Allow suggestions to be sorted"` toggle to
`false`, it should always default to `"Document count (descending)"` to
prevent invalid sort selections. For example, consider the following:
    - Create an options list control on some keyword field
- Set the sort to alphabetical (either ascending or descending) in the
popover
    - Edit that control and change it to an IP field
    - Set `"Allow suggestions to be sorted"` to `false
- The default sort should be `"Document count (descending)"` and **not**
`"Alphabetical (descending/ascending)"`, since alphabetical sorting
would be invalid in this case.

**Flaky Test Runner**
<a
href="https://buildkite.com/elastic/kibana-flaky-test-suite-runner/builds/1585"><img
src="https://user-images.githubusercontent.com/8698078/203428246-13f5ff9a-df0c-4cd5-a4ee-cf7a98792362.png"/></a>



### Checklist

Delete any items that are not applicable to this PR.

- [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] 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))
<p><img
src="https://user-images.githubusercontent.com/8698078/202545715-96daa0ab-8900-45cb-979f-20a83e622597.png"/></p>
- [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>
2022-11-24 12:46:47 -07:00
Nathan Reese
b74137ee51
[controls] fix timeslider control not filtering dashboard panels (#145184)
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>
2022-11-15 08:16:35 -07:00
Hannah Mudge
a30e6c2555
[Dashboard] [Controls] Add "Exists" functionality to options list (#143762)
* 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
2022-11-04 14:08:07 -07:00
Hannah Mudge
7dd7a74820
[Dashboard] [Controls] Add excludes toggle to options list (#142780)
* 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
2022-10-25 09:50:20 -07:00
Nathan Reese
ddcae9cfcf
[Controls] timeslider control (#139228)
* 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>
2022-09-07 11:21:53 -06:00
Hannah Mudge
8de3401dff
[Controls] Field first control creation (#131461)
* 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>
2022-05-19 09:12:00 -07:00
Catherine Liu
6375d90683
[Controls] Decouple control fixed width and auto size settings (#131769)
* 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>
2022-05-17 11:30:25 -07:00
Corey Robertson
25d4fdd6df
[Input Controls] Enable new input controls by default (#131341)
* Enable new input controls by default

* Fix snapshot tests

* Stop controls callout appearing on reports
2022-05-17 13:14:11 -04:00
Hannah Mudge
595522b5c2
[Controls] [Dashboard] Allow existing controls to change type (#129385)
* 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
2022-05-12 11:36:40 -07:00
spalger
3730dd0779 fix all violations 2022-04-16 01:37:30 -05:00
Catherine Liu
ba6be79adb
[Controls] Range slider (#125584)
* Adds range slider control

Fix ts error

Fix ref type error

Extracted i18n strings

Fixed number rounding

Fixed missing i18n string

Add loading state to range slider control output

Remove unnecessary change

Fix i18n errors

Apply formatter to range slider tick labels

* Apply comment updates from code review

Co-authored-by: Devon Thomson <devon.thomson@elastic.co>

* Remove extra fetches

* set min width for panel

* Fix functional tests

* Fixed controls page object

Co-authored-by: Devon Thomson <devon.thomson@elastic.co>
Co-authored-by: andreadelrio <andrea.delrio@elastic.co>
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
2022-03-28 14:06:47 -07:00
Devon Thomson
d202b73da7
[Controls] Select Relevant Data View ID (#128440)
Get relevant data view id when creating control
2022-03-28 11:51:19 -04:00
Devon Thomson
82d4cd56dc
[Dashboard][Controls] Add Control Group Search Settings (#128090)
* Added ability to toggle hierarchical chaining, control validation, and query bar sync to the Control Group
2022-03-23 18:28:39 -04:00
Hannah Mudge
c9dfe16725
[Controls] Improve controls management UX (#127524)
* 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
2022-03-21 13:59:54 -07:00
Hannah Mudge
fe34af7bc0
[Controls] Conditionally hide settings that only make sense when at least one control (#127932)
* Make some settings conditional on control count

* Add functional tests for control group settings

* Remove unnecessary string
2022-03-18 14:02:02 -06:00
Hannah Mudge
b2cd94df7b
[Controls] Improve controls empty state (#125728)
* 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
2022-03-09 12:04:27 -07:00
Devon Thomson
825ea5b919
[Controls] Move Controls To Their Own Plugin (#121668)
* Moved controls out of Presentation Util and into their own plugin
2022-01-06 13:33:52 -05:00
Devon Thomson
bf2779c708
added functional tests for dashboard controls integration (#119755) 2021-12-06 13:58:33 -05:00