mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[dashboard] replace lens vis alias with lens add panel action (#210478)
Remove visualizations dependency from dashboard plugin. Instead of using lens visTypeAlias, navigating to lens is done by executing addLensPanel action.
This commit is contained in:
parent
d9d0b39272
commit
fbce75620c
11 changed files with 63 additions and 115 deletions
|
@ -21,7 +21,8 @@ export interface HasAppContext {
|
|||
|
||||
export const apiHasAppContext = (unknownApi: unknown): unknownApi is HasAppContext => {
|
||||
return (
|
||||
(unknownApi as HasAppContext).getAppContext !== undefined &&
|
||||
Boolean(unknownApi) &&
|
||||
(unknownApi as HasAppContext)?.getAppContext !== undefined &&
|
||||
typeof (unknownApi as HasAppContext).getAppContext === 'function'
|
||||
);
|
||||
};
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
"uiActions",
|
||||
"urlForwarding",
|
||||
"presentationUtil",
|
||||
"visualizations",
|
||||
"unifiedSearch"
|
||||
],
|
||||
"optionalPlugins": [
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import { ActionExecutionContext, addPanelMenuTrigger } from '@kbn/ui-actions-plugin/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { coreServices, uiActionsService } from '../services/kibana_services';
|
||||
import { DashboardApi } from '../dashboard_api/types';
|
||||
|
||||
export async function executeAddLensPanelAction(dashboardApi: DashboardApi) {
|
||||
try {
|
||||
const addLensPanelAction = await uiActionsService.getAction('addLensPanelAction');
|
||||
addLensPanelAction.execute({
|
||||
embeddable: dashboardApi,
|
||||
trigger: addPanelMenuTrigger,
|
||||
} as ActionExecutionContext);
|
||||
} catch (error) {
|
||||
coreServices.notifications.toasts.addWarning(
|
||||
i18n.translate('dashboard.addNewPanelError', {
|
||||
defaultMessage: 'Unable to add new panel',
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
/*
|
||||
* 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", the "GNU Affero General Public License v3.0 only", 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", the "GNU Affero General Public
|
||||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import type { HasAppContext } from '@kbn/presentation-publishing';
|
||||
import type { BaseVisType, VisTypeAlias } from '@kbn/visualizations-plugin/public';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import {
|
||||
dataService,
|
||||
embeddableService,
|
||||
usageCollectionService,
|
||||
} from '../../../services/kibana_services';
|
||||
import { DASHBOARD_UI_METRIC_ID } from '../../../utils/telemetry_constants';
|
||||
|
||||
export function navigateToVisEditor(api: HasAppContext, visType?: BaseVisType | VisTypeAlias) {
|
||||
let path = '';
|
||||
let appId = '';
|
||||
|
||||
if (visType) {
|
||||
const trackUiMetric = usageCollectionService?.reportUiCounter.bind(
|
||||
usageCollectionService,
|
||||
DASHBOARD_UI_METRIC_ID
|
||||
);
|
||||
if (trackUiMetric) {
|
||||
trackUiMetric(METRIC_TYPE.CLICK, `${visType.name}:create`);
|
||||
}
|
||||
|
||||
if (!('alias' in visType)) {
|
||||
// this visualization is not an alias
|
||||
appId = 'visualize';
|
||||
path = `#/create?type=${encodeURIComponent(visType.name)}`;
|
||||
} else if (visType.alias && 'path' in visType.alias) {
|
||||
// this visualization **is** an alias, and it has an app to redirect to for creation
|
||||
appId = visType.alias.app;
|
||||
path = visType.alias.path;
|
||||
}
|
||||
} else {
|
||||
appId = 'visualize';
|
||||
path = '#/create?';
|
||||
}
|
||||
|
||||
const stateTransferService = embeddableService.getStateTransfer();
|
||||
stateTransferService.navigateToEditor(appId, {
|
||||
path,
|
||||
state: {
|
||||
originatingApp: api.getAppContext()?.currentAppId,
|
||||
originatingPath: api.getAppContext()?.getCurrentPath?.(),
|
||||
searchSessionId: dataService.search.session.getSessionId(),
|
||||
},
|
||||
});
|
||||
}
|
|
@ -9,28 +9,25 @@
|
|||
|
||||
import { useEuiTheme } from '@elastic/eui';
|
||||
import { css } from '@emotion/react';
|
||||
import React, { useCallback } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
import { AddFromLibraryButton, Toolbar, ToolbarButton } from '@kbn/shared-ux-button-toolbar';
|
||||
|
||||
import { useStateFromPublishingSubject } from '@kbn/presentation-publishing';
|
||||
import useMountedState from 'react-use/lib/useMountedState';
|
||||
import { useDashboardApi } from '../../dashboard_api/use_dashboard_api';
|
||||
import { visualizationsService } from '../../services/kibana_services';
|
||||
import { getCreateVisualizationButtonTitle } from '../_dashboard_app_strings';
|
||||
import { ControlsToolbarButton } from './controls_toolbar_button';
|
||||
import { AddPanelButton } from './add_panel_button/components/add_panel_button';
|
||||
import { addFromLibrary } from '../../dashboard_container/embeddable/api';
|
||||
import { navigateToVisEditor } from './add_panel_button/navigate_to_vis_editor';
|
||||
import { executeAddLensPanelAction } from '../../dashboard_actions/execute_add_lens_panel_action';
|
||||
|
||||
export function DashboardEditingToolbar({ isDisabled }: { isDisabled?: boolean }) {
|
||||
const { euiTheme } = useEuiTheme();
|
||||
|
||||
const isMounted = useMountedState();
|
||||
const dashboardApi = useDashboardApi();
|
||||
|
||||
const navigateToDefaultEditor = useCallback(() => {
|
||||
const lensAlias = visualizationsService.getAliases().find(({ name }) => name === 'lens');
|
||||
navigateToVisEditor(dashboardApi, lensAlias);
|
||||
}, [dashboardApi]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const controlGroupApi = useStateFromPublishingSubject(dashboardApi.controlGroupApi$);
|
||||
const extraButtons = [
|
||||
|
@ -55,10 +52,17 @@ export function DashboardEditingToolbar({ isDisabled }: { isDisabled?: boolean }
|
|||
primaryButton: (
|
||||
<ToolbarButton
|
||||
type="primary"
|
||||
isDisabled={isDisabled}
|
||||
isDisabled={isDisabled || isLoading}
|
||||
isLoading={isLoading}
|
||||
iconType="lensApp"
|
||||
size="s"
|
||||
onClick={navigateToDefaultEditor}
|
||||
onClick={async () => {
|
||||
setIsLoading(true);
|
||||
await executeAddLensPanelAction(dashboardApi);
|
||||
if (isMounted()) {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}}
|
||||
label={getCreateVisualizationButtonTitle()}
|
||||
data-test-subj="dashboardAddNewPanelButton"
|
||||
/>
|
||||
|
|
|
@ -13,13 +13,11 @@ import React from 'react';
|
|||
|
||||
import { DashboardContext } from '../../../dashboard_api/use_dashboard_api';
|
||||
import { DashboardApi } from '../../../dashboard_api/types';
|
||||
import { coreServices, visualizationsService } from '../../../services/kibana_services';
|
||||
import { coreServices } from '../../../services/kibana_services';
|
||||
import { DashboardEmptyScreen } from './dashboard_empty_screen';
|
||||
import { ViewMode } from '@kbn/presentation-publishing';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
|
||||
visualizationsService.getAliases = jest.fn().mockReturnValue([{ name: 'lens' }]);
|
||||
|
||||
describe('DashboardEmptyScreen', () => {
|
||||
function mountComponent(viewMode: ViewMode) {
|
||||
const mockDashboardApi = {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* License v3.0 only", or the "Server Side Public License, v 1".
|
||||
*/
|
||||
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import {
|
||||
|
@ -19,58 +19,29 @@ import {
|
|||
EuiPageTemplate,
|
||||
EuiText,
|
||||
} from '@elastic/eui';
|
||||
import { METRIC_TYPE } from '@kbn/analytics';
|
||||
import { useStateFromPublishingSubject } from '@kbn/presentation-publishing';
|
||||
|
||||
import useMountedState from 'react-use/lib/useMountedState';
|
||||
import { useDashboardApi } from '../../../dashboard_api/use_dashboard_api';
|
||||
import { DASHBOARD_UI_METRIC_ID } from '../../../utils/telemetry_constants';
|
||||
import {
|
||||
coreServices,
|
||||
dataService,
|
||||
embeddableService,
|
||||
usageCollectionService,
|
||||
visualizationsService,
|
||||
} from '../../../services/kibana_services';
|
||||
import { coreServices } from '../../../services/kibana_services';
|
||||
import { getDashboardCapabilities } from '../../../utils/get_dashboard_capabilities';
|
||||
import { addFromLibrary } from '../../embeddable/api';
|
||||
import { executeAddLensPanelAction } from '../../../dashboard_actions/execute_add_lens_panel_action';
|
||||
|
||||
export function DashboardEmptyScreen() {
|
||||
const lensAlias = useMemo(
|
||||
() => visualizationsService.getAliases().find(({ name }) => name === 'lens'),
|
||||
[]
|
||||
);
|
||||
const { showWriteControls } = useMemo(() => {
|
||||
return getDashboardCapabilities();
|
||||
}, []);
|
||||
|
||||
const isMounted = useMountedState();
|
||||
const dashboardApi = useDashboardApi();
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const isDarkTheme = useObservable(coreServices.theme.theme$)?.darkMode;
|
||||
const viewMode = useStateFromPublishingSubject(dashboardApi.viewMode$);
|
||||
const isEditMode = useMemo(() => {
|
||||
return viewMode === 'edit';
|
||||
}, [viewMode]);
|
||||
|
||||
const goToLens = useCallback(() => {
|
||||
if (!lensAlias || !lensAlias.alias) return;
|
||||
const trackUiMetric = usageCollectionService?.reportUiCounter.bind(
|
||||
usageCollectionService,
|
||||
DASHBOARD_UI_METRIC_ID
|
||||
);
|
||||
|
||||
if (trackUiMetric) {
|
||||
trackUiMetric(METRIC_TYPE.CLICK, `${lensAlias.name}:create`);
|
||||
}
|
||||
const appContext = dashboardApi.getAppContext();
|
||||
embeddableService.getStateTransfer().navigateToEditor(lensAlias.alias.app, {
|
||||
path: lensAlias.alias.path,
|
||||
state: {
|
||||
originatingApp: appContext?.currentAppId,
|
||||
originatingPath: appContext?.getCurrentPath?.() ?? '',
|
||||
searchSessionId: dataService.search.session.getSessionId(),
|
||||
},
|
||||
});
|
||||
}, [lensAlias, dashboardApi]);
|
||||
|
||||
// TODO replace these SVGs with versions from EuiIllustration as soon as it becomes available.
|
||||
const imageUrl = coreServices.http.basePath.prepend(
|
||||
`/plugins/dashboard/assets/${isDarkTheme ? 'dashboards_dark' : 'dashboards_light'}.svg`
|
||||
|
@ -123,7 +94,17 @@ export function DashboardEmptyScreen() {
|
|||
return (
|
||||
<EuiFlexGroup justifyContent="center" gutterSize="l" alignItems="center">
|
||||
<EuiFlexItem grow={false}>
|
||||
<EuiButton iconType="lensApp" onClick={() => goToLens()}>
|
||||
<EuiButton
|
||||
isLoading={isLoading}
|
||||
iconType="lensApp"
|
||||
onClick={async () => {
|
||||
setIsLoading(true);
|
||||
await executeAddLensPanelAction(dashboardApi);
|
||||
if (isMounted()) {
|
||||
setIsLoading(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{i18n.translate('dashboard.emptyScreen.createVisualization', {
|
||||
defaultMessage: 'Create visualization',
|
||||
})}
|
||||
|
|
|
@ -59,7 +59,6 @@ import type {
|
|||
UsageCollectionSetup,
|
||||
UsageCollectionStart,
|
||||
} from '@kbn/usage-collection-plugin/public';
|
||||
import type { VisualizationsStart } from '@kbn/visualizations-plugin/public';
|
||||
|
||||
import { CONTENT_ID, LATEST_VERSION } from '../common/content_management';
|
||||
import {
|
||||
|
@ -119,7 +118,6 @@ export interface DashboardStartDependencies {
|
|||
unifiedSearch: UnifiedSearchPublicPluginStart;
|
||||
urlForwarding: UrlForwardingStart;
|
||||
usageCollection?: UsageCollectionStart;
|
||||
visualizations: VisualizationsStart;
|
||||
customBranding: CustomBrandingStart;
|
||||
serverless?: ServerlessPluginStart;
|
||||
noDataPage?: NoDataPagePluginStart;
|
||||
|
|
|
@ -28,7 +28,6 @@ import type { SpacesApi } from '@kbn/spaces-plugin/public';
|
|||
import type { UiActionsPublicStart } from '@kbn/ui-actions-plugin/public/plugin';
|
||||
import type { UrlForwardingStart } from '@kbn/url-forwarding-plugin/public';
|
||||
import type { UsageCollectionStart } from '@kbn/usage-collection-plugin/public';
|
||||
import type { VisualizationsStart } from '@kbn/visualizations-plugin/public';
|
||||
|
||||
import type { DashboardStartDependencies } from '../plugin';
|
||||
|
||||
|
@ -51,7 +50,6 @@ export let spacesService: SpacesApi | undefined;
|
|||
export let uiActionsService: UiActionsPublicStart;
|
||||
export let urlForwardingService: UrlForwardingStart;
|
||||
export let usageCollectionService: UsageCollectionStart | undefined;
|
||||
export let visualizationsService: VisualizationsStart;
|
||||
|
||||
const servicesReady$ = new BehaviorSubject(false);
|
||||
|
||||
|
@ -75,7 +73,6 @@ export const setKibanaServices = (kibanaCore: CoreStart, deps: DashboardStartDep
|
|||
uiActionsService = deps.uiActions;
|
||||
urlForwardingService = deps.urlForwarding;
|
||||
usageCollectionService = deps.usageCollection;
|
||||
visualizationsService = deps.visualizations;
|
||||
|
||||
servicesReady$.next(true);
|
||||
};
|
||||
|
|
|
@ -29,7 +29,6 @@ import { savedObjectTaggingOssPluginMock } from '@kbn/saved-objects-tagging-oss-
|
|||
import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks';
|
||||
import { unifiedSearchPluginMock } from '@kbn/unified-search-plugin/public/mocks';
|
||||
import { urlForwardingPluginMock } from '@kbn/url-forwarding-plugin/public/mocks';
|
||||
import { visualizationsPluginMock } from '@kbn/visualizations-plugin/public/mocks';
|
||||
|
||||
import { setKibanaServices } from './kibana_services';
|
||||
import { setLogger } from './logger';
|
||||
|
@ -72,7 +71,6 @@ export const setStubKibanaServices = () => {
|
|||
unifiedSearch: unifiedSearchPluginMock.createStartContract(),
|
||||
urlForwarding: urlForwardingPluginMock.createStartContract(),
|
||||
usageCollection: usageCollectionPluginMock.createSetupContract(),
|
||||
visualizations: visualizationsPluginMock.createStartContract(),
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
"@kbn/saved-objects-plugin",
|
||||
"@kbn/screenshot-mode-plugin",
|
||||
"@kbn/ui-actions-plugin",
|
||||
"@kbn/visualizations-plugin",
|
||||
"@kbn/spaces-plugin",
|
||||
"@kbn/config-schema",
|
||||
"@kbn/utility-types",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue