Commit graph

25 commits

Author SHA1 Message Date
Devon Thomson
3e882d8cd9
[Embeddables] Serialized State Only (#215947)
Closes https://github.com/elastic/kibana/issues/205531
Closes #219877.
Closes https://github.com/elastic/kibana/issues/213153
Closes https://github.com/elastic/kibana/issues/150920
Closes https://github.com/elastic/kibana/issues/203130
 
### Overview
The embeddable framework has two types of state: `SerializedState` and
`RuntimeState`.

`SerializedState` is the form of the state when saved into a Dashboard
saved object. I.e. the References are extracted, and state saved
externally (by reference) is removed. In contrast `RuntimeState` is an
exact snapshot of the state used by the embeddable to render.

<b>Exposing SerializedState and RuntimeState was a mistake</b> that
caused numerous regressions and architectural complexities.

This PR simplifies the embeddable framework by only exposing
`SerializedState`. `RuntimeState` stays localized to the embeddable
implementation and is never leaked to the embeddable framework.

### Whats changed
* `ReactEmbeddableFactory<SerializedState, RuntimeState, Api>` =>
`EmbeddableFactory<SerializedState, Api>`
* `deserializeState` removed from embeddable factory. Instead,
`SerializedState` is passed directly into `buildEmbeddable`.
* `buildEmbeddable` parameter `buildApi` replaced with `finalizeApi`.
`buildApi({ api, comparators })` => `finalizeApi(api)`.
* The embeddable framework previously used its knowledge of
`RuntimeState` to setup and monitor unsaved changes. Now, unsaved
changes setup is pushed down to the embeddable implementation since the
embeddable framework no longer has knowledge of embeddable RuntimeState.

### Reviewer instructions
<b>Please prioritize reviews.</b> This is a large effort from our team
and is blocking many other initiatives. Getting this merged is a top
priority.

This is a large change that would best be reviewed by manually testing
the changes
* adding/editing your embeddable types
* Ensuring dashboard shows unsaved changes as expected
* Ensuring dashboard resets unsaved changes as expected
* Ensuring dashboard does not show unsaved changes after save and reset
* Returning to a dashboard with unsaved changes renders embeddables with
those unsaved changes

---------

Co-authored-by: Hannah Mudge <Heenawter@users.noreply.github.com>
Co-authored-by: Nathan Reese <reese.nathan@elastic.co>
Co-authored-by: Nick Peihl <nick.peihl@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: Catherine Liu <catherine.liu@elastic.co>
Co-authored-by: Ola Pawlus <98127445+olapawlus@users.noreply.github.com>
2025-05-06 15:08:34 -06:00
Nathan Reese
05916056cd
[embeddable] make presentation interface names consistent (#205279)
PR cleans up presentation interface names for consistentency
* adds `$` suffix to all observables. For example, `dataLoading` =>
`dataLoading$`
* removes `Panel` naming convention from interface names since an api
may not be a panel, an api may be a dashboard. For example,
`PublisesPanelTitle` => `PublishesTitle`

#### Note to Reviewers
Pay special attention to any place where your application creates an
untyped API. In the example below, there is no typescript violation when
the parent returns `dataLoading` instead of `dataLoading$` since the
parent is not typed as `PublishesDataLoading`. Please check for
instances like these.

```
<ReactEmbeddableRenderer
  getParentApi={() => {
    dataLoading: new BehaviorSubject()
  }}
/>
```

---------

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
2025-01-22 10:46:01 -06:00
Catherine Liu
b80980694a
[Embeddable] EUI Visual Refresh Integration (#204452)
## Summary

Related to https://github.com/elastic/kibana/issues/203132.
Part of [#204596](https://github.com/elastic/kibana/issues/204596).

This replaces all references to euiThemeVars in favor of the useEuiTheme
hook.

### Checklist

Check the PR satisfies following conditions. 

Reviewers should verify this PR satisfies this list as well.

- [ ] 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
- [ ] 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 was checked for breaking HTTP API changes, and any breaking
changes have been approved by the breaking-change committee. The
`release_note:breaking` label should be applied in these situations.
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [ ] The PR description includes the appropriate Release Notes section,
and the correct `release_note:*` label is applied per the
[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

### Identify risks

Does this PR introduce any risks? For example, consider risks like hard
to test bugs, performance regression, potential of data loss.

Describe the risk, its severity, and mitigation for each identified
risk. Invite stakeholders and evaluate how to proceed before merging.

- [ ] [See some risk
examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx)
- [ ] ...

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
2024-12-19 10:12:09 -08:00
Luke Elmers
b6287708f6
Adds AGPL 3.0 license (#192025)
Updates files outside of x-pack to be triple-licensed under Elastic
License 2.0, AGPL 3.0, or SSPL 1.0.
2024-09-06 19:02:41 -06:00
Larry Gregory
74d88580a5
Migrate codebase to use Object.hasOwn instead of Object.hasOwnProperty (#186829)
## Summary

This PR has breadth, but not depth. This adds 3 new `eslint` rules. The
first two protect against the use of code generated from strings (`eval`
and friends), which will not work client-side due to our CSP, and is not
something we wish to support server-side. The last rule aims to prevent
a subtle class of bugs, and to defend against a subset of prototype
pollution exploits:

- `no-new-func` to be compliant with our CSP, and to prevent code
execution from strings server-side:
https://eslint.org/docs/latest/rules/no-new-func
- `no-implied-eval` to be compliant with our CSP, and to prevent code
execution from strings server-side:
https://eslint.org/docs/latest/rules/no-implied-eval. Note that this
function implies that it prevents no-new-func, but I don't see [test
cases](https://github.com/eslint/eslint/blob/main/tests/lib/rules/no-implied-eval.js)
covering this behavior, so I think we should play it safe and enable
both rules.
- `no-prototype-builtins` to prevent accessing shadowed properties:
https://eslint.org/docs/latest/rules/no-prototype-builtins


In order to be compliant with `no-prototype-builtins`, I've migrated all
usages and variants of `Object.hasOwnProperty` to use the newer
[`Object.hasOwn`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn).
2024-08-13 10:30:19 -05:00
Eyo O. Eyo
22e0545d0e
Redesign the "Add Panel" Experience (#183764)
## Summary

Closes https://github.com/elastic/kibana/issues/144418

This PR introduces changes to the dashboard add panel selection
functionality, so that panel selection would now happen from within a
flyout, and as such panels are now grouped together logically.

With this implementation any panel that is intended to show up within
this new flyout is required to have either been registered leveraging
the ui action trigger `ADD_PANEL_TRIGGER` and have it's `grouping` value
defined or belong to a subset of visualization types (`PROMOTED`,
`TOOLS`, and `LEGACY`) that would automatically get grouped.

It's worth pointing out that because we can't control the order at which
UI actions gets registered, we won't always get the the panel groups in
the same order, for this specific reason ~a new optional property
(`placementPriority`) has been added in~ the property `order` is now
leveraged such that it allows a user registering a UI action define a
relative weight for where they'd like their group to show up. All
registered actions would be rendered in descending order considering all
`order` defined, in the case where no order is defined `0` is assumed
for the group. In addition an action which is registered without a
group, would automatically get assigned into a default group titled
"Other".

The search implemented within the add panel is rudimentary, checking if
the group titles and group item titles contain the input character; when
a group title is matched the entire group is remains highlighted, in the
case that the group isn't matched and it's just the group item, only
said item is highlighted within it's group.

## Visuals

#### Default view
<img width="2560" alt="Screenshot 2024-06-10 at 17 44 17"
src="90aadf82-684a-4263-aecd-2843c3eff3c1">


#### Search match view
<img width="2560" alt="Screenshot 2024-06-10 at 17 45 11"
src="5a766f29-a3b7-40e3-b1f7-8b423073cd87">


##### P.S.

This changes also includes changes to the display of certain panels;
- ML group has a new title i.e. *Machine Learning and Analytics*
- In serverless, the observability panels (SLO*) only shows as a
selection choice in the observability project type.


### 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)
<!--
- [ ]
[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)
was added for features that require explanation or tutorials
- [ ] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed
- [ ] 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)
-->
- [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)


<!--
### 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&mdash;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&mdash;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: Catherine Liu <catherine.liu@elastic.co>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
2024-06-26 13:55:28 -07:00
Devon Thomson
6d39b8a432
[Embeddables Rebuild] Fix runtime state types. (#186194)
Fixes runtime state types, requiring them to be specified twice.
2024-06-19 10:05:27 -04:00
Nathan Reese
f8c582da25
[canvas] fix parent API should implement unified search interface with react embeddables (#183772)
Closes https://github.com/elastic/kibana/issues/183766

### test instructions
1. start kibana with `yarn start --run-examples`
2. install sample web logs data set
3. create new canvas work pad
4. Click "Add element" -> "Filter" -> "Dropdown select"
5. Select "data" tab and configure filter to pull from logs sample data
and `machine.os.keyword` field.
6. Select "display" tab and "Value column" and "Filter column" to
`machine.os.keyword`.
7. Click "Add element" -> "Filter" -> "Time filter"
9. Click "Select type" -> "Search example"
10. Click panel context menu -> "Settings" and turn off custom time
range
11. Click "Expression editor" button in lower right corner to open the
expression editor for the map and prefix the expression with `kibana |
selectFilter | embeddable`
<img width="500" alt="Screenshot 2024-05-17 at 11 50 42 AM"
src="453096d5-c254-4f43-a09c-386586aa05a1">
12. Interact with drop down filter and time range filter. Verify Search
react embeddable updates as expected
2024-05-22 11:01:29 -06:00
Devon Thomson
53435eace3
[Embeddables rebuild] Support for by reference embeddables (#182523)
Adds first-class by reference support to the new Embeddable framework and adds an example of how a new-styled by reference embeddable could work.
2024-05-21 16:37:31 -04:00
Nathan Reese
3ecd73c2e5
embeddable overview guiding principles and best practices (#183099)
Paired with @ThomThomson to expand Embeddable documentation with
"Guiding principles" and "Best practices"

PR also moves overview to src/plugins/embeddables/README.md. Then, this
markdown is displayed in the embeddable example application as well.

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Devon Thomson <devon.thomson@elastic.co>
2024-05-14 12:03:45 -06:00
Devon Thomson
6584663bf6
[Embeddable] Move registries (#182621)
Moves the React Embeddable registry, and saved object to panel registries onto the embeddable start / setup contracts
2024-05-10 12:42:34 -04:00
Devon Thomson
102c207025
[Embeddables Rebuild] Example aesthetics (#181920)
Slight aesthetic changes to the example embeddables
2024-04-29 15:28:48 -04:00
Devon Thomson
89b7a65426
[Embeddables Rebuild] Restrict types & remove per panel versioning (#181751)
Removes per-panel versioning and makes a few changes to further lock down types to make the new embeddable system more consistent and less error-prone.
2024-04-29 13:43:17 -04:00
Devon Thomson
98d2ab2e1a
[Embeddables Rebuild] Data table example (#181768)
Adds a new data table example that shows how embeddables can interact with their siblings
2024-04-26 16:12:30 -04:00
Nathan Reese
438f623f3d
Add "Register new embeddable type" to Embeddable tutorial (#181761)
PR adds "Register new embeddable type" section to Embeddable tutorial
<img width="600" alt="Screenshot 2024-04-25 at 12 25 59 PM"
src="075c534b-0b1b-4600-a057-d601d09da5d1">

PR also groups example embeddables to make them easier to find
<img width="600" alt="Screenshot 2024-04-25 at 12 26 12 PM"
src="82d55fca-bbe8-4b63-a80e-dd052307d7e5">

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
2024-04-26 12:02:48 -06:00
Nathan Reese
60ab2cfe95
PresentationPanel props hidePanelChrome (#181473)
### Changes
1. adds `hidePanelChrome` parameter to `ReactEmbeddableRenderer`. When
true, embeddable is rendered without `PresentationPanel` wrapper
2. Removes `embeddable-explorer` plugin
3. Moves Embeddable developer example into embeddable_examples plugin
4. Creates new examples that demonstrate how to use
`ReactEmbeddableRenderer`
<img width="600" alt="Screenshot 2024-04-23 at 5 19 18 PM"
src="5167a2a4-1968-42e6-92f7-4577c9cda3c6">

Follow-up work to narrow scope of this PR
1. add key concepts to embeddable overview
2. add "Register new embeddable type" tab that details how to create a
new embeddable and shows how you can add embeddable examples to
dashboard
3. group embeddable examples into a single item in "Add panel" menu - to
show best practices of how to keep menu clean
4. remove class based example embeddables

### Test instructions
1. start kibana with `yarn start --run-examples`
5. Open kibana menu and click "Developer examples"
6. Click "Embeddables" card and run examples

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
2024-04-24 14:05:19 -06:00
Nathan Reese
46cb23a80d
Update SearchReactEmbeddable example to use sessionId and abortSignal (#181249)
Fixes https://github.com/elastic/kibana/issues/181199

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
2024-04-23 08:07:33 -06:00
Nathan Reese
1c38891dfc
[embeddable rebuild] change onFetchContextChanged from accepting callback to returning an observable (#180410)
Closes https://github.com/elastic/kibana/issues/180363

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
2024-04-11 13:45:22 -06:00
Devon Thomson
3a1936f81f
[Embeddables Rebuild] Clean up parenting structure (#179769)
Significantly cleans up the PresentationContainer interface by adding a `children$` publishing subject.
2024-04-05 13:37:53 -04:00
Nathan Reese
e23335ba8b
[embeddable refactor] complete fetch context interface (#179776)
Closes https://github.com/elastic/kibana/issues/179838

1. define `PublishesSearchSource` interface
2. define `PublishesReload` interface
3. Add optional `timeslice$` to `PublishesTimeRange` interface
4. Update `DashboardContainer` to implement `PublishesSearchSource`,
`PublishesReload`, and `PublishesTimeRange` interfaces
5. `onFetchContextChanged` utility method created to consolidate fetch
context logic into a single re-usable component.

### Test instructions
1. Start kibana with `yarn start --run-examples`
2. Install sample web logs data set
3. create new dashboard, add `Unified search example` panel
4. Change time range, filters, search and verify panel fetches count for
narrowed data range
5. add timeslider control and advance timeslider, verify panel fetches
count for timeslice
6. Click reload, verify panel reloads count

---------

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
2024-04-04 20:57:03 -06:00
Hannah Mudge
4cc61b98e1
[Embeddable Rebuild] Make React embeddables work in Canvas (#179667)
Closes https://github.com/elastic/kibana/issues/179548

## Summary

This PR makes it so that React embeddables will now work in Canvas. It
does so by doing two main things:

1. It ensures that the `ReactEmbeddableRenderer` is used in Canvas when
an embeddable exists in the React embeddable registry - if it does not
exist, it continues to use the legacy embeddable factory's `render`
method.

Since Canvas auto-applies all changes and doesn't have save
functionality like Dashboard does, we must keep track of changes **as
they happen** and update the expression to match the new Embeddable
input - therefore, I had to add a `onAnyStateChange` callback to the
`ReactEmbeddableRenderer` as a backdoor for Canvas. As a bonus to this,
embeddables that **previously** didn't respect inline editing (such as
the Image embeddable) will start to work once they are converted!


3. It adds a new trigger (`ADD_CANVAS_ELEMENT_TRIGGER`) specifically for
registering an embeddable to the **Canvas** add panel menu. This trigger
can be attached to the **same action** that the Dashboard
`ADD_PANEL_TRIGGER` is attached to - this makes it super simple to add
React embeddables to Canvas:
    
    ```typescript
    uiActions.registerAction<EmbeddableApiContext>({
      id: ADD_EMBEDDABLE_ACTION_ID,
      isCompatible: async ({ embeddable }) => { ... },
      execute: async ({ embeddable }) => { ... },
      getDisplayName: () => { ... },
    });

    // register this action to the Dashboard add panel menu:
uiActions.attachAction('ADD_PANEL_TRIGGER', ADD_EMBEDDABLE_ACTION_ID);

    // register this action to the Canvas add panel menu:
uiActions.attachAction('ADD_CANVAS_ELEMENT_TRIGGER',
ADD_EMBEDDABLE_ACTION_ID);
    ```

As a small cleanup, I also replaced some inline embeddable expressions
with `embeddableInputToExpression` - this is because I was originally
missing `| render` at the end of my expression, and I didn't catch it
because the expressions I was comparing it to were all declared inline.
This should help keep things more consistent.

### How to Test
I attached the `ADD_EUI_MARKDOWN_ACTION_ID` action to the new
`ADD_CANVAS_ELEMENT_TRIGGER`, so the new EUI Markdown React embeddable
should show up in the Canvas add panel menu. Ensure that this React
embeddable can be added to a workpad, and make sure it responds to edits
as expected:



d9062949-9c61-4c9e-8a8e-08042753eab6



### 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: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
2024-04-03 15:29:07 -07:00
Nathan Reese
61047aead0
[embeddable refactor] initializeTimeRange utility (#179379)
Move timeRange$ logic into reusable `initializeTimeRange` method.

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
2024-03-25 18:18:17 -06:00
Devon Thomson
b4e0a04af9
[Embeddables Rebuild] Async factories (#179302)
Changes the new Embeddable factory definition to take an async function instead of the factory object directly.
2024-03-25 15:44:57 -04:00
Devon Thomson
59b1f8ae94
[Embeddables Rebuild] Move titles API (#179202)
Moves the titles API and state comparators away from the embeddable plugin and to the presentation-publishing package.
2024-03-22 12:28:20 -04:00
Nathan Reese
85d243a059
[embeddable refactor] search react embeddable example (#178681)
Closes [178630](https://github.com/elastic/kibana/issues/178630)

To run examples, start kibana with `yarn start --run-examples`

PR adds "Unified search example" to Dashboard "Add panel" menu
<img width="400" alt="Screenshot 2024-03-13 at 9 33 22 PM"
src="d1edb4f5-ac1e-49bd-ad03-f624af74fff1">

Embeddable displays count with unified search context from dashboard.
Changing unified search and global time picker will cause search to
update
<img width="400" alt="Screenshot 2024-03-13 at 9 34 09 PM"
src="675b2c7d-9fc0-4173-aa67-354483593c09">

Embeddable also allows for setting custom time range on the panel
<img width="418" alt="Screenshot 2024-03-13 at 9 34 52 PM"
src="a79ea546-c4ce-4af5-8bb3-7be9cac7c02c">

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
2024-03-21 19:54:55 -06:00