[dashboard] clean up dashboard setup and start contracts (#212968)

* remove `locator` from setup and start contract
* remove `dashboardFeatureFlagConfig` from start contract

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
Nathan Reese 2025-03-12 10:36:37 -06:00 committed by GitHub
parent 78647b01ee
commit 377a812784
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
45 changed files with 168 additions and 170 deletions

View file

@ -24,7 +24,7 @@ export type {
export { DASHBOARD_API_TYPE } from './dashboard_api/types';
export type { DashboardRendererProps } from './dashboard_renderer/dashboard_renderer';
export { LazyDashboardRenderer as DashboardRenderer } from './dashboard_renderer/lazy_dashboard_renderer';
export type { DashboardSetup, DashboardStart, DashboardFeatureFlagConfig } from './plugin';
export type { DashboardStart } from './plugin';
export { DashboardListingTable } from './dashboard_listing';
export { DashboardTopNav } from './dashboard_top_nav';

View file

@ -61,10 +61,7 @@ import type {
} from '@kbn/usage-collection-plugin/public';
import { CONTENT_ID, LATEST_VERSION } from '../common/content_management';
import {
DashboardAppLocatorDefinition,
type DashboardAppLocator,
} from './dashboard_app/locator/locator';
import { DashboardAppLocatorDefinition } from './dashboard_app/locator/locator';
import { DashboardMountContextProps } from './dashboard_app/types';
import {
DASHBOARD_APP_ID,
@ -80,10 +77,7 @@ import type { FindDashboardsService } from './services/dashboard_content_managem
import { setKibanaServices, untilPluginStartServicesReady } from './services/kibana_services';
import { setLogger } from './services/logger';
import { registerActions } from './dashboard_actions/register_actions';
export interface DashboardFeatureFlagConfig {
allowByValueEmbeddables: boolean;
}
import type { ConfigSchema } from '../server/config';
export interface DashboardSetupDependencies {
data: DataPublicPluginSetup;
@ -125,23 +119,10 @@ export interface DashboardStartDependencies {
observabilityAIAssistant?: ObservabilityAIAssistantPublicStart;
}
export interface DashboardSetup {
/**
* @deprecated
*
* Use `shareStartService.url.locators.get(DASHBOARD_APP_LOCATOR)` instead.
*/
locator?: DashboardAppLocator;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface
interface DashboardSetup {}
export interface DashboardStart {
/**
* @deprecated
*
* Use `shareStartService.url.locators.get(DASHBOARD_APP_LOCATOR)` instead.
*/
locator?: DashboardAppLocator;
dashboardFeatureFlagConfig: DashboardFeatureFlagConfig;
findDashboardsService: () => Promise<FindDashboardsService>;
registerDashboardPanelPlacementSetting: <SerializedState extends object = object>(
embeddableType: string,
@ -149,8 +130,6 @@ export interface DashboardStart {
) => void;
}
export let resolveServicesReady: () => void;
export class DashboardPlugin
implements
Plugin<DashboardSetup, DashboardStart, DashboardSetupDependencies, DashboardStartDependencies>
@ -162,23 +141,18 @@ export class DashboardPlugin
private appStateUpdater = new BehaviorSubject<AppUpdater>(() => ({}));
private stopUrlTracking: (() => void) | undefined = undefined;
private currentHistory: ScopedHistory | undefined = undefined;
private dashboardFeatureFlagConfig?: DashboardFeatureFlagConfig;
private locator?: DashboardAppLocator;
public setup(
core: CoreSetup<DashboardStartDependencies, DashboardStart>,
{ share, embeddable, home, urlForwarding, data, contentManagement }: DashboardSetupDependencies
): DashboardSetup {
this.dashboardFeatureFlagConfig =
this.initializerContext.config.get<DashboardFeatureFlagConfig>();
) {
core.analytics.registerEventType({
eventType: 'dashboard_loaded_with_data',
schema: {},
});
if (share) {
this.locator = share.url.locators.create(
share.url.locators.create(
new DashboardAppLocatorDefinition({
useHashedUrl: core.uiSettings.get('state:storeInSessionStorage'),
getDashboardFilterFields: async (dashboardId: string) => {
@ -329,9 +303,7 @@ export class DashboardPlugin
name: dashboardAppTitle,
});
return {
locator: this.locator,
};
return {};
}
public start(core: CoreStart, plugins: DashboardStartDependencies): DashboardStart {
@ -340,13 +312,12 @@ export class DashboardPlugin
untilPluginStartServicesReady().then(() => {
registerActions({
plugins,
allowByValueEmbeddables: this.dashboardFeatureFlagConfig?.allowByValueEmbeddables,
allowByValueEmbeddables:
this.initializerContext.config.get<ConfigSchema>()?.allowByValueEmbeddables ?? true,
});
});
return {
locator: this.locator,
dashboardFeatureFlagConfig: this.dashboardFeatureFlagConfig!,
registerDashboardPanelPlacementSetting,
findDashboardsService: async () => {
const { getDashboardContentManagementService } = await import(

View file

@ -18,11 +18,11 @@
"uiActionsEnhanced",
"data",
"discover",
"dashboard",
"dashboardEnhanced",
"developerExamples",
"unifiedSearch",
"embeddable",
"share"
],
"requiredBundles": [
"dashboardEnhanced",

View file

@ -15,13 +15,13 @@ import {
} from '@kbn/ui-actions-enhanced-plugin/public';
import { createStartServicesGetter } from '@kbn/kibana-utils-plugin/public';
import { DiscoverSetup, DiscoverStart } from '@kbn/discover-plugin/public';
import { DashboardSetup, DashboardStart } from '@kbn/dashboard-plugin/public';
import { DeveloperExamplesSetup } from '@kbn/developer-examples-plugin/public';
import {
UiActionsEnhancedMemoryActionStorage,
UiActionsEnhancedDynamicActionManager,
} from '@kbn/ui-actions-enhanced-plugin/public';
import { EmbeddableSetup } from '@kbn/embeddable-plugin/public';
import { SharePluginStart } from '@kbn/share-plugin/public';
import { DashboardHelloWorldDrilldown } from './drilldowns/dashboard_hello_world_drilldown';
import { DashboardToDiscoverDrilldown } from './drilldowns/dashboard_to_discover_drilldown';
import { App1ToDashboardDrilldown } from './drilldowns/app1_to_dashboard_drilldown';
@ -39,7 +39,6 @@ import { App2ToDashboardDrilldown } from './drilldowns/app2_to_dashboard_drilldo
import { registerButtonEmbeddable } from './embeddables/register_button_embeddable';
export interface SetupDependencies {
dashboard: DashboardSetup;
data: DataPublicPluginSetup;
developerExamples: DeveloperExamplesSetup;
discover: DiscoverSetup;
@ -48,9 +47,9 @@ export interface SetupDependencies {
}
export interface StartDependencies {
dashboard: DashboardStart;
data: DataPublicPluginStart;
discover: DiscoverStart;
share: SharePluginStart;
uiActionsEnhanced: AdvancedUiActionsStart;
}

View file

@ -18,7 +18,6 @@
"@kbn/kibana-utils-plugin",
"@kbn/share-plugin",
"@kbn/discover-plugin",
"@kbn/dashboard-plugin",
"@kbn/embeddable-plugin",
"@kbn/ui-actions-enhanced-plugin",
"@kbn/developer-examples-plugin",

View file

@ -11,6 +11,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import { i18n } from '@kbn/i18n';
import { EuiCallOut, EuiConfirmModal, EuiSpacer } from '@elastic/eui';
import { KibanaSavedObjectType } from '@kbn/fleet-plugin/public';
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
import { MonitoringStartServices } from '../../../types';
const INGEST_PIPELINE_DASHBOARD_ID = 'elasticsearch-metrics-ingest-pipelines';
@ -35,7 +36,7 @@ export const ingestPipelineTabOnClick = async (services: MonitoringStartServices
response.data.items.some((item) => item.id === INGEST_PIPELINE_DASHBOARD_ID);
const navigateToDashboard = () =>
services.dashboard!.locator!.navigate({
services.share.url.locators.get(DASHBOARD_APP_LOCATOR)?.navigate({
dashboardId: INGEST_PIPELINE_DASHBOARD_ID,
});

View file

@ -54,7 +54,8 @@
"@kbn/analytics",
"@kbn/response-ops-rule-form",
"@kbn/charts-plugin",
"@kbn/fields-metadata-plugin"
"@kbn/fields-metadata-plugin",
"@kbn/deeplinks-analytics"
],
"exclude": ["target/**/*"]
}

View file

@ -15,7 +15,6 @@
"dashboardEnhanced"
],
"requiredPlugins": [
"dashboard",
"data",
"embeddable",
"share",
@ -23,6 +22,7 @@
"unifiedSearch"
],
"requiredBundles": [
"dashboard",
"embeddable",
"embeddableEnhanced",
"kibanaUtils",

View file

@ -13,7 +13,6 @@ import {
AdvancedUiActionsSetup,
AdvancedUiActionsStart,
} from '@kbn/ui-actions-enhanced-plugin/public';
import { DashboardStart } from '@kbn/dashboard-plugin/public';
import { DashboardDrilldownsService } from './services';
export interface SetupDependencies {
@ -27,7 +26,6 @@ export interface StartDependencies {
data: DataPublicPluginStart;
embeddable: EmbeddableStart;
share: SharePluginStart;
dashboard: DashboardStart;
}
// eslint-disable-next-line @typescript-eslint/no-empty-interface

View file

@ -5,10 +5,9 @@
* 2.0.
*/
import type { KibanaLocation } from '@kbn/share-plugin/public';
import type { KibanaLocation, SharePluginStart } from '@kbn/share-plugin/public';
import React from 'react';
import { DataPublicPluginStart } from '@kbn/data-plugin/public';
import { DashboardStart } from '@kbn/dashboard-plugin/public';
import {
AdvancedUiActionsStart,
UiActionsEnhancedBaseActionFactoryContext as BaseActionFactoryContext,
@ -16,6 +15,7 @@ import {
} from '@kbn/ui-actions-enhanced-plugin/public';
import { CollectConfigProps, StartServicesGetter } from '@kbn/kibana-utils-plugin/public';
import { DEFAULT_DASHBOARD_DRILLDOWN_OPTIONS } from '@kbn/presentation-util-plugin/public';
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
import { CollectConfigContainer } from './components';
import { txtGoToDashboard } from './i18n';
@ -24,7 +24,7 @@ export interface Params {
start: StartServicesGetter<{
uiActionsEnhanced: AdvancedUiActionsStart;
data: DataPublicPluginStart;
dashboard: DashboardStart;
share: SharePluginStart;
}>;
}
@ -87,7 +87,7 @@ export abstract class AbstractDashboardDrilldown<Context extends object = object
};
protected get locator() {
const locator = this.params.start().plugins.dashboard.locator;
const locator = this.params.start().plugins.share.url.locators.get(DASHBOARD_APP_LOCATOR);
if (!locator) throw new Error('Dashboard locator is required for dashboard drilldown.');
return locator;
}

View file

@ -92,17 +92,21 @@ describe('.execute() & getHref', () => {
},
plugins: {
uiActionsEnhanced: {},
dashboard: {
locator: {
getLocation: async (params: DashboardLocatorParams) => {
return await definition.getLocation(params);
share: {
url: {
locators: {
get: () => ({
getLocation: async (params: DashboardLocatorParams) => {
return await definition.getLocation(params);
},
}),
},
},
},
},
self: {},
})) as unknown as StartServicesGetter<
Pick<StartDependencies, 'data' | 'uiActionsEnhanced' | 'dashboard'>
Pick<StartDependencies, 'data' | 'uiActionsEnhanced' | 'share'>
>,
});

View file

@ -21,7 +21,8 @@
"@kbn/presentation-util-plugin",
"@kbn/presentation-containers",
"@kbn/presentation-publishing",
"@kbn/react-kibana-mount"
"@kbn/react-kibana-mount",
"@kbn/deeplinks-analytics"
],
"exclude": ["target/**/*"]
}

View file

@ -28,6 +28,8 @@ import {
import { isDefined } from '@kbn/ml-is-defined';
import { parseInterval } from '@kbn/ml-parse-interval';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
import type { DashboardItems } from '../../../services/dashboard_service';
import { categoryFieldTypes } from '../../../../../common/util/fields_utils';
import { TIME_RANGE_TYPE, URL_TYPE } from './constants';
@ -221,12 +223,13 @@ export function isValidCustomUrlSettings(
export function buildCustomUrlFromSettings(
dashboardService: DashboardStart,
share: SharePluginStart,
settings: CustomUrlSettings
): Promise<MlUrlConfig> {
// Dashboard URL returns a Promise as a query is made to obtain the full dashboard config.
// So wrap the other two return types in a Promise for consistent return type.
if (settings.type === URL_TYPE.KIBANA_DASHBOARD) {
return buildDashboardUrlFromSettings(dashboardService, settings);
return buildDashboardUrlFromSettings(dashboardService, share, settings);
} else if (settings.type === URL_TYPE.KIBANA_DISCOVER) {
return Promise.resolve(buildDiscoverUrlFromSettings(settings));
} else {
@ -256,6 +259,7 @@ function getUrlRangeFromSettings(settings: CustomUrlSettings) {
async function buildDashboardUrlFromSettings(
dashboardService: DashboardStart,
share: SharePluginStart,
settings: CustomUrlSettings,
isPartialDFAJob?: boolean
): Promise<MlUrlConfig> {
@ -300,7 +304,7 @@ async function buildDashboardUrlFromSettings(
const { from, to } = getUrlRangeFromSettings(settings);
const location = await dashboardService.locator?.getLocation({
const location = await share.url.locators.get(DASHBOARD_APP_LOCATOR)?.getLocation({
dashboardId,
timeRange: {
from,

View file

@ -151,9 +151,9 @@ export class CustomUrls extends Component<CustomUrlsProps, CustomUrlsState> {
};
addNewCustomUrl = () => {
const { dashboard } = this.context.services;
const { dashboard, share } = this.context.services;
buildCustomUrlFromSettings(dashboard, this.state.editorSettings as CustomUrlSettings)
buildCustomUrlFromSettings(dashboard, share, this.state.editorSettings as CustomUrlSettings)
.then((customUrl) => {
const customUrls = [...this.state.customUrls, customUrl];
this.props.setCustomUrls(customUrls);
@ -179,6 +179,7 @@ export class CustomUrls extends Component<CustomUrlsProps, CustomUrlsState> {
data: { dataViews },
dashboard,
mlServices: { mlApi },
share,
} = this.context.services;
const dataViewId = this.state?.editorSettings?.kibanaSettings?.discoverIndexPatternId;
const job = this.props.job;
@ -191,33 +192,34 @@ export class CustomUrls extends Component<CustomUrlsProps, CustomUrlsState> {
})
.then((dataView) => {
const timefieldName = dataView?.timeFieldName ?? null;
buildCustomUrlFromSettings(dashboard, this.state.editorSettings as CustomUrlSettings).then(
(customUrl) => {
getTestUrl(
mlApi,
job,
customUrl,
timefieldName,
this.props.currentTimeFilter,
this.props.isPartialDFAJob
)
.then((testUrl) => {
openCustomUrlWindow(testUrl, customUrl, basePath.get());
})
.catch((error) => {
this.toastNotificationService!.displayErrorToast(
error,
i18n.translate(
'xpack.ml.jobsList.editJobFlyout.customUrls.getTestUrlErrorNotificationMessage',
{
defaultMessage:
'An error occurred obtaining the URL to test the configuration',
}
)
);
});
}
);
buildCustomUrlFromSettings(
dashboard,
share,
this.state.editorSettings as CustomUrlSettings
).then((customUrl) => {
getTestUrl(
mlApi,
job,
customUrl,
timefieldName,
this.props.currentTimeFilter,
this.props.isPartialDFAJob
)
.then((testUrl) => {
openCustomUrlWindow(testUrl, customUrl, basePath.get());
})
.catch((error) => {
this.toastNotificationService!.displayErrorToast(
error,
i18n.translate(
'xpack.ml.jobsList.editJobFlyout.customUrls.getTestUrlErrorNotificationMessage',
{
defaultMessage: 'An error occurred obtaining the URL to test the configuration',
}
)
);
});
});
})
.catch((error) => {
this.toastNotificationService!.displayErrorToast(

View file

@ -11,16 +11,14 @@ import type { IUiSettingsClient } from '@kbn/core/public';
import type { TimefilterContract } from '@kbn/data-plugin/public';
import { firstValueFrom } from 'rxjs';
import type { estypes } from '@elastic/elasticsearch';
import type {
DashboardApi,
DashboardLocatorParams,
DashboardStart,
} from '@kbn/dashboard-plugin/public';
import type { DashboardApi, DashboardLocatorParams } from '@kbn/dashboard-plugin/public';
import { getTitle } from '@kbn/presentation-publishing';
import type { Filter, Query, DataViewBase } from '@kbn/es-query';
import { FilterStateStore } from '@kbn/es-query';
import type { ErrorType } from '@kbn/ml-error-utils';
import type { DataViewsContract } from '@kbn/data-views-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
import type { MlApi } from '../../../services/ml_api_service';
import type { Job, Datafeed } from '../../../../../common/types/anomaly_detection_jobs';
import { getFiltersForDSLQuery } from '../../../../../common/util/job_utils';
@ -55,7 +53,7 @@ export class QuickJobCreatorBase {
protected readonly dataViews: DataViewsContract,
protected readonly kibanaConfig: IUiSettingsClient,
protected readonly timeFilter: TimefilterContract,
protected readonly dashboardService: DashboardStart,
protected readonly share: SharePluginStart,
protected readonly mlApi: MlApi
) {}
@ -246,7 +244,7 @@ export class QuickJobCreatorBase {
),
};
const location = await this.dashboardService.locator?.getLocation(params);
const location = await this.share.url.locators.get(DASHBOARD_APP_LOCATOR)?.getLocation(params);
if (location === undefined) {
return null;
}

View file

@ -15,7 +15,7 @@ import type { IUiSettingsClient } from '@kbn/core/public';
import type { TimefilterContract } from '@kbn/data-plugin/public';
import type { DataViewsContract } from '@kbn/data-views-plugin/public';
import { isOfAggregateQueryType, type Filter, type Query } from '@kbn/es-query';
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { LensApi } from '@kbn/lens-plugin/public';
import type { JobCreatorType } from '../common/job_creator';
import { createEmptyJob, createEmptyDatafeed } from '../common/job_creator/util/default_configs';
@ -41,10 +41,10 @@ export class QuickLensJobCreator extends QuickJobCreatorBase {
dataViews: DataViewsContract,
kibanaConfig: IUiSettingsClient,
timeFilter: TimefilterContract,
dashboardService: DashboardStart,
share: SharePluginStart,
mlApi: MlApi
) {
super(dataViews, kibanaConfig, timeFilter, dashboardService, mlApi);
super(dataViews, kibanaConfig, timeFilter, share, mlApi);
}
public async createAndSaveJob(

View file

@ -11,7 +11,7 @@ import type { Filter } from '@kbn/es-query';
import type { LensPublicStart, LensSavedObjectAttributes } from '@kbn/lens-plugin/public';
import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser';
import type { TimefilterContract } from '@kbn/data-plugin/public';
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { DataViewsContract } from '@kbn/data-views-plugin/public';
import { QuickLensJobCreator } from './quick_create_job';
import type { MlApi } from '../../../services/ml_api_service';
@ -23,7 +23,7 @@ interface Dependencies {
dataViews: DataViewsContract;
kibanaConfig: IUiSettingsClient;
timeFilter: TimefilterContract;
dashboardService: DashboardStart;
share: SharePluginStart;
mlApi: MlApi;
}
export async function resolver(
@ -35,7 +35,7 @@ export async function resolver(
filtersRisonString: string,
layerIndexRisonString: string
) {
const { dataViews, lens, mlApi, timeFilter, kibanaConfig, dashboardService } = deps;
const { dataViews, lens, mlApi, timeFilter, kibanaConfig, share } = deps;
if (lensSavedObjectRisonString === undefined) {
throw new Error('Cannot create visualization');
}
@ -56,7 +56,7 @@ export async function resolver(
dataViews,
kibanaConfig,
timeFilter,
dashboardService,
share,
mlApi
);
await jobCreator.createAndStashADJob(vis, from, to, query, filters, layerIndex);

View file

@ -10,7 +10,7 @@ import type { IUiSettingsClient } from '@kbn/core/public';
import type { TimefilterContract } from '@kbn/data-plugin/public';
import type { Filter, Query } from '@kbn/es-query';
import type { DataView, DataViewsContract } from '@kbn/data-views-plugin/public';
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { MapApi } from '@kbn/maps-plugin/public';
import type { MlApi } from '../../../services/ml_api_service';
import {
@ -42,10 +42,10 @@ export class QuickGeoJobCreator extends QuickJobCreatorBase {
dataViews: DataViewsContract,
kibanaConfig: IUiSettingsClient,
timeFilter: TimefilterContract,
dashboardService: DashboardStart,
share: SharePluginStart,
mlApi: MlApi
) {
super(dataViews, kibanaConfig, timeFilter, dashboardService, mlApi);
super(dataViews, kibanaConfig, timeFilter, share, mlApi);
}
public async createAndSaveGeoJob({

View file

@ -7,7 +7,7 @@
import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser';
import type { TimefilterContract } from '@kbn/data-plugin/public';
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { DataViewsContract } from '@kbn/data-views-plugin/public';
import type { MlApi } from '../../../services/ml_api_service';
import { QuickGeoJobCreator } from './quick_create_job';
@ -18,7 +18,7 @@ interface Dependencies {
dataViews: DataViewsContract;
kibanaConfig: IUiSettingsClient;
timeFilter: TimefilterContract;
dashboardService: DashboardStart;
share: SharePluginStart;
mlApi: MlApi;
}
export async function resolver(
@ -32,7 +32,7 @@ export async function resolver(
toRisonString: string,
layerRisonString?: string
) {
const { dataViews, kibanaConfig, timeFilter, dashboardService, mlApi } = deps;
const { dataViews, kibanaConfig, timeFilter, share, mlApi } = deps;
const defaultLayer = { query: getDefaultQuery(), filters: [] };
const dashboard = getRisonValue<typeof defaultLayer>(dashboardRisonString, defaultLayer);
@ -50,13 +50,7 @@ export async function resolver(
const from = getRisonValue<string>(fromRisonString, '');
const to = getRisonValue<string>(toRisonString, '');
const jobCreator = new QuickGeoJobCreator(
dataViews,
kibanaConfig,
timeFilter,
dashboardService,
mlApi
);
const jobCreator = new QuickGeoJobCreator(dataViews, kibanaConfig, timeFilter, share, mlApi);
await jobCreator.createAndStashGeoJob(
dataViewId,

View file

@ -7,7 +7,7 @@
import type { IUiSettingsClient } from '@kbn/core/public';
import type { DataPublicPluginStart, TimefilterContract } from '@kbn/data-plugin/public';
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { DataViewField, DataView } from '@kbn/data-views-plugin/common';
import type { DataViewsContract } from '@kbn/data-views-plugin/public';
import type { TimeRange } from '@kbn/es-query';
@ -34,11 +34,11 @@ export class QuickCategorizationJobCreator extends QuickJobCreatorBase {
dataViews: DataViewsContract,
kibanaConfig: IUiSettingsClient,
timeFilter: TimefilterContract,
dashboardService: DashboardStart,
share: SharePluginStart,
private data: DataPublicPluginStart,
mlApi: MlApi
) {
super(dataViews, kibanaConfig, timeFilter, dashboardService, mlApi);
super(dataViews, kibanaConfig, timeFilter, share, mlApi);
}
public async createAndSaveJob(

View file

@ -7,7 +7,7 @@
import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser';
import type { DataPublicPluginStart, TimefilterContract } from '@kbn/data-plugin/public';
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { QueryDslQueryContainer } from '@kbn/data-views-plugin/common/types';
import {
type CategorizationType,
@ -21,9 +21,9 @@ import { getDefaultDatafeedQuery, getRisonValue } from '../utils/new_job_utils';
interface Dependencies {
kibanaConfig: IUiSettingsClient;
timeFilter: TimefilterContract;
dashboardService: DashboardStart;
data: DataPublicPluginStart;
mlApi: MlApi;
share: SharePluginStart;
}
export async function resolver(
deps: Dependencies,
@ -36,7 +36,7 @@ export async function resolver(
toRisonString: string,
queryRisonString: string
) {
const { mlApi, timeFilter, kibanaConfig, dashboardService, data } = deps;
const { mlApi, timeFilter, kibanaConfig, share, data } = deps;
const query = getRisonValue<QueryDslQueryContainer>(queryRisonString, getDefaultDatafeedQuery());
const from = getRisonValue<string>(fromRisonString, '');
@ -55,7 +55,7 @@ export async function resolver(
data.dataViews,
kibanaConfig,
timeFilter,
dashboardService,
share,
data,
mlApi
);

View file

@ -37,10 +37,10 @@ const PageWrapper: FC<PageProps> = ({ location }) => {
timefilter: { timefilter: timeFilter },
},
},
dashboard: dashboardService,
uiSettings: kibanaConfig,
mlServices: { mlApi },
lens,
share,
},
} = useMlKibana();
@ -53,7 +53,7 @@ const PageWrapper: FC<PageProps> = ({ location }) => {
mlApi,
timeFilter,
kibanaConfig,
dashboardService,
share,
},
vis,
from,

View file

@ -44,16 +44,16 @@ const PageWrapper: FC<PageProps> = ({ location }) => {
timefilter: { timefilter: timeFilter },
},
},
dashboard: dashboardService,
uiSettings: kibanaConfig,
mlServices: { mlApi },
share,
},
} = useMlKibana();
const { context } = useRouteResolver('full', ['canCreateJob'], {
redirect: () =>
resolver(
{ dataViews, mlApi, timeFilter, kibanaConfig, dashboardService },
{ dataViews, mlApi, timeFilter, kibanaConfig, share },
dashboard,
dataViewId,
embeddable,

View file

@ -38,9 +38,9 @@ const PageWrapper: FC<PageProps> = ({ location }) => {
const {
services: {
data,
dashboard: dashboardService,
uiSettings: kibanaConfig,
mlServices: { mlApi },
share,
},
} = useMlKibana();
@ -51,7 +51,7 @@ const PageWrapper: FC<PageProps> = ({ location }) => {
mlApi,
timeFilter: data.query.timefilter.timefilter,
kibanaConfig,
dashboardService,
share,
data,
},
categorizationType,

View file

@ -5,10 +5,12 @@
* 2.0.
*/
import type { SharePluginStart } from '@kbn/share-plugin/public';
import { dashboardServiceProvider } from './dashboard_service';
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
describe('DashboardService', () => {
const getUrlMock = jest.fn();
const dashboard: DashboardStart = {
// @ts-expect-error Only partial mock of full plugin
locator: {
@ -22,7 +24,17 @@ describe('DashboardService', () => {
}),
};
const dashboardService = dashboardServiceProvider(dashboard);
const shareMock = {
url: {
locators: {
get: () => ({
getUrl: getUrlMock,
}),
},
},
} as unknown as SharePluginStart;
const dashboardService = dashboardServiceProvider(dashboard, shareMock);
test('should fetch dashboard', async () => {
// act
@ -37,7 +49,7 @@ describe('DashboardService', () => {
});
test('should generate url to the dashboard', () => {
dashboardService.getDashboardUrl('test-id');
expect(dashboard.locator?.getUrl).toHaveBeenCalledWith({
expect(getUrlMock).toHaveBeenCalledWith({
dashboardId: 'test-id',
useHash: false,
viewMode: 'edit',

View file

@ -8,12 +8,17 @@
import { useMemo } from 'react';
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
import type { ViewMode } from '@kbn/presentation-publishing';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
import { useMlKibana } from '../contexts/kibana';
export type DashboardService = ReturnType<typeof dashboardServiceProvider>;
export type DashboardItems = Awaited<ReturnType<DashboardService['fetchDashboards']>>;
export function dashboardServiceProvider(dashboardService: DashboardStart) {
export function dashboardServiceProvider(
dashboardService: DashboardStart,
share: SharePluginStart
) {
return {
/**
* Fetches dashboards
@ -39,7 +44,7 @@ export function dashboardServiceProvider(dashboardService: DashboardStart) {
* Generates dashboard url
*/
async getDashboardUrl(dashboardId: string, viewMode: ViewMode = 'edit') {
return await dashboardService.locator?.getUrl({
return await share.url.locators.get(DASHBOARD_APP_LOCATOR)?.getUrl({
dashboardId,
viewMode: 'edit',
useHash: false,
@ -53,8 +58,8 @@ export function dashboardServiceProvider(dashboardService: DashboardStart) {
*/
export function useDashboardService(): DashboardService {
const {
services: { dashboard },
services: { dashboard, share },
} = useMlKibana();
return useMemo(() => dashboardServiceProvider(dashboard), [dashboard]);
return useMemo(() => dashboardServiceProvider(dashboard, share), [dashboard, share]);
}

View file

@ -48,7 +48,6 @@ export const CreateJob: FC<Props> = ({ dataView, field, query, timeRange }) => {
data,
share,
uiSettings,
dashboardService,
mlServices: { mlApi },
},
} = useMlFromLensKibanaContext();
@ -88,11 +87,11 @@ export const CreateJob: FC<Props> = ({ dataView, field, query, timeRange }) => {
data.dataViews,
uiSettings,
data.query.timefilter.timefilter,
dashboardService,
share,
data,
mlApi
),
[dashboardService, data, mlApi, uiSettings]
[share, data, mlApi, uiSettings]
);
function createADJobInWizard() {

View file

@ -12,14 +12,12 @@ import { useKibana } from '@kbn/kibana-react-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { LensPublicStart } from '@kbn/lens-plugin/public';
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
import type { MlServicesContext } from '../../../application/app';
interface StartPlugins {
data: DataPublicPluginStart;
share: SharePluginStart;
lens: LensPublicStart;
dashboardService: DashboardStart;
}
export type StartServices = CoreStart & StartPlugins & MlServicesContext;
export const useMlFromLensKibanaContext = () => useKibana<StartServices>();

View file

@ -33,7 +33,6 @@ export const CompatibleLayer: FC<Props> = ({ layer, layerIndex, embeddable }) =>
share,
uiSettings,
lens,
dashboardService,
mlServices: { mlApi },
},
} = useMlFromLensKibanaContext();
@ -45,7 +44,7 @@ export const CompatibleLayer: FC<Props> = ({ layer, layerIndex, embeddable }) =>
data.dataViews,
uiSettings,
data.query.timefilter.timefilter,
dashboardService,
share,
mlApi
),
// eslint-disable-next-line react-hooks/exhaustive-deps

View file

@ -50,7 +50,6 @@ export const CompatibleLayer: FC<Props> = ({ embeddable, layer, layerIndex }) =>
data,
share,
uiSettings,
dashboardService,
mlServices: { mlApi },
},
} = useMlFromLensKibanaContext();
@ -61,7 +60,7 @@ export const CompatibleLayer: FC<Props> = ({ embeddable, layer, layerIndex }) =>
data.dataViews,
uiSettings,
data.query.timefilter.timefilter,
dashboardService,
share,
mlApi
),
// eslint-disable-next-line react-hooks/exhaustive-deps

View file

@ -44,7 +44,7 @@ import type { DataVisualizerPluginStart } from '@kbn/data-visualizer-plugin/publ
import type { PluginSetupContract as AlertingSetup } from '@kbn/alerting-plugin/public';
import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
import type { FieldFormatsSetup } from '@kbn/field-formats-plugin/public';
import type { DashboardSetup, DashboardStart } from '@kbn/dashboard-plugin/public';
import type { DashboardStart } from '@kbn/dashboard-plugin/public';
import type { ChartsPluginStart } from '@kbn/charts-plugin/public';
import type { CasesPublicSetup, CasesPublicStart } from '@kbn/cases-plugin/public';
import type { SavedSearchPublicPluginStart } from '@kbn/saved-search-plugin/public';
@ -109,7 +109,6 @@ export interface MlStartDependencies {
export interface MlSetupDependencies {
alerting?: AlertingSetup;
cases?: CasesPublicSetup;
dashboard: DashboardSetup;
embeddable: EmbeddableSetup;
fieldFormats: FieldFormatsSetup;
home?: HomePublicPluginSetup;

View file

@ -139,6 +139,7 @@
"@kbn/response-ops-rule-form",
"@kbn/unsaved-changes-prompt",
"@kbn/fields-metadata-plugin",
"@kbn/core-analytics-browser"
"@kbn/core-analytics-browser",
"@kbn/deeplinks-analytics",
]
}

View file

@ -25,11 +25,17 @@ const connectorId = '123';
const mockServices = {
http: mockHttp,
notifications: { toasts: mockToasts },
dashboard: {
locator: {
getRedirectUrl: mockGetRedirectUrl.mockImplementation(
({ dashboardId }) => `http://localhost:5601/app/dashboards#/view/${dashboardId}`
),
share: {
url: {
locators: {
get: () => {
return {
getRedirectUrl: mockGetRedirectUrl.mockImplementation(
({ dashboardId }) => `http://localhost:5601/app/dashboards#/view/${dashboardId}`
),
};
},
},
},
},
spaces: {

View file

@ -8,6 +8,7 @@
import { useState, useEffect, useRef, useCallback } from 'react';
import { useKibana } from '@kbn/triggers-actions-ui-plugin/public';
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
import { getDashboard } from './api';
import * as i18n from './translations';
@ -22,7 +23,7 @@ export interface UseGetDashboard {
}
export const useGetDashboard = ({ connectorId, selectedProvider }: Props): UseGetDashboard => {
const {
dashboard,
share,
http,
notifications: { toasts },
spaces,
@ -50,7 +51,7 @@ export const useGetDashboard = ({ connectorId, selectedProvider }: Props): UseGe
const setUrl = useCallback(
(dashboardId: string) => {
const url = dashboard?.locator?.getRedirectUrl({
const url = share?.url.locators.get(DASHBOARD_APP_LOCATOR)?.getRedirectUrl({
query: {
language: 'kuery',
query: `kibana.saved_objects: { id : ${connectorId} }`,
@ -59,7 +60,7 @@ export const useGetDashboard = ({ connectorId, selectedProvider }: Props): UseGe
});
setDashboardUrl(url ?? null);
},
[connectorId, dashboard?.locator]
[connectorId, share]
);
useEffect(() => {

View file

@ -43,6 +43,7 @@
"@kbn/response-ops-rule-form",
"@kbn/inference-endpoint-ui-common",
"@kbn/alerts-ui-shared",
"@kbn/deeplinks-analytics",
],
"exclude": [
"target/**/*",

View file

@ -39,7 +39,8 @@
"features",
"home",
"spaces",
"serverless"
"serverless",
"share"
],
"requiredBundles": [
"alerting",

View file

@ -37,6 +37,7 @@ import { DashboardStart } from '@kbn/dashboard-plugin/public';
import { ExpressionsStart } from '@kbn/expressions-plugin/public';
import { CloudSetup } from '@kbn/cloud-plugin/public';
import { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public';
import { SharePluginStart } from '@kbn/share-plugin/public';
import { suspendedComponentWithProps } from './lib/suspended_component_with_props';
import { ActionTypeRegistryContract, RuleTypeRegistryContract } from '../types';
import {
@ -85,6 +86,7 @@ export interface TriggersAndActionsUiServices extends CoreStart {
fieldFormats: FieldFormatsStart;
lens: LensPublicStart;
fieldsMetadata: FieldsMetadataPublicStart;
share?: SharePluginStart;
}
export const renderApp = (deps: TriggersAndActionsUiServices) => {

View file

@ -76,7 +76,8 @@
"@kbn/rrule",
"@kbn/core-notifications-browser-mocks",
"@kbn/response-ops-rule-params",
"@kbn/fields-metadata-plugin"
"@kbn/fields-metadata-plugin",
"@kbn/share-plugin"
],
"exclude": ["target/**/*"]
}

View file

@ -61,7 +61,8 @@
"licenseManagement",
"profilingDataAccess",
"cases",
"observabilityAIAssistant"
"observabilityAIAssistant",
"share"
],
"requiredBundles": [
"fleet",

View file

@ -8,17 +8,16 @@ import { EuiButtonEmpty } from '@elastic/eui';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
import type { ApmPluginStartDeps } from '../../../../plugin';
import type { SavedApmCustomDashboard } from '../../../../../common/custom_dashboards';
export function GotoDashboard({ currentDashboard }: { currentDashboard: SavedApmCustomDashboard }) {
const {
services: {
dashboard: { locator: dashboardLocator },
},
services: { share },
} = useKibana<ApmPluginStartDeps>();
const url = dashboardLocator?.getRedirectUrl({
const url = share?.url.locators.get(DASHBOARD_APP_LOCATOR)?.getRedirectUrl({
dashboardId: currentDashboard?.dashboardSavedObjectId,
});
return (

View file

@ -73,6 +73,7 @@ import type { LogsSharedClientStartExports } from '@kbn/logs-shared-plugin/publi
import type { LogsDataAccessPluginStart } from '@kbn/logs-data-access-plugin/public';
import type { SavedSearchPublicPluginStart } from '@kbn/saved-search-plugin/public';
import type { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public';
import type { SharePublicStart } from '@kbn/share-plugin/public/plugin';
import type { ConfigSchema } from '.';
import { registerApmRuleTypes } from './components/alerting/rule_types/register_apm_rule_types';
import { registerEmbeddables } from './embeddable/register_embeddables';
@ -150,6 +151,7 @@ export interface ApmPluginStartDeps {
logsDataAccess: LogsDataAccessPluginStart;
savedSearch: SavedSearchPublicPluginStart;
fieldsMetadata: FieldsMetadataPublicStart;
share?: SharePublicStart;
}
const applicationsTitle = i18n.translate('xpack.apm.navigation.rootTitle', {

View file

@ -137,6 +137,7 @@
"@kbn/event-stacktrace",
"@kbn/response-ops-rule-form",
"@kbn/fields-metadata-plugin",
"@kbn/deeplinks-analytics"
],
"exclude": ["target/**/*"]
}

View file

@ -7,6 +7,7 @@
import { EuiButtonEmpty } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics';
import type { DashboardItemWithTitle } from '../../../../../../common/custom_dashboards';
import { useKibanaContextForPlugin } from '../../../../../hooks/use_kibana';
@ -16,12 +17,10 @@ export function GotoDashboardLink({
currentDashboard: DashboardItemWithTitle;
}) {
const {
services: {
dashboard: { locator: dashboardLocator },
},
services: { share },
} = useKibanaContextForPlugin();
const url = dashboardLocator?.getRedirectUrl({
const url = share?.url.locators.get(DASHBOARD_APP_LOCATOR)?.getRedirectUrl({
dashboardId: currentDashboard?.dashboardSavedObjectId,
});
return (

View file

@ -119,7 +119,8 @@
"@kbn/deeplinks-management",
"@kbn/response-ops-rule-form",
"@kbn/traced-es-client",
"@kbn/fields-metadata-plugin"
"@kbn/fields-metadata-plugin",
"@kbn/deeplinks-analytics"
],
"exclude": ["target/**/*"]
}

View file

@ -59,7 +59,7 @@ import {
import { ServerlessPluginSetup, ServerlessPluginStart } from '@kbn/serverless/public';
import type { UiActionsSetup, UiActionsStart } from '@kbn/ui-actions-plugin/public';
import type { PresentationUtilPluginStart } from '@kbn/presentation-util-plugin/public';
import { DashboardStart, DashboardSetup } from '@kbn/dashboard-plugin/public';
import { DashboardStart } from '@kbn/dashboard-plugin/public';
import { SLOPublicStart } from '@kbn/slo-plugin/public';
import type { ChartsPluginStart } from '@kbn/charts-plugin/public';
import { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public';
@ -88,7 +88,6 @@ export interface ClientPluginsSetup {
embeddable: EmbeddableSetup;
serverless?: ServerlessPluginSetup;
uiActions: UiActionsSetup;
dashboard: DashboardSetup;
}
export interface ClientPluginsStart {