mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[ML] AI Ops: Adds discover link to analysis table (#139877)
* wip: create linksMenu component for discover url * adds actions column to spikeanalysis table with link to discover * [CI] Auto-commit changed files from 'node scripts/eslint --no-cache --fix' * use EuiTable built in Actions column type for Discover link * remove linkMenu * fix localization messages * set fixed width for actions column * [CI] Auto-commit changed files from 'node scripts/precommit_hook.js --ref HEAD~1..HEAD --fix' * update link icon and simplify discoverUrlError setting * Update x-pack/plugins/aiops/public/components/spike_analysis_table/spike_analysis_table.tsx Co-authored-by: Dima Arnautov <arnautov.dima@gmail.com> Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Dima Arnautov <arnautov.dima@gmail.com>
This commit is contained in:
parent
27d93fdf69
commit
7a83e87560
3 changed files with 101 additions and 2 deletions
|
@ -178,6 +178,7 @@ export const ExplainLogRateSpikesAnalysis: FC<ExplainLogRateSpikesAnalysisProps>
|
|||
onPinnedChangePoint={onPinnedChangePoint}
|
||||
onSelectedChangePoint={onSelectedChangePoint}
|
||||
selectedChangePoint={selectedChangePoint}
|
||||
dataViewId={dataView.id}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -18,22 +18,31 @@ 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 { getFailedTransactionsCorrelationImpactLabel } from './get_failed_transactions_correlation_impact_label';
|
||||
|
||||
const NARROW_COLUMN_WIDTH = '120px';
|
||||
const ACTIONS_COLUMN_WIDTH = '60px';
|
||||
|
||||
const PAGINATION_SIZE_OPTIONS = [5, 10, 20, 50];
|
||||
const DEFAULT_SORT_FIELD = 'pValue';
|
||||
const DEFAULT_SORT_DIRECTION = 'asc';
|
||||
const viewInDiscoverMessage = i18n.translate(
|
||||
'xpack.aiops.spikeAnalysisTable.linksMenu.viewInDiscover',
|
||||
{
|
||||
defaultMessage: 'View in Discover',
|
||||
}
|
||||
);
|
||||
|
||||
interface SpikeAnalysisTableProps {
|
||||
changePoints: ChangePoint[];
|
||||
dataViewId?: string;
|
||||
loading: boolean;
|
||||
onPinnedChangePoint?: (changePoint: ChangePoint | null) => void;
|
||||
onSelectedChangePoint?: (changePoint: ChangePoint | null) => void;
|
||||
|
@ -42,6 +51,7 @@ interface SpikeAnalysisTableProps {
|
|||
|
||||
export const SpikeAnalysisTable: FC<SpikeAnalysisTableProps> = ({
|
||||
changePoints,
|
||||
dataViewId,
|
||||
loading,
|
||||
onPinnedChangePoint,
|
||||
onSelectedChangePoint,
|
||||
|
@ -54,6 +64,67 @@ 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 discoverLocator = useMemo(
|
||||
() => share.url.locators.get('DISCOVER_APP_LOCATOR'),
|
||||
[share.url.locators]
|
||||
);
|
||||
|
||||
const discoverUrlError = useMemo(() => {
|
||||
if (!application.capabilities.discover?.show) {
|
||||
const discoverNotEnabled = i18n.translate(
|
||||
'xpack.aiops.spikeAnalysisTable.discoverNotEnabledErrorMessage',
|
||||
{
|
||||
defaultMessage: 'Discover is not enabled',
|
||||
}
|
||||
);
|
||||
|
||||
return discoverNotEnabled;
|
||||
}
|
||||
if (!discoverLocator) {
|
||||
const discoverLocatorMissing = i18n.translate(
|
||||
'xpack.aiops.spikeAnalysisTable.discoverLocatorMissingErrorMessage',
|
||||
{
|
||||
defaultMessage: 'No locator for Discover detected',
|
||||
}
|
||||
);
|
||||
|
||||
return discoverLocatorMissing;
|
||||
}
|
||||
if (!dataViewId) {
|
||||
const autoGeneratedDiscoverLinkError = i18n.translate(
|
||||
'xpack.aiops.spikeAnalysisTable.autoGeneratedDiscoverLinkErrorMessage',
|
||||
{
|
||||
defaultMessage: 'Unable to link to Discover; no data view exists for this index',
|
||||
}
|
||||
);
|
||||
|
||||
return autoGeneratedDiscoverLinkError;
|
||||
}
|
||||
}, [application.capabilities.discover?.show, dataViewId, discoverLocator]);
|
||||
|
||||
const generateDiscoverUrl = async (changePoint: ChangePoint) => {
|
||||
if (discoverLocator !== undefined) {
|
||||
const url = await discoverLocator.getRedirectUrl({
|
||||
indexPatternId: dataViewId,
|
||||
timeRange: data.query.timefilter.timefilter.getTime(),
|
||||
filters: data.query.filterManager.getFilters(),
|
||||
query: {
|
||||
language: SEARCH_QUERY_LANGUAGE.KUERY,
|
||||
query: `${escapeKuery(changePoint.fieldName)}:${escapeKuery(
|
||||
String(changePoint.fieldValue)
|
||||
)}`,
|
||||
},
|
||||
});
|
||||
|
||||
return url;
|
||||
}
|
||||
};
|
||||
|
||||
const columns: Array<EuiBasicTableColumn<ChangePoint>> = [
|
||||
{
|
||||
'data-test-subj': 'aiopsSpikeAnalysisTableColumnFieldName',
|
||||
|
@ -163,6 +234,31 @@ export const SpikeAnalysisTable: FC<SpikeAnalysisTableProps> = ({
|
|||
},
|
||||
sortable: true,
|
||||
},
|
||||
{
|
||||
'data-test-subj': 'aiOpsSpikeAnalysisTableColumnAction',
|
||||
name: i18n.translate('xpack.aiops.spikeAnalysisTable.actionsColumnName', {
|
||||
defaultMessage: 'Actions',
|
||||
}),
|
||||
actions: [
|
||||
{
|
||||
name: () => (
|
||||
<EuiToolTip content={discoverUrlError ? discoverUrlError : viewInDiscoverMessage}>
|
||||
<EuiIcon type="discoverApp" />
|
||||
</EuiToolTip>
|
||||
),
|
||||
description: viewInDiscoverMessage,
|
||||
type: 'button',
|
||||
onClick: async (changePoint) => {
|
||||
const openInDiscoverUrl = await generateDiscoverUrl(changePoint);
|
||||
if (typeof openInDiscoverUrl === 'string') {
|
||||
await application.navigateToUrl(openInDiscoverUrl);
|
||||
}
|
||||
},
|
||||
enabled: () => discoverUrlError === undefined,
|
||||
},
|
||||
],
|
||||
width: ACTIONS_COLUMN_WIDTH,
|
||||
},
|
||||
];
|
||||
|
||||
const onChange = useCallback((tableSettings) => {
|
||||
|
|
|
@ -10,6 +10,7 @@ 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 { AiopsPluginSetup, AiopsPluginStart } from './types';
|
||||
import { setStartServices } from './kibana_services';
|
||||
|
@ -19,6 +20,7 @@ export interface AiOpsStartDependencies {
|
|||
charts: ChartsPluginStart;
|
||||
fieldFormats: FieldFormatsStart;
|
||||
unifiedSearch: UnifiedSearchPublicPluginStart;
|
||||
share: SharePluginStart;
|
||||
}
|
||||
|
||||
export class AiopsPlugin implements Plugin<AiopsPluginSetup, AiopsPluginStart> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue