Skip to content

[dashboards as code] drilldown schemas#249445

Merged
nreese merged 91 commits intoelastic:mainfrom
nreese:embeddable_drilldowns
Feb 4, 2026
Merged

[dashboards as code] drilldown schemas#249445
nreese merged 91 commits intoelastic:mainfrom
nreese:embeddable_drilldowns

Conversation

@nreese
Copy link
Copy Markdown
Contributor

@nreese nreese commented Jan 16, 2026

Part of #239425

Kibana-presentation team is working on "Dashboards as code" project. Dashboard REST API state contains drilldown state. This PR refactors drilldown state and provides schemas for drilldown state.

Before

In the image below, notice how drilldown state is passed as { enhancements: { dynamicActions: events: [ { ...messyStateWithClassStructures } ] } }. This shape leaks Kibana registry design and class structures into dashboards as code REST API.
Screenshot 2026-01-21 at 4 27 31 PM

After

In the image below, notice how drilldown state is passed as { drilldowns: [ {...cleanState } ] }. Now the dashboards as code REST API does not leak Kibana registry design or class structures.
Screenshot 2026-01-27 at 12 18 32 PM

Overview of changes

  • EmbeddableServerSetup changes
    • Adds registerDrilldown, allowing drilldowns to register schemas and transforms.
    • Changes registerTransforms shape from { transformIn, transformOut, ...otherProps } to { getTransforms, ...otherProps }. This change is done to pass drilldownTransforms to embeddable transform implementations. drilldownTransforms is stateful because it uses the contents of drilldown registry.
    • Removes transformEnhancementsIn and transformEnhancementsOut from interface. Instead of exposing drilldown tranforms directly from EmbeddableServerSetup, drilldownTransforms is provided to embeddables as a prop to getTransforms
  • Registers schema and transforms for all drilldown types; dashboard_drilldown, discover_drilldown, and url_drilldown
  • Updates all usages of registerTransforms to provide { getTransforms, ...otherProps } instead of { transformIn, transformOut, ...otherProps }
  • Updates all usages of transformEnhancementsIn and transformEnhancementsOut to use drilldownTransforms

What this PR does not do

To limit scope as much as possible, this PR does not refactor client code to use the new drilldown format. As a stop gap, a translation layer is in place that converts drilldowns to enhancements. Then, on save, enhancements are converted back to drilldowns before sending state across the dashboard REST API. In a follow up PR(s), this translation layer will be removed and drilldown client code will be refactored to work directly with DrilldownsState

External team testing

If your embebbable type does not support drilldowns then there is nothing to test.

If your embeddable type does support drilldowns, then run the following

  • install your favorite data set or use one of the sample data sets that ship with kibana
  • Open dashboard application and create a new dashboard
  • Add a panel for your embeddable type
  • Add one or more drilldowns to this panel
  • Save dashboard
  • Inspect network requests (filtering by /api/dashboards). Notice that drilldowns are passed as drilldowns instead of enhancements.
  • Open dashboard and verify drilldowns still work as expected
  • Open dashboards with drilldowns created from 9.3 cloud instance and in sure drilldowns still function as expected.

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Jan 20, 2026

@elasticmachine merge upstream

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Jan 20, 2026

@elasticmachine merge upstream

@elasticmachine
Copy link
Copy Markdown
Contributor

merge conflict between base and head

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Jan 21, 2026

/ci

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Jan 21, 2026

/ci

@nreese
Copy link
Copy Markdown
Contributor Author

nreese commented Jan 22, 2026

@elasticmachine merge upstream


const drilldownsFromEnhancements = enhancements.dynamicActions.events
.map((event) => {
if (event.action.factoryId === 'DASHBOARD_TO_DASHBOARD_DRILLDOWN') {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wonder if we should be using constants instead of hard-coding the strings here? I see this constant is defined in the dashboard_enhanced plugin, but I expect that plugin will be removed in a subsequent PR?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I see this constant is defined in the dashboard_enhanced plugin, but I expect that plugin will be removed in a subsequent PR?

That is correct. BWC code should be isolated and not import from other places to ensure the functionality remains the same. In this case, dashboard_enhanced, will be removed when client gets migrated to drilldown schema.

For BWC, I think hard coded strings are more clear and since its BWC, we know the string value will never change so there is no advantage for a constant.

nreese added a commit that referenced this pull request Feb 3, 2026
…1337)

There is currently an issue in main where `findLensReference` does not
find a lens reference because the reference name is `panel_5` instead of
`savedObjectRef`. This causes the transform out to throw because
`savedObjectRef && isByRefLensState(state)` check fails and call to
`const migratedAttributes = migrateAttributes(state.attributes);`
throws.

I discovered this because
x-pack/platform/test/functional/apps/dashboard/group2/migration_smoke_tests/lens_migration_smoke_test.ts
started failing in #249445. With
#249445, throwing in lens
transforms prevents enhancements from getting converted to drilldowns so
the functional test fails because the lens state is `{ enhancements }`
instead of `{ drilldowns }`.

The root of the problem is that `transformPanelProperties` injects
by-reference reference. This is left over from client side injection.
The problem is resolved by transforming the reference to what transforms
expect and stop injecting references in `transformPanelProperties`.

---------

Co-authored-by: Devon Thomson <devon.thomson@elastic.co>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
@nreese nreese requested a review from davismcphee February 3, 2026 18:50
Comment on lines +105 to +108
// Do not change constan value - part of public REST API
export const DISCOVER_DRILLDOWN_TYPE = 'discover_drilldown';
// Only additive changes are allowed, part of public REST API
export const DISCOVER_DRILLDOWN_SUPPORTED_TRIGGERS = [APPLY_FILTER_TRIGGER];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great to have these comments.

@elasticmachine
Copy link
Copy Markdown
Contributor

elasticmachine commented Feb 3, 2026

⏳ Build in-progress, with failures

Failed CI Steps

Test Failures

  • [job] [logs] Jest Tests #22 / drilldown registry getSchemas should include triggers that intersect with supported triggers
  • [job] [logs] Jest Tests #22 / drilldown registry getSchemas should include triggers that intersect with supported triggers
  • [job] [logs] Jest Tests #7 / getTransformIn by reference should extract references
  • [job] [logs] Jest Tests #7 / getTransformIn by reference should extract references
  • [job] [logs] Jest Tests #7 / getTransformIn by value should extract references
  • [job] [logs] Jest Tests #7 / getTransformIn by value should extract references
  • [job] [logs] Jest Tests #7 / getTransformOut by reference should inject references
  • [job] [logs] Jest Tests #7 / getTransformOut by reference should inject references
  • [job] [logs] Jest Tests #7 / getTransformOut by value should inject references
  • [job] [logs] Jest Tests #7 / getTransformOut by value should inject references

History

Copy link
Copy Markdown
Contributor

@nickpeihl nickpeihl left a comment

Choose a reason for hiding this comment

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

lgtm! code review only.

Copy link
Copy Markdown
Contributor

@davismcphee davismcphee left a comment

Choose a reason for hiding this comment

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

Data Discovery changes LGTM 👍

Copy link
Copy Markdown
Contributor

@Dosant Dosant left a comment

Choose a reason for hiding this comment

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

i smoked checked image, url drilldowns. lgtm

Copy link
Copy Markdown
Contributor

@andrimal andrimal left a comment

Choose a reason for hiding this comment

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

Visualization changes LGTM!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: I think I would keep the index.ts to the transforms directory and export getTransformIn and getTransformOut from there. This would be consistent with other directories within lens and give us a cleaner import path.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I opted to directly import getTransformOut only because getTransform requires both transformDrilldownOut and trasnformDrilldownIn. In public, only transformDrilldownOut is available and only transformDrilldownOut is needed.

Copy link
Copy Markdown
Member

@qn895 qn895 left a comment

Choose a reason for hiding this comment

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

ML changes LGTM

@nreese nreese merged commit b2cd262 into elastic:main Feb 4, 2026
16 checks passed
nreese added a commit that referenced this pull request Feb 19, 2026
…hema types (#252976)

Follow up to #249445
Part of #239425

Kibana-presentation team is working on "Dashboards as code" project.
#249445 created a schema for
drilldowns and updated Dashboard REST API to use new schema defined
shape for drilldowns. #249445 did
not touch client code - leaving client code using old shape. This PR
takes the next step and refactors client code to use new schema defined
drilldowns shape.

### Overview of changes
* Decouples drilldowns from dynamic actions
* Moves registryDrilldown from uiActionsEnhanced plugin to embeddables
plugin
* Moves DrilldownsManager UI components from uiActionsEnhanced plugin to
embeddables plugin. The effort tried to change as little as possible in
DrilldownsManager UI components.
* Removes dashboardEnhanced plugin
* Moves createDrilldowns action and manageDrilldowns action registration
into embeddable plugin
    * Moves dashboard drilldown registation into drilldown plugin
* Removes emebbeddableEnhanced plugin
* Replaces `HasDynamicActions` interface with `HasDrilldown` interface
and moves this interface into embeddable plugin
* Replaces `initializeDynamicActionsManager` with
`initializeDrilldownsManager`
* Moves `initializeDrilldownsManager` as parameter passed to
`buildEmbeddable` instead of exposing via plugin start contract.
   * Updates all embeddables to `initializeDrilldownsManager` 
* Moves DiscoverDrilldown to embeddables plugin `registerDrilldown`
* Moves URLDrilldown to embeddables plugin `registerDrilldown`  

### What this PR does not do
The uiActionsEnhanced plugin can be removed now that drilldowns no
longer use dynamic actions. This is clean up work that will occur in
future efforts. URLDrilldown is still very intertwined with
uiActionsEnhancement plugin. These 2 plugins will need to be separated
in future work.

### Embeddable owner test instructions
* Create new dashboard
* add your embeddable panel
* add drilldowns. Ensure they work as expected

### Drilldown owner test instructions
* Create new dashboard
* add an embeddable panel that supports your drilldown type
* add drilldowns. Ensure they work as expected

---------

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Anton Dosov <dosantappdev@gmail.com>
ersin-erdal pushed a commit to ersin-erdal/kibana that referenced this pull request Feb 19, 2026
…hema types (elastic#252976)

Follow up to elastic#249445
Part of elastic#239425

Kibana-presentation team is working on "Dashboards as code" project.
elastic#249445 created a schema for
drilldowns and updated Dashboard REST API to use new schema defined
shape for drilldowns. elastic#249445 did
not touch client code - leaving client code using old shape. This PR
takes the next step and refactors client code to use new schema defined
drilldowns shape.

### Overview of changes
* Decouples drilldowns from dynamic actions
* Moves registryDrilldown from uiActionsEnhanced plugin to embeddables
plugin
* Moves DrilldownsManager UI components from uiActionsEnhanced plugin to
embeddables plugin. The effort tried to change as little as possible in
DrilldownsManager UI components.
* Removes dashboardEnhanced plugin
* Moves createDrilldowns action and manageDrilldowns action registration
into embeddable plugin
    * Moves dashboard drilldown registation into drilldown plugin
* Removes emebbeddableEnhanced plugin
* Replaces `HasDynamicActions` interface with `HasDrilldown` interface
and moves this interface into embeddable plugin
* Replaces `initializeDynamicActionsManager` with
`initializeDrilldownsManager`
* Moves `initializeDrilldownsManager` as parameter passed to
`buildEmbeddable` instead of exposing via plugin start contract.
   * Updates all embeddables to `initializeDrilldownsManager` 
* Moves DiscoverDrilldown to embeddables plugin `registerDrilldown`
* Moves URLDrilldown to embeddables plugin `registerDrilldown`  

### What this PR does not do
The uiActionsEnhanced plugin can be removed now that drilldowns no
longer use dynamic actions. This is clean up work that will occur in
future efforts. URLDrilldown is still very intertwined with
uiActionsEnhancement plugin. These 2 plugins will need to be separated
in future work.

### Embeddable owner test instructions
* Create new dashboard
* add your embeddable panel
* add drilldowns. Ensure they work as expected

### Drilldown owner test instructions
* Create new dashboard
* add an embeddable panel that supports your drilldown type
* add drilldowns. Ensure they work as expected

---------

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Anton Dosov <dosantappdev@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting Feature:Embedding Embedding content via iFrame Project:Dashboards API release_note:skip Skip the PR/issue when compiling release notes Team:obs-ux-management Team:Presentation Presentation Team for Dashboard, Input Controls, and Canvas t// v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.