Skip to content

Commit

Permalink
Added Open in Log explorer action
Browse files Browse the repository at this point in the history
  • Loading branch information
yngrdyn committed Dec 13, 2023
1 parent 6443b57 commit 3805285
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
EuiFlexGroup,
EuiFlexItem,
EuiIcon,
EuiLink,
EuiSkeletonRectangle,
EuiText,
EuiToolTip,
Expand All @@ -28,6 +29,7 @@ import {
import { DataStreamStat } from '../../../common/data_streams_stats/data_stream_stat';
import loggingIcon from '../../icons/logging.svg';
import { QualityIndicator, QualityPercentageIndicator } from '../quality_indicator';
import { useLinkToLogExplorer } from '../../hooks/use_link_to_log_explorer';

const nameColumnName = i18n.translate('xpack.datasetQuality.nameColumnName', {
defaultMessage: 'Dataset Name',
Expand All @@ -41,6 +43,17 @@ const degradedDocsColumnName = i18n.translate('xpack.datasetQuality.degradedDocs
defaultMessage: 'Degraded Docs',
});

const lastActivityColumnName = i18n.translate('xpack.datasetQuality.lastActivityColumnName', {
defaultMessage: 'Last Activity',
});

const actionsColumnName = i18n.translate('xpack.datasetQuality.actionsColumnName', {
defaultMessage: 'Actions',
});
const openActionName = i18n.translate('xpack.datasetQuality.openActionName', {
defaultMessage: 'Open',
});

const degradedDocsDescription = (minimimPercentage: number) =>
i18n.translate('xpack.datasetQuality.degradedDocsQualityDescription', {
defaultMessage: 'greater than {minimimPercentage}%',
Expand Down Expand Up @@ -83,10 +96,6 @@ const degradedDocsColumnTooltip = (
/>
);

const lastActivityColumnName = i18n.translate('xpack.datasetQuality.lastActivityColumnName', {
defaultMessage: 'Last Activity',
});

export const getDatasetQualitTableColumns = ({
fieldFormats,
loadingDegradedStats,
Expand Down Expand Up @@ -164,5 +173,17 @@ export const getDatasetQualitTableColumns = ({
.convert(timestamp),
sortable: true,
},
{
name: actionsColumnName,
render: (dataStreamStat: DataStreamStat) => (
<LinkToLogExplorer dataStreamStat={dataStreamStat} />
),
width: '100px',
},
];
};

const LinkToLogExplorer = ({ dataStreamStat }: { dataStreamStat: DataStreamStat }) => {
const url = useLinkToLogExplorer({ dataStreamStat });
return <EuiLink href={url}>{openActionName}</EuiLink>;
};
Original file line number Diff line number Diff line change
@@ -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 {
SingleDatasetLocatorParams,
SINGLE_DATASET_LOCATOR_ID,
} from '@kbn/deeplinks-observability';
import { useMemo } from 'react';
import { DataStreamStat } from '../../common/data_streams_stats/data_stream_stat';
import { useKibanaContextForPlugin } from '../utils';

export const useLinkToLogExplorer = ({ dataStreamStat }: { dataStreamStat: DataStreamStat }) => {
const {
services: { share },
} = useKibanaContextForPlugin();
const [dataset, namespace] = dataStreamStat.title.split('-');
const integration = dataStreamStat.integration?.name;

const url = useMemo(() => {
return share.url.locators
.get<SingleDatasetLocatorParams>(SINGLE_DATASET_LOCATOR_ID)
?.getRedirectUrl({
dataset,
timeRange: {
from: 'now-1d',
to: 'now',
},
integration,
filterControls: {
namespace: {
mode: 'include',
values: [namespace],
},
},
});
}, [dataset, integration, namespace, share.url.locators]);

return url;
};
10 changes: 3 additions & 7 deletions x-pack/plugins/log_explorer/public/controller/public_state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,7 @@ import {
DEFAULT_CONTEXT,
LogExplorerControllerContext,
} from '../state_machines/log_explorer_controller';
import {
LogExplorerPublicState,
LogExplorerPublicStateUpdate,
OptionsListControlOption,
} from './types';
import { LogExplorerPublicState, LogExplorerPublicStateUpdate, OptionsListControl } from './types';

export const getPublicStateFromContext = (
context: LogExplorerControllerContext
Expand Down Expand Up @@ -80,7 +76,7 @@ const getPublicControlsStateFromControlPanels = (

const getOptionsListPublicControlStateFromControlPanel = (
optionsListControlPanel: ControlPanels[string]
): OptionsListControlOption => ({
): OptionsListControl => ({
mode: optionsListControlPanel.explicitInput.exclude ? 'exclude' : 'include',
selection: optionsListControlPanel.explicitInput.existsSelected
? { type: 'exists' }
Expand Down Expand Up @@ -113,7 +109,7 @@ const getControlPanelsFromPublicControlsState = (

const getControlPanelFromOptionsListPublicControlState = (
controlId: string,
publicControlState: OptionsListControlOption
publicControlState: OptionsListControl
): ControlPanels[string] => {
const defaultControlPanelConfig = controlPanelConfigs[controlId];

Expand Down
20 changes: 11 additions & 9 deletions x-pack/plugins/log_explorer/public/controller/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,21 @@ export type LogExplorerDiscoverServices = Pick<
};

export interface OptionsListControlOption {
type: 'options';
selectedOptions: string[];
}

export interface OptionsListControlExists {
type: 'exists';
}

export interface OptionsListControl {
mode: 'include' | 'exclude';
selection:
| {
type: 'options';
selectedOptions: string[];
}
| {
type: 'exists';
};
selection: OptionsListControlOption | OptionsListControlExists;
}

export interface ControlOptions {
[availableControlsPanels.NAMESPACE]?: OptionsListControlOption;
[availableControlsPanels.NAMESPACE]?: OptionsListControl;
}

// we might want to wrap this into an object that has a "state value" laster
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/log_explorer/public/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export type { LogExplorerPluginSetup, LogExplorerPluginStart } from './types';
export {
getDiscoverColumnsFromDisplayOptions,
getDiscoverGridFromDisplayOptions,
getDiscoverFiltersFromState,
} from './utils/convert_discover_app_state';

export function plugin(context: PluginInitializerContext<LogExplorerConfig>) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@

import { QueryState } from '@kbn/data-plugin/public';
import { DiscoverAppState } from '@kbn/discover-plugin/public';
import { ExistsFilter, Filter, FILTERS, PhrasesFilter } from '@kbn/es-query';
import { PhraseFilterValue } from '@kbn/es-query/src/filters/build_filters';
import { cloneDeep } from 'lodash';
import {
ChartDisplayOptions,
DisplayOptions,
GridColumnDisplayOptions,
GridRowsDisplayOptions,
} from '../../common';
import { ControlOptions, OptionsListControlOption } from '../controller';

export const getGridColumnDisplayOptionsFromDiscoverAppState = (
discoverAppState: DiscoverAppState
Expand Down Expand Up @@ -71,3 +74,60 @@ export const getDiscoverGridFromDisplayOptions = (
return gridColumns;
}, {}),
});

const createDiscoverPhrasesFilter = ({
key,
values,
negate,
}: {
values: PhraseFilterValue[];
key: string;
negate?: boolean;
}): PhrasesFilter =>
({
meta: {
key,
type: FILTERS.PHRASES,
params: values,
},
query: {
bool: {
should: values.map((value) => ({ match_phrase: { [key]: value.toString() } })),
minimum_should_match: 1,
},
},
} as PhrasesFilter);

const createDiscoverExistsFilter = ({
key,
negate,
}: {
key: string;
negate?: boolean;
}): ExistsFilter => ({
meta: {
key,
negate,
type: FILTERS.EXISTS,
},
query: { exists: { field: key } },
});

export const getDiscoverFiltersFromState = (filters: Filter[] = [], controls?: ControlOptions) => [
...filters,
...(controls
? Object.keys(controls).map((key) =>
controls[key as keyof ControlOptions]?.selection.type === 'exists'
? createDiscoverExistsFilter({
key,
negate: controls[key as keyof ControlOptions]?.mode === 'exclude',
})
: createDiscoverPhrasesFilter({
key,
values: (controls[key as keyof ControlOptions]?.selection as OptionsListControlOption)
.selectedOptions,
negate: controls[key as keyof ControlOptions]?.mode === 'exclude',
})
)
: []),
];
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import { EuiHeaderLink } from '@elastic/eui';
import { DiscoverAppLocatorParams } from '@kbn/discover-plugin/common';
import { DiscoverStart } from '@kbn/discover-plugin/public';
import { hydrateDatasetSelection } from '@kbn/log-explorer-plugin/common';
import { getDiscoverColumnsFromDisplayOptions } from '@kbn/log-explorer-plugin/public';
import {
getDiscoverColumnsFromDisplayOptions,
getDiscoverFiltersFromState,
} from '@kbn/log-explorer-plugin/public';
import { MatchedStateFromActor } from '@kbn/xstate-utils';
import { useActor } from '@xstate/react';
import React, { useMemo } from 'react';
Expand Down Expand Up @@ -54,7 +57,7 @@ export const DiscoverLinkForValidState = React.memo(
() => ({
breakdownField: logExplorerState.chart.breakdownField ?? undefined,
columns: getDiscoverColumnsFromDisplayOptions(logExplorerState),
filters: logExplorerState.filters,
filters: getDiscoverFiltersFromState(logExplorerState.filters, logExplorerState.controls),
query: logExplorerState.query,
refreshInterval: logExplorerState.refreshInterval,
timeRange: logExplorerState.time,
Expand Down

0 comments on commit 3805285

Please sign in to comment.