-
Notifications
You must be signed in to change notification settings - Fork 8.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ES|QL] Creates charts from the dashboard (#171973)
## Summary Closes #165928 Enables the creation of ES|QL charts from the dashboard. ![esql](https://github.com/elastic/kibana/assets/17003240/86dd5594-d130-4fb7-b495-29ddbaee5e5b) The implementation is using UIActions which I think is the correct way to register a new panel action to a dashboard. Lens is responsible to register the ESQL panel action and owns the code. ### How it works - A new ES|QL panel has been added to the dashboard toolbar registered by a ui action - A new panel is been created with a default esql query `from <default_dataview_index_pattern> | limit 10` - This results to a datatable and opens the flyout - If a user clicks cancel then the embeddable is being removed ### Checklist - [ ] 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) - [ ] [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/)) - [ ] 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)) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
- Loading branch information
1 parent
cdb1047
commit 0503b82
Showing
29 changed files
with
663 additions
and
34 deletions.
There are no files selected for viewing
40 changes: 40 additions & 0 deletions
40
src/plugins/dashboard/public/dashboard_app/top_nav/add_panel_action_menu_items.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import { getAddPanelActionMenuItems } from './add_panel_action_menu_items'; | ||
|
||
describe('getAddPanelActionMenuItems', () => { | ||
it('returns the items correctly', async () => { | ||
const registeredActions = [ | ||
{ | ||
id: 'ACTION_CREATE_ESQL_CHART', | ||
type: 'ACTION_CREATE_ESQL_CHART', | ||
getDisplayName: () => 'Action name', | ||
getIconType: () => 'pencil', | ||
getDisplayNameTooltip: () => 'Action tooltip', | ||
isCompatible: () => Promise.resolve(true), | ||
execute: jest.fn(), | ||
}, | ||
]; | ||
const items = getAddPanelActionMenuItems(registeredActions, jest.fn(), jest.fn(), jest.fn()); | ||
expect(items).toStrictEqual([ | ||
{ | ||
'data-test-subj': 'create-action-Action name', | ||
icon: 'pencil', | ||
name: 'Action name', | ||
onClick: expect.any(Function), | ||
toolTipContent: 'Action tooltip', | ||
}, | ||
]); | ||
}); | ||
|
||
it('returns empty array if no actions have been registered', async () => { | ||
const items = getAddPanelActionMenuItems([], jest.fn(), jest.fn(), jest.fn()); | ||
expect(items).toStrictEqual([]); | ||
}); | ||
}); |
52 changes: 52 additions & 0 deletions
52
src/plugins/dashboard/public/dashboard_app/top_nav/add_panel_action_menu_items.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
import type { ActionExecutionContext, Action } from '@kbn/ui-actions-plugin/public'; | ||
import type { EmbeddableFactory } from '@kbn/embeddable-plugin/public'; | ||
import { addPanelMenuTrigger } from '../../triggers'; | ||
|
||
const onAddPanelActionClick = | ||
(action: Action, context: ActionExecutionContext<object>, closePopover: () => void) => | ||
(event: React.MouseEvent) => { | ||
closePopover(); | ||
if (event.currentTarget instanceof HTMLAnchorElement) { | ||
if ( | ||
!event.defaultPrevented && // onClick prevented default | ||
event.button === 0 && | ||
(!event.currentTarget.target || event.currentTarget.target === '_self') && | ||
!(event.metaKey || event.altKey || event.ctrlKey || event.shiftKey) | ||
) { | ||
event.preventDefault(); | ||
action.execute(context); | ||
} | ||
} else action.execute(context); | ||
}; | ||
|
||
export const getAddPanelActionMenuItems = ( | ||
actions: Array<Action<object>> | undefined, | ||
createNewEmbeddable: (embeddableFactory: EmbeddableFactory) => void, | ||
deleteEmbeddable: (embeddableId: string) => void, | ||
closePopover: () => void | ||
) => { | ||
return ( | ||
actions?.map((item) => { | ||
const context = { | ||
createNewEmbeddable, | ||
deleteEmbeddable, | ||
trigger: addPanelMenuTrigger, | ||
}; | ||
const actionName = item.getDisplayName(context); | ||
return { | ||
name: actionName, | ||
icon: item.getIconType(context), | ||
onClick: onAddPanelActionClick(item, context, closePopover), | ||
'data-test-subj': `create-action-${actionName}`, | ||
toolTipContent: item?.getDisplayNameTooltip?.(context), | ||
}; | ||
}) ?? [] | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
|
||
import type { UiActionsStart } from '@kbn/ui-actions-plugin/public'; | ||
|
||
export interface DashboardUiActionsService { | ||
getTriggerCompatibleActions?: UiActionsStart['getTriggerCompatibleActions']; | ||
} |
17 changes: 17 additions & 0 deletions
17
src/plugins/dashboard/public/services/ui_actions/ui_actions_service.stub.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0 and the Server Side Public License, v 1; you may not use this file except | ||
* in compliance with, at your election, the Elastic License 2.0 or the Server | ||
* Side Public License, v 1. | ||
*/ | ||
import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; | ||
import { PluginServiceFactory } from '@kbn/presentation-util-plugin/public'; | ||
import { DashboardUiActionsService } from './types'; | ||
|
||
export type UIActionsServiceFactory = PluginServiceFactory<DashboardUiActionsService>; | ||
|
||
export const uiActionsServiceFactory: UIActionsServiceFactory = () => { | ||
const pluginMock = uiActionsPluginMock.createStartContract(); | ||
return { getTriggerCompatibleActions: pluginMock.getTriggerCompatibleActions }; | ||
}; |
Oops, something went wrong.