mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[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:
parent
1a1159b0c5
commit
52febd8807
29 changed files with 167 additions and 182 deletions
|
@ -12,11 +12,9 @@
|
|||
"requiredPlugins": [
|
||||
"charts",
|
||||
"data",
|
||||
"discover",
|
||||
"licensing",
|
||||
"unifiedSearch"
|
||||
"licensing"
|
||||
],
|
||||
"optionalPlugins": [],
|
||||
"requiredBundles": ["kibanaReact", "fieldFormats"],
|
||||
"requiredBundles": ["fieldFormats"],
|
||||
"extraPublicDirs": ["common"]
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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',
|
||||
}),
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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 || '',
|
||||
|
|
|
@ -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'),
|
||||
|
|
43
x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts
Normal file
43
x-pack/plugins/aiops/public/hooks/use_aiops_app_context.ts
Normal 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;
|
||||
};
|
|
@ -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 !== '') {
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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,
|
|
@ -14,4 +14,3 @@ export function plugin() {
|
|||
}
|
||||
|
||||
export { ExplainLogRateSpikes } from './shared_lazy_components';
|
||||
export type { AiopsPluginSetup, AiopsPluginStart } from './types';
|
||||
|
|
|
@ -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>();
|
|
@ -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;
|
|
@ -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() {}
|
||||
}
|
||||
|
|
|
@ -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 = {};
|
|
@ -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} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
|
||||
|
|
|
@ -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 & {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue