[ML] Explain Log Rate Spikes: Improve app dependency handling. (#140005)

Improves dependency handling. Previously we had a mix of plugin dependencies and kibana context values passed on from the ML plugin. Now we have a single context that gets dependencies passed on from the parent container in the ML plugin.
This commit is contained in:
Walter Rafelsberger 2022-09-08 18:58:33 +02:00 committed by GitHub
parent 1a1159b0c5
commit 52febd8807
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
29 changed files with 167 additions and 182 deletions

View file

@ -12,11 +12,9 @@
"requiredPlugins": [
"charts",
"data",
"discover",
"licensing",
"unifiedSearch"
"licensing"
],
"optionalPlugins": [],
"requiredBundles": ["kibanaReact", "fieldFormats"],
"requiredBundles": ["fieldFormats"],
"extraPublicDirs": ["common"]
}

View file

@ -10,7 +10,8 @@
import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types';
import { getCoreStart } from '../../kibana_services';
import type { HttpStart } from '@kbn/core/public';
export interface GetTimeFieldRangeResponse {
success: boolean;
@ -23,16 +24,17 @@ export async function getTimeFieldRange({
timeFieldName,
query,
runtimeMappings,
http,
}: {
index: string;
timeFieldName?: string;
query?: QueryDslQueryContainer;
runtimeMappings?: estypes.MappingRuntimeFields;
http: HttpStart;
}) {
const body = JSON.stringify({ index, timeFieldName, query, runtimeMappings });
const coreStart = getCoreStart();
return await coreStart.http.fetch<GetTimeFieldRangeResponse>({
return await http.fetch<GetTimeFieldRangeResponse>({
path: `/internal/file_upload/time_field_range`,
method: 'POST',
body,

View file

@ -16,8 +16,8 @@ import { EuiSuperDatePicker, OnRefreshProps } from '@elastic/eui';
import type { TimeRange } from '@kbn/es-query';
import { TimeHistoryContract, UI_SETTINGS } from '@kbn/data-plugin/public';
import { useUrlState } from '../../hooks/url_state';
import { useAiOpsKibana } from '../../kibana_context';
import { useUrlState } from '../../hooks/use_url_state';
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
import { aiopsRefresh$ } from '../../application/services/timefilter_refresh_service';
interface TimePickerQuickRange {
@ -54,9 +54,8 @@ function updateLastRefresh(timeRange: OnRefreshProps) {
}
export const DatePickerWrapper: FC = () => {
const { services } = useAiOpsKibana();
const config = services.uiSettings;
const { timefilter, history } = services.data.query.timefilter;
const { uiSettings, data } = useAiopsAppContext();
const { timefilter, history } = data.query.timefilter;
const [globalState, setGlobalState] = useUrlState('_g');
const getRecentlyUsedRanges = getRecentlyUsedRangesFactory(history);
@ -81,8 +80,8 @@ export const DatePickerWrapper: FC = () => {
timefilter.isTimeRangeSelectorEnabled()
);
const dateFormat = config.get('dateFormat');
const timePickerQuickRanges = config.get<TimePickerQuickRange[]>(
const dateFormat = uiSettings.get('dateFormat');
const timePickerQuickRanges = uiSettings.get<TimePickerQuickRange[]>(
UI_SETTINGS.TIMEPICKER_QUICK_RANGES
);

View file

@ -29,7 +29,7 @@ import type { WindowParameters } from '@kbn/aiops-utils';
import { MULTILAYER_TIME_AXIS_STYLE } from '@kbn/charts-plugin/common';
import type { ChangePoint } from '@kbn/ml-agg-utils';
import { useAiOpsKibana } from '../../../kibana_context';
import { useAiopsAppContext } from '../../../hooks/use_aiops_app_context';
import { BrushBadge } from './brush_badge';
@ -103,9 +103,7 @@ export const DocumentCountChart: FC<DocumentCountChartProps> = ({
changePoint,
isBrushCleared,
}) => {
const {
services: { data, uiSettings, fieldFormats, charts },
} = useAiOpsKibana();
const { data, uiSettings, fieldFormats, charts } = useAiopsAppContext();
const chartTheme = charts.theme.useChartsTheme();
const chartBaseTheme = charts.theme.useChartsBaseTheme();

View file

@ -19,7 +19,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import type { ChangePoint } from '@kbn/ml-agg-utils';
import type { Query } from '@kbn/es-query';
import { useAiOpsKibana } from '../../kibana_context';
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
import { initialState, streamReducer } from '../../../common/api/stream_reducer';
import type { ApiExplainLogRateSpikes } from '../../../common/api';
@ -53,8 +53,8 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
onSelectedChangePoint,
selectedChangePoint,
}) => {
const { services } = useAiOpsKibana();
const basePath = services.http?.basePath.get() ?? '';
const { http } = useAiopsAppContext();
const basePath = http.basePath.get() ?? '';
const [currentAnalysisWindowParameters, setCurrentAnalysisWindowParameters] = useState<
WindowParameters | undefined

View file

@ -32,7 +32,9 @@ import {
isRisonSerializationRequired,
getNestedProperty,
SetUrlState,
} from '../../hooks/url_state';
} from '../../hooks/use_url_state';
import type { AiopsAppDependencies } from '../../hooks/use_aiops_app_context';
import { AiopsAppContext } from '../../hooks/use_aiops_app_context';
import { ExplainLogRateSpikesPage } from './explain_log_rate_spikes_page';
@ -41,6 +43,8 @@ export interface ExplainLogRateSpikesAppStateProps {
dataView: DataView;
/** The saved search to analyze. */
savedSearch: SavedSearch | SavedSearchSavedObject | null;
/** App dependencies */
appDependencies: AiopsAppDependencies;
}
const defaultSearchQuery = {
@ -69,6 +73,7 @@ export const restorableDefaults = getDefaultAiOpsListState();
export const ExplainLogRateSpikesAppState: FC<ExplainLogRateSpikesAppStateProps> = ({
dataView,
savedSearch,
appDependencies,
}) => {
const history = useHistory();
const { search: urlSearchString } = useLocation();
@ -157,8 +162,10 @@ export const ExplainLogRateSpikesAppState: FC<ExplainLogRateSpikesAppStateProps>
}
return (
<UrlStateContextProvider value={{ searchString: urlSearchString, setUrlState }}>
<ExplainLogRateSpikesPage dataView={dataView} savedSearch={savedSearch} />
</UrlStateContextProvider>
<AiopsAppContext.Provider value={appDependencies}>
<UrlStateContextProvider value={{ searchString: urlSearchString, setUrlState }}>
<ExplainLogRateSpikesPage dataView={dataView} savedSearch={savedSearch} />
</UrlStateContextProvider>
</AiopsAppContext.Provider>
);
};

View file

@ -26,9 +26,9 @@ import { Filter, FilterStateStore, Query } from '@kbn/es-query';
import { FormattedMessage } from '@kbn/i18n-react';
import { SavedSearch } from '@kbn/discover-plugin/public';
import { useAiOpsKibana } from '../../kibana_context';
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
import { SearchQueryLanguage, SavedSearchSavedObject } from '../../application/utils/search_utils';
import { useUrlState, usePageUrlState, AppStateKey } from '../../hooks/url_state';
import { useUrlState, usePageUrlState, AppStateKey } from '../../hooks/use_url_state';
import { useData } from '../../hooks/use_data';
import { FullTimeRangeSelector } from '../full_time_range_selector';
import { DocumentCountContent } from '../document_count_content/document_count_content';
@ -55,8 +55,7 @@ export const ExplainLogRateSpikesPage: FC<ExplainLogRateSpikesPageProps> = ({
dataView,
savedSearch,
}) => {
const { services } = useAiOpsKibana();
const { data: dataService } = services;
const { data: dataService } = useAiopsAppContext();
const [aiopsListState, setAiopsListState] = usePageUrlState(AppStateKey, restorableDefaults);
const [globalState, setGlobalState] = useUrlState('_g');

View file

@ -25,7 +25,7 @@ import {
EuiToolTip,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { useAiOpsKibana } from '../../kibana_context';
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
import { setFullTimeRange } from './full_time_range_selector_service';
import { AIOPS_FROZEN_TIER_PREFERENCE, useStorage } from '../../hooks/use_storage';
@ -52,16 +52,22 @@ export const FullTimeRangeSelector: FC<Props> = ({
callback,
}) => {
const {
services: {
notifications: { toasts },
},
} = useAiOpsKibana();
http,
notifications: { toasts },
} = useAiopsAppContext();
// wrapper around setFullTimeRange to allow for the calling of the optional callBack prop
const setRange = useCallback(
async (i: DataView, q?: QueryDslQueryContainer, excludeFrozenData?: boolean) => {
try {
const fullTimeRange = await setFullTimeRange(timefilter, i, q, excludeFrozenData, toasts);
const fullTimeRange = await setFullTimeRange(
timefilter,
i,
toasts,
http,
q,
excludeFrozenData
);
if (typeof callback === 'function') {
callback(fullTimeRange);
}
@ -76,7 +82,7 @@ export const FullTimeRangeSelector: FC<Props> = ({
);
}
},
[callback, timefilter, toasts]
[callback, http, timefilter, toasts]
);
const [isPopoverOpen, setPopover] = useState(false);

View file

@ -13,7 +13,7 @@ import { TimefilterContract } from '@kbn/data-plugin/public';
import dateMath from '@kbn/datemath';
import { QueryDslQueryContainer } from '@elastic/elasticsearch/lib/api/types';
import { i18n } from '@kbn/i18n';
import type { ToastsStart } from '@kbn/core/public';
import type { ToastsStart, HttpStart } from '@kbn/core/public';
import { DataView } from '@kbn/data-views-plugin/public';
import { isPopulatedObject } from '@kbn/ml-is-populated-object';
import { getTimeFieldRange } from '../../application/services/time_field_range';
@ -33,9 +33,10 @@ export interface TimeRange {
export async function setFullTimeRange(
timefilter: TimefilterContract,
dataView: DataView,
toasts: ToastsStart,
http: HttpStart,
query?: QueryDslQueryContainer,
excludeFrozenData?: boolean,
toasts?: ToastsStart
excludeFrozenData?: boolean
): Promise<GetTimeFieldRangeResponse> {
const runtimeMappings = dataView.getRuntimeMappings();
const resp = await getTimeFieldRange({
@ -43,6 +44,7 @@ export async function setFullTimeRange(
timeFieldName: dataView.timeFieldName,
query: excludeFrozenData ? addExcludeFrozenToQuery(query) : query,
...(isPopulatedObject(runtimeMappings) ? { runtimeMappings } : {}),
http,
});
if (resp.start.epoch && resp.end.epoch) {
@ -51,7 +53,7 @@ export async function setFullTimeRange(
to: moment(resp.end.epoch).toISOString(),
});
} else {
toasts?.addWarning({
toasts.addWarning({
title: i18n.translate('xpack.aiops.index.fullTimeRangeSelector.noResults', {
defaultMessage: 'No results match your search criteria',
}),

View file

@ -14,7 +14,7 @@ import { EuiLoadingChart, EuiTextColor } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import type { ChangePointHistogramItem } from '@kbn/ml-agg-utils';
import { useAiOpsKibana } from '../../kibana_context';
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
import { useEuiTheme } from '../../hooks/use_eui_theme';
interface MiniHistogramProps {
@ -24,9 +24,7 @@ interface MiniHistogramProps {
}
export const MiniHistogram: FC<MiniHistogramProps> = ({ chartData, isLoading, label }) => {
const {
services: { charts },
} = useAiOpsKibana();
const { charts } = useAiopsAppContext();
const euiTheme = useEuiTheme();
const defaultChartTheme = charts.theme.useChartsTheme();

View file

@ -12,8 +12,7 @@ import { Query, Filter } from '@kbn/es-query';
import type { TimeRange } from '@kbn/es-query';
import { DataView, DataViewField } from '@kbn/data-views-plugin/public';
import { SearchQueryLanguage } from '../../application/utils/search_utils';
import { useAiOpsKibana } from '../../kibana_context';
import { getPluginsStart } from '../../kibana_services';
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
import { createMergedEsQuery } from '../../application/utils/search_utils';
interface Props {
dataView: DataView;
@ -40,15 +39,15 @@ export const SearchPanel: FC<Props> = ({
searchQueryLanguage,
setSearchParams,
}) => {
const { unifiedSearch } = getPluginsStart();
const { SearchBar } = unifiedSearch?.ui;
const {
services: {
uiSettings,
notifications: { toasts },
data: { query: queryManager },
uiSettings,
unifiedSearch: {
ui: { SearchBar },
},
} = useAiOpsKibana();
notifications: { toasts },
data: { query: queryManager },
} = useAiopsAppContext();
// The internal state of the input query bar updated on every key stroke.
const [searchInput, setSearchInput] = useState<Query>({
query: searchString || '',

View file

@ -6,6 +6,8 @@
*/
import React, { FC, useCallback, useMemo, useState } from 'react';
import { sortBy } from 'lodash';
import {
EuiBadge,
EuiBasicTable,
@ -14,16 +16,17 @@ import {
EuiTableSortingType,
EuiToolTip,
} from '@elastic/eui';
import { sortBy } from 'lodash';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { escapeKuery } from '@kbn/es-query';
import type { ChangePoint } from '@kbn/ml-agg-utils';
import { useEuiTheme } from '../../hooks/use_eui_theme';
import { MiniHistogram } from '../mini_histogram';
import { useAiOpsKibana } from '../../kibana_context';
import { SEARCH_QUERY_LANGUAGE } from '../../application/utils/search_utils';
import { useEuiTheme } from '../../hooks/use_eui_theme';
import { useAiopsAppContext } from '../../hooks/use_aiops_app_context';
import { MiniHistogram } from '../mini_histogram';
import { getFailedTransactionsCorrelationImpactLabel } from './get_failed_transactions_correlation_impact_label';
@ -64,10 +67,7 @@ export const SpikeAnalysisTable: FC<SpikeAnalysisTableProps> = ({
const [sortField, setSortField] = useState<keyof ChangePoint>(DEFAULT_SORT_FIELD);
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>(DEFAULT_SORT_DIRECTION);
const aiOpsKibana = useAiOpsKibana();
const {
services: { application, share, data },
} = aiOpsKibana;
const { application, share, data } = useAiopsAppContext();
const discoverLocator = useMemo(
() => share.url.locators.get('DISCOVER_APP_LOCATOR'),

View file

@ -0,0 +1,43 @@
/*
* 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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { createContext, useContext } from 'react';
import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import type { ChartsPluginStart } from '@kbn/charts-plugin/public';
import type { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import type { CoreStart, CoreSetup, HttpStart, IUiSettingsClient } from '@kbn/core/public';
export interface AiopsAppDependencies {
application: CoreStart['application'];
data: DataPublicPluginStart;
charts: ChartsPluginStart;
fieldFormats: FieldFormatsStart;
http: HttpStart;
notifications: CoreSetup['notifications'];
storage: IStorageWrapper;
uiSettings: IUiSettingsClient;
unifiedSearch: UnifiedSearchPublicPluginStart;
share: SharePluginStart;
}
export const AiopsAppContext = createContext<AiopsAppDependencies | undefined>(undefined);
export const useAiopsAppContext = (): AiopsAppDependencies => {
const aiopsAppContext = useContext(AiopsAppContext);
// if `undefined`, throw an error
if (aiopsAppContext === undefined) {
throw new Error('useAiopsAppContext was used outside of its Provider');
}
return aiopsAppContext;
};

View file

@ -16,7 +16,7 @@ import type { SavedSearch } from '@kbn/discover-plugin/public';
import { TimeBuckets } from '../../common/time_buckets';
import { useAiOpsKibana } from '../kibana_context';
import { useAiopsAppContext } from './use_aiops_app_context';
import { aiopsRefresh$ } from '../application/services/timefilter_refresh_service';
import type { DocumentStatsSearchStrategyParams } from '../get_document_stats';
import type { AiOpsIndexBasedAppState } from '../components/explain_log_rate_spikes/explain_log_rate_spikes_app_state';
@ -27,7 +27,7 @@ import {
import { useTimefilter } from './use_time_filter';
import { useDocumentCountStats } from './use_document_count_stats';
import type { Dictionary } from './url_state';
import type { Dictionary } from './use_url_state';
export const useData = (
{
@ -38,8 +38,12 @@ export const useData = (
onUpdate: (params: Dictionary<unknown>) => void,
selectedChangePoint?: ChangePoint
) => {
const { services } = useAiOpsKibana();
const { uiSettings, data } = services;
const {
uiSettings,
data: {
query: { filterManager },
},
} = useAiopsAppContext();
const [lastRefresh, setLastRefresh] = useState(0);
const [fieldStatsRequest, setFieldStatsRequest] = useState<
DocumentStatsSearchStrategyParams | undefined
@ -47,12 +51,11 @@ export const useData = (
/** Prepare required params to pass to search strategy **/
const { searchQueryLanguage, searchString, searchQuery } = useMemo(() => {
const filterManager = data.query.filterManager;
const searchData = getEsQueryFromSavedSearch({
dataView: currentDataView,
uiSettings,
savedSearch: currentSavedSearch,
filterManager: data.query.filterManager,
filterManager,
});
if (searchData === undefined || aiopsListState.searchString !== '') {

View file

@ -12,7 +12,6 @@ import { i18n } from '@kbn/i18n';
import type { ToastsStart } from '@kbn/core/public';
import { stringHash } from '@kbn/ml-string-hash';
import { useAiOpsKibana } from '../kibana_context';
import { extractErrorProperties } from '../application/utils/error_utils';
import {
DocumentCountStats,
@ -21,6 +20,8 @@ import {
DocumentStatsSearchStrategyParams,
} from '../get_document_stats';
import { useAiopsAppContext } from './use_aiops_app_context';
export interface DocumentStats {
totalCount: number;
documentCountStats?: DocumentCountStats;
@ -59,11 +60,9 @@ export function useDocumentCountStats<TParams extends DocumentStatsSearchStrateg
lastRefresh: number
): DocumentStats {
const {
services: {
data,
notifications: { toasts },
},
} = useAiOpsKibana();
data,
notifications: { toasts },
} = useAiopsAppContext();
const abortCtrl = useRef(new AbortController());

View file

@ -9,14 +9,12 @@ import { useMemo } from 'react';
import { euiLightVars as euiThemeLight, euiDarkVars as euiThemeDark } from '@kbn/ui-theme';
import { useAiOpsKibana } from '../kibana_context';
import { useAiopsAppContext } from './use_aiops_app_context';
export type EuiThemeType = typeof euiThemeLight | typeof euiThemeDark;
export function useEuiTheme() {
const {
services: { uiSettings },
} = useAiOpsKibana();
const { uiSettings } = useAiopsAppContext();
return useMemo(
() => (uiSettings.get('theme:darkMode') ? euiThemeDark : euiThemeLight),

View file

@ -6,7 +6,7 @@
*/
import { useCallback, useState } from 'react';
import { useAiOpsKibana } from '../kibana_context';
import { useAiopsAppContext } from './use_aiops_app_context';
export const AIOPS_FROZEN_TIER_PREFERENCE = 'aiops.frozenDataTierPreference';
@ -22,9 +22,7 @@ export type AiOpsKey = keyof Exclude<AiOps, null>;
* @param initValue
*/
export function useStorage<T>(key: AiOpsKey, initValue?: T): [T, (value: T) => void] {
const {
services: { storage },
} = useAiOpsKibana();
const { storage } = useAiopsAppContext();
const [val, setVal] = useState<T>(storage.get(key) ?? initValue);

View file

@ -6,7 +6,7 @@
*/
import { useEffect } from 'react';
import { useAiOpsKibana } from '../kibana_context';
import { useAiopsAppContext } from './use_aiops_app_context';
interface UseTimefilterOptions {
timeRangeSelector?: boolean;
@ -17,8 +17,13 @@ export const useTimefilter = ({
timeRangeSelector,
autoRefreshSelector,
}: UseTimefilterOptions = {}) => {
const { services } = useAiOpsKibana();
const { timefilter } = services.data.query.timefilter;
const {
data: {
query: {
timefilter: { timefilter },
},
},
} = useAiopsAppContext();
useEffect(() => {
if (timeRangeSelector === true && !timefilter.isTimeRangeSelectorEnabled()) {

View file

@ -13,7 +13,7 @@ export interface Dictionary<TValue> {
[id: string]: TValue;
}
// duplicate of ml/object_utils
// TODO duplicate of ml/object_utils
export const getNestedProperty = (
obj: Record<string, any>,
accessor: string,

View file

@ -14,4 +14,3 @@ export function plugin() {
}
export { ExplainLogRateSpikes } from './shared_lazy_components';
export type { AiopsPluginSetup, AiopsPluginStart } from './types';

View file

@ -1,18 +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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { CoreStart } from '@kbn/core/public';
import { KibanaReactContextValue, useKibana } from '@kbn/kibana-react-plugin/public';
import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public';
import type { AiOpsStartDependencies } from './plugin';
export type StartServices = CoreStart &
AiOpsStartDependencies & {
storage: IStorageWrapper;
};
export type AiOpsKibanaReactContextValue = KibanaReactContextValue<StartServices>;
export const useAiOpsKibana = () => useKibana<StartServices>();

View file

@ -1,19 +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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import { CoreStart } from '@kbn/core/public';
import { AiOpsStartDependencies } from './plugin';
let coreStart: CoreStart;
let pluginsStart: AiOpsStartDependencies;
export function setStartServices(core: CoreStart, plugins: AiOpsStartDependencies) {
coreStart = core;
pluginsStart = plugins;
}
export const getCoreStart = () => coreStart;
export const getPluginsStart = () => pluginsStart;

View file

@ -5,28 +5,10 @@
* 2.0.
*/
import { CoreSetup, CoreStart, Plugin } from '@kbn/core/public';
import type { DataPublicPluginStart } from '@kbn/data-plugin/public';
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import { ChartsPluginStart } from '@kbn/charts-plugin/public';
import { FieldFormatsStart } from '@kbn/field-formats-plugin/public';
import type { SharePluginStart } from '@kbn/share-plugin/public';
import { Plugin } from '@kbn/core/public';
import { AiopsPluginSetup, AiopsPluginStart } from './types';
import { setStartServices } from './kibana_services';
export interface AiOpsStartDependencies {
data: DataPublicPluginStart;
charts: ChartsPluginStart;
fieldFormats: FieldFormatsStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
share: SharePluginStart;
}
export class AiopsPlugin implements Plugin<AiopsPluginSetup, AiopsPluginStart> {
public setup(core: CoreSetup) {}
public start(core: CoreStart, plugins: AiOpsStartDependencies) {
setStartServices(core, plugins);
}
export class AiopsPlugin implements Plugin {
public setup() {}
public start() {}
public stop() {}
}

View file

@ -1,21 +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; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import type { AiopsPlugin } from './plugin';
/**
* aiops plugin public setup contract
*/
export type AiopsPluginSetup = ReturnType<AiopsPlugin['setup']>;
/**
* aiops plugin public start contract
*/
export type AiopsPluginStart = ReturnType<AiopsPlugin['start']>;
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
export type AppPluginStartDependencies = {};

View file

@ -6,6 +6,7 @@
*/
import React, { FC } from 'react';
import { pick } from 'lodash';
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
@ -20,9 +21,7 @@ import { TechnicalPreviewBadge } from '../components/technical_preview_badge';
import { MlPageHeader } from '../components/page_header';
export const ExplainLogRateSpikesPage: FC = () => {
const {
services: { docLinks },
} = useMlKibana();
const { services } = useMlKibana();
const context = useMlContext();
const dataView = context.currentDataView;
@ -43,8 +42,25 @@ export const ExplainLogRateSpikesPage: FC = () => {
</EuiFlexItem>
</EuiFlexGroup>
</MlPageHeader>
{dataView && <ExplainLogRateSpikes dataView={dataView} savedSearch={savedSearch} />}
<HelpMenu docLink={docLinks.links.ml.guide} />
{dataView && (
<ExplainLogRateSpikes
dataView={dataView}
savedSearch={savedSearch}
appDependencies={pick(services, [
'application',
'data',
'charts',
'fieldFormats',
'http',
'notifications',
'share',
'storage',
'uiSettings',
'unifiedSearch',
])}
/>
)}
<HelpMenu docLink={services.docLinks.links.ml.guide} />
</>
);
};

View file

@ -85,12 +85,12 @@ const App: FC<AppProps> = ({ coreStart, deps, appMountParams }) => {
maps: deps.maps,
triggersActionsUi: deps.triggersActionsUi,
dataVisualizer: deps.dataVisualizer,
aiops: deps.aiops,
usageCollection: deps.usageCollection,
fieldFormats: deps.fieldFormats,
dashboard: deps.dashboard,
charts: deps.charts,
cases: deps.cases,
unifiedSearch: deps.unifiedSearch,
...coreStart,
};
@ -140,7 +140,6 @@ export const renderApp = (
dashboard: deps.dashboard,
maps: deps.maps,
dataVisualizer: deps.dataVisualizer,
aiops: deps.aiops,
dataViews: deps.data.dataViews,
});

View file

@ -16,13 +16,13 @@ import type { IStorageWrapper } from '@kbn/kibana-utils-plugin/public';
import type { EmbeddableStart } from '@kbn/embeddable-plugin/public';
import type { MapsStartApi } from '@kbn/maps-plugin/public';
import type { DataVisualizerPluginStart } from '@kbn/data-visualizer-plugin/public';
import type { AiopsPluginStart } from '@kbn/aiops-plugin/public';
import type { TriggersAndActionsUIPublicPluginStart } from '@kbn/triggers-actions-ui-plugin/public';
import type { FieldFormatsRegistry } from '@kbn/field-formats-plugin/common';
import type { DashboardSetup } from '@kbn/dashboard-plugin/public';
import type { SpacesPluginStart } from '@kbn/spaces-plugin/public';
import type { ChartsPluginStart } from '@kbn/charts-plugin/public';
import type { CasesUiStart } from '@kbn/cases-plugin/public';
import type { UnifiedSearchPublicPluginStart } from '@kbn/unified-search-plugin/public';
import type { MlServicesContext } from '../../app';
interface StartPlugins {
@ -34,13 +34,13 @@ interface StartPlugins {
maps?: MapsStartApi;
triggersActionsUi?: TriggersAndActionsUIPublicPluginStart;
dataVisualizer?: DataVisualizerPluginStart;
aiops?: AiopsPluginStart;
usageCollection?: UsageCollectionSetup;
fieldFormats: FieldFormatsRegistry;
dashboard: DashboardSetup;
spacesApi: SpacesPluginStart;
charts: ChartsPluginStart;
cases?: CasesUiStart;
unifiedSearch: UnifiedSearchPublicPluginStart;
}
export type StartServices = CoreStart &
StartPlugins & {

View file

@ -27,7 +27,6 @@ import type { DataViewsContract } from '@kbn/data-views-plugin/public';
import type { SecurityPluginSetup } from '@kbn/security-plugin/public';
import type { MapsStartApi } from '@kbn/maps-plugin/public';
import type { DataVisualizerPluginStart } from '@kbn/data-visualizer-plugin/public';
import type { AiopsPluginStart } from '@kbn/aiops-plugin/public';
export interface DependencyCache {
timefilter: DataPublicPluginSetup['query']['timefilter'] | null;
@ -49,7 +48,6 @@ export interface DependencyCache {
dashboard: DashboardStart | null;
maps: MapsStartApi | null;
dataVisualizer: DataVisualizerPluginStart | null;
aiops: AiopsPluginStart | null;
dataViews: DataViewsContract | null;
}
@ -73,7 +71,6 @@ const cache: DependencyCache = {
dashboard: null,
maps: null,
dataVisualizer: null,
aiops: null,
dataViews: null,
};
@ -96,7 +93,6 @@ export function setDependencyCache(deps: Partial<DependencyCache>) {
cache.i18n = deps.i18n || null;
cache.dashboard = deps.dashboard || null;
cache.dataVisualizer = deps.dataVisualizer || null;
cache.aiops = deps.aiops || null;
cache.dataViews = deps.dataViews || null;
}

View file

@ -38,7 +38,6 @@ import {
TriggersAndActionsUIPublicPluginStart,
} from '@kbn/triggers-actions-ui-plugin/public';
import type { DataVisualizerPluginStart } from '@kbn/data-visualizer-plugin/public';
import type { AiopsPluginStart } from '@kbn/aiops-plugin/public';
import type { PluginSetupContract as AlertingSetup } from '@kbn/alerting-plugin/public';
import type { UsageCollectionSetup } from '@kbn/usage-collection-plugin/public';
import type { FieldFormatsSetup, FieldFormatsStart } from '@kbn/field-formats-plugin/public';
@ -62,7 +61,6 @@ export interface MlStartDependencies {
maps?: MapsStartApi;
triggersActionsUi?: TriggersAndActionsUIPublicPluginStart;
dataVisualizer: DataVisualizerPluginStart;
aiops: AiopsPluginStart;
fieldFormats: FieldFormatsStart;
dashboard: DashboardStart;
charts: ChartsPluginStart;
@ -132,7 +130,6 @@ export class MlPlugin implements Plugin<MlPluginSetup, MlPluginStart> {
kibanaVersion,
triggersActionsUi: pluginsStart.triggersActionsUi,
dataVisualizer: pluginsStart.dataVisualizer,
aiops: pluginsStart.aiops,
usageCollection: pluginsSetup.usageCollection,
fieldFormats: pluginsStart.fieldFormats,
lens: pluginsStart.lens,