-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Dashboard] Makes lens default editor for creating new panels #96181
Changes from all commits
c420000
8a90b53
e12deec
28aae73
108062f
8ea0de6
c4af900
a637f79
25aaf6c
b092b03
d54c065
86814d8
fdfea24
58e5eeb
cd53b78
092a721
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [getDescription](./kibana-plugin-plugins-embeddable-public.embeddablefactory.getdescription.md) | ||
|
||
## EmbeddableFactory.getDescription() method | ||
|
||
Returns a description about the embeddable. | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
getDescription(): string; | ||
``` | ||
<b>Returns:</b> | ||
|
||
`string` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [getIconType](./kibana-plugin-plugins-embeddable-public.embeddablefactory.geticontype.md) | ||
|
||
## EmbeddableFactory.getIconType() method | ||
|
||
Returns an EUI Icon type to be displayed in a menu. | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
getIconType(): string; | ||
``` | ||
<b>Returns:</b> | ||
|
||
`string` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!-- Do not edit this file. It is automatically generated by API Documenter. --> | ||
|
||
[Home](./index.md) > [kibana-plugin-plugins-embeddable-public](./kibana-plugin-plugins-embeddable-public.md) > [EmbeddableFactory](./kibana-plugin-plugins-embeddable-public.embeddablefactory.md) > [grouping](./kibana-plugin-plugins-embeddable-public.embeddablefactory.grouping.md) | ||
|
||
## EmbeddableFactory.grouping property | ||
|
||
Indicates the grouping this factory should appear in a sub-menu. Example, this is used for grouping options in the editors menu in Dashboard for creating new embeddables | ||
|
||
<b>Signature:</b> | ||
|
||
```typescript | ||
readonly grouping?: UiActionsPresentableGrouping; | ||
``` |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,26 +6,24 @@ | |
* Side Public License, v 1. | ||
*/ | ||
|
||
import { METRIC_TYPE } from '@kbn/analytics'; | ||
import { EuiHorizontalRule } from '@elastic/eui'; | ||
import { i18n } from '@kbn/i18n'; | ||
import angular from 'angular'; | ||
import React, { useCallback, useEffect, useMemo, useState } from 'react'; | ||
|
||
import UseUnmount from 'react-use/lib/useUnmount'; | ||
import { BaseVisType, VisTypeAlias } from '../../../../visualizations/public'; | ||
import { | ||
AddFromLibraryButton, | ||
PrimaryActionButton, | ||
QuickButtonGroup, | ||
SolutionToolbar, | ||
QuickButtonProps, | ||
} from '../../../../presentation_util/public'; | ||
import { useKibana } from '../../services/kibana_react'; | ||
import { IndexPattern, SavedQuery, TimefilterContract } from '../../services/data'; | ||
import { | ||
EmbeddableFactoryNotFoundError, | ||
EmbeddableInput, | ||
isErrorEmbeddable, | ||
openAddPanelFlyout, | ||
ViewMode, | ||
} from '../../services/embeddable'; | ||
import { isErrorEmbeddable, openAddPanelFlyout, ViewMode } from '../../services/embeddable'; | ||
import { | ||
getSavedObjectFinder, | ||
SavedObjectSaveOpts, | ||
|
@@ -55,6 +53,7 @@ import { DashboardConstants } from '../../dashboard_constants'; | |
import { getNewDashboardTitle, unsavedChangesBadge } from '../../dashboard_strings'; | ||
import { DASHBOARD_PANELS_UNSAVED_ID } from '../lib/dashboard_panel_storage'; | ||
import { DashboardContainer } from '..'; | ||
import { EditorMenu } from './editor_menu'; | ||
|
||
export interface DashboardTopNavState { | ||
chromeIsVisible: boolean; | ||
|
@@ -104,12 +103,22 @@ export function DashboardTopNav({ | |
dashboardCapabilities, | ||
dashboardPanelStorage, | ||
allowByValueEmbeddables, | ||
visualizations, | ||
usageCollection, | ||
} = useKibana<DashboardAppServices>().services; | ||
|
||
const [state, setState] = useState<DashboardTopNavState>({ chromeIsVisible: false }); | ||
const [isSaveInProgress, setIsSaveInProgress] = useState(false); | ||
|
||
const lensAlias = visualizations.getAliases().find(({ name }) => name === 'lens'); | ||
const quickButtonVisTypes = ['markdown', 'maps']; | ||
const stateTransferService = embeddable.getStateTransfer(); | ||
const IS_DARK_THEME = uiSettings.get('theme:darkMode'); | ||
|
||
const trackUiMetric = usageCollection?.reportUiCounter.bind( | ||
usageCollection, | ||
DashboardConstants.DASHBOARDS_ID | ||
); | ||
|
||
useEffect(() => { | ||
const visibleSubscription = chrome.getIsVisible$().subscribe((chromeIsVisible) => { | ||
|
@@ -152,27 +161,36 @@ export function DashboardTopNav({ | |
uiSettings, | ||
]); | ||
|
||
const createNew = useCallback(async () => { | ||
const type = 'visualization'; | ||
const factory = embeddable.getEmbeddableFactory(type); | ||
const createNewVisType = useCallback( | ||
(visType?: BaseVisType | VisTypeAlias) => () => { | ||
let path = ''; | ||
let appId = ''; | ||
|
||
if (!factory) { | ||
throw new EmbeddableFactoryNotFoundError(type); | ||
} | ||
if (visType) { | ||
if (trackUiMetric) { | ||
trackUiMetric(METRIC_TYPE.CLICK, visType.name); | ||
} | ||
|
||
await factory.create({} as EmbeddableInput, dashboardContainer); | ||
}, [dashboardContainer, embeddable]); | ||
if ('aliasPath' in visType) { | ||
appId = visType.aliasApp; | ||
path = visType.aliasPath; | ||
} else { | ||
appId = 'visualize'; | ||
path = `#/create?type=${encodeURIComponent(visType.name)}`; | ||
} | ||
} else { | ||
appId = 'visualize'; | ||
path = '#/create?'; | ||
} | ||
|
||
const createNewVisType = useCallback( | ||
(newVisType: string) => async () => { | ||
stateTransferService.navigateToEditor('visualize', { | ||
path: `#/create?type=${encodeURIComponent(newVisType)}`, | ||
stateTransferService.navigateToEditor(appId, { | ||
path, | ||
state: { | ||
originatingApp: DashboardConstants.DASHBOARDS_ID, | ||
}, | ||
}); | ||
}, | ||
[stateTransferService] | ||
[trackUiMetric, stateTransferService] | ||
); | ||
|
||
const clearAddPanel = useCallback(() => { | ||
|
@@ -563,38 +581,57 @@ export function DashboardTopNav({ | |
|
||
const { TopNavMenu } = navigation.ui; | ||
|
||
const quickButtons = [ | ||
{ | ||
iconType: 'visText', | ||
createType: i18n.translate('dashboard.solutionToolbar.markdownQuickButtonLabel', { | ||
defaultMessage: 'Markdown', | ||
}), | ||
onClick: createNewVisType('markdown'), | ||
'data-test-subj': 'dashboardMarkdownQuickButton', | ||
}, | ||
{ | ||
iconType: 'controlsHorizontal', | ||
createType: i18n.translate('dashboard.solutionToolbar.inputControlsQuickButtonLabel', { | ||
defaultMessage: 'Input control', | ||
}), | ||
onClick: createNewVisType('input_control_vis'), | ||
'data-test-subj': 'dashboardInputControlsQuickButton', | ||
}, | ||
]; | ||
const getVisTypeQuickButton = (visTypeName: string) => { | ||
const visType = | ||
visualizations.get(visTypeName) || | ||
visualizations.getAliases().find(({ name }) => name === visTypeName); | ||
|
||
if (visType) { | ||
if ('aliasPath' in visType) { | ||
const { name, icon, title } = visType as VisTypeAlias; | ||
|
||
return { | ||
iconType: icon, | ||
createType: title, | ||
onClick: createNewVisType(visType as VisTypeAlias), | ||
'data-test-subj': `dashboardQuickButton${name}`, | ||
isDarkModeEnabled: IS_DARK_THEME, | ||
}; | ||
} else { | ||
const { name, icon, title, titleInWizard } = visType as BaseVisType; | ||
|
||
return { | ||
iconType: icon, | ||
createType: titleInWizard || title, | ||
onClick: createNewVisType(visType as BaseVisType), | ||
'data-test-subj': `dashboardQuickButton${name}`, | ||
isDarkModeEnabled: IS_DARK_THEME, | ||
}; | ||
} | ||
} | ||
|
||
return; | ||
}; | ||
|
||
const quickButtons = quickButtonVisTypes | ||
.map(getVisTypeQuickButton) | ||
.filter((button) => button) as QuickButtonProps[]; | ||
|
||
return ( | ||
<> | ||
<TopNavMenu {...getNavBarProps()} /> | ||
<EuiHorizontalRule margin="none" /> | ||
{viewMode !== ViewMode.VIEW ? ( | ||
<SolutionToolbar> | ||
<SolutionToolbar isDarkModeEnabled={IS_DARK_THEME}> | ||
{{ | ||
primaryActionButton: ( | ||
<PrimaryActionButton | ||
isDarkModeEnabled={IS_DARK_THEME} | ||
label={i18n.translate('dashboard.solutionToolbar.addPanelButtonLabel', { | ||
defaultMessage: 'Create panel', | ||
defaultMessage: 'Create visualization', | ||
})} | ||
onClick={createNew} | ||
iconType="plusInCircleFilled" | ||
onClick={createNewVisType(lensAlias)} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can this button take a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the benefit to adding an I don't think just having an href is sufficient bc we need to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you are seeing some of the same limitations as we did in Lens, and we haven't been able to find a better way: #96723 (comment) |
||
iconType="lensApp" | ||
data-test-subj="dashboardAddNewPanelButton" | ||
/> | ||
), | ||
|
@@ -605,6 +642,12 @@ export function DashboardTopNav({ | |
data-test-subj="dashboardAddPanelButton" | ||
/> | ||
), | ||
extraButtons: [ | ||
<EditorMenu | ||
createNewVisType={createNewVisType} | ||
dashboardContainer={dashboardContainer} | ||
/>, | ||
], | ||
}} | ||
</SolutionToolbar> | ||
) : null} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cqliu1 Is this something that needs to be fixed in EUI? If so can you point to the issue you were having that made you need to target
.euiIcon
directly and their SVG paths?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the dual color app icons don’t use the same color as the text on a button, so I had to manually adjust the icon color with CSS. I’ll file an issue in the EUI repo.