Fix fiter controls in apm app and change defaultSearchQueries to defaultFilters

This commit is contained in:
Maryam Saeidi 2025-01-07 14:06:31 +01:00
parent c6cad2dbe1
commit bc0970e8ce
9 changed files with 90 additions and 57 deletions

View file

@ -7,6 +7,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import type { ObservabilityRuleTypeRegistry } from '@kbn/observability-plugin/public';
import { AppMountParameters, CoreStart, APP_WRAPPER_CLASS } from '@kbn/core/public';
import { KibanaRenderContextProvider } from '@kbn/react-kibana-context-render';
@ -61,6 +62,7 @@ export const renderApp = ({
kibanaEnvironment,
licensing: pluginsStart.licensing,
};
const queryClient = new QueryClient();
// render APM feedback link in global help menu
setHelpExtension(coreStart);
@ -81,11 +83,13 @@ export const renderApp = ({
},
}}
>
<ApmAppRoot
apmPluginContextValue={apmPluginContextValue}
pluginsStart={pluginsStart}
apmServices={apmServices}
/>
<QueryClientProvider client={queryClient}>
<ApmAppRoot
apmPluginContextValue={apmPluginContextValue}
pluginsStart={pluginsStart}
apmServices={apmServices}
/>
</QueryClientProvider>
</KibanaThemeProvider>
</KibanaRenderContextProvider>,
element

View file

@ -10,7 +10,7 @@ import { useHistory } from 'react-router-dom';
import { ObservabilityAlertSearchBar } from '@kbn/observability-plugin/public';
import { AlertStatus } from '@kbn/observability-plugin/common/typings';
import { EuiPanel, EuiFlexItem, EuiFlexGroup } from '@elastic/eui';
import { BoolQuery } from '@kbn/es-query';
import { BoolQuery, Filter } from '@kbn/es-query';
import { AlertConsumers } from '@kbn/rule-data-utils';
import { useKibana } from '@kbn/kibana-react-plugin/public';
import {
@ -19,7 +19,7 @@ import {
} from '../../../../common/alerting/config/apm_alerting_feature_ids';
import { ApmPluginStartDeps } from '../../../plugin';
import { useAnyOfApmParams } from '../../../hooks/use_apm_params';
import { SERVICE_NAME } from '../../../../common/es_fields/apm';
import { SERVICE_ENVIRONMENT, SERVICE_NAME } from '../../../../common/es_fields/apm';
import { getEnvironmentKuery } from '../../../../common/environment_filter_values';
import { push } from '../../shared/links/url_helpers';
@ -48,30 +48,45 @@ export function AlertsOverview() {
alertsTableConfigurationRegistry,
},
notifications,
data: {
query: {
timefilter: { timefilter: timeFilterService },
},
},
data,
dataViews,
http,
spaces,
uiSettings,
observability: { observabilityRuleTypeRegistry },
} = services;
const {
query: {
timefilter: { timefilter: timeFilterService },
},
} = data;
const useToasts = () => notifications!.toasts;
const apmQueries = useMemo(() => {
const apmFilters: Filter[] = useMemo(() => {
const environmentKuery = getEnvironmentKuery(environment);
let query = `${SERVICE_NAME}:${serviceName}`;
if (environmentKuery) {
query += ` AND ${environmentKuery}`;
}
return [
const filters: Filter[] = [
{
query,
language: 'kuery',
query: {
match_phrase: {
[SERVICE_NAME]: serviceName,
},
},
meta: {},
},
];
if (environmentKuery) {
filters.push({
query: {
match_phrase: {
[SERVICE_ENVIRONMENT]: environmentKuery,
},
},
meta: {},
});
}
return filters;
}, [serviceName, environment]);
const onKueryChange = useCallback(
@ -90,7 +105,7 @@ export function AlertsOverview() {
onRangeFromChange={(value) => push(history, { query: { rangeFrom: value } })}
onRangeToChange={(value) => push(history, { query: { rangeTo: value } })}
onKueryChange={onKueryChange}
defaultSearchQueries={apmQueries}
defaultFilters={apmFilters}
onStatusChange={setAlertStatusFilter}
onEsQueryChange={setEsQuery}
rangeTo={rangeTo}
@ -99,6 +114,11 @@ export function AlertsOverview() {
services={{
timeFilterService,
AlertsSearchBar,
http,
data,
dataViews,
notifications,
spaces,
useToasts,
uiSettings,
}}

View file

@ -29,6 +29,7 @@ describe('ObservabilityAlertSearchBar', () => {
appName: 'testAppName',
kuery: '',
filters: [],
filterControls: [],
onRangeFromChange: jest.fn(),
onRangeToChange: jest.fn(),
onKueryChange: jest.fn(),
@ -36,7 +37,7 @@ describe('ObservabilityAlertSearchBar', () => {
onEsQueryChange: jest.fn(),
onFiltersChange: jest.fn(),
onControlConfigsChange: jest.fn(),
onControlFiltersChange: jest.fn(),
onFilterControlsChange: jest.fn(),
setSavedQuery: jest.fn(),
rangeTo: 'now',
rangeFrom: 'now-15m',

View file

@ -14,24 +14,17 @@ import { i18n } from '@kbn/i18n';
import { Filter } from '@kbn/es-query';
import { getEsQueryConfig } from '@kbn/data-plugin/common';
import { OBSERVABILITY_RULE_TYPE_IDS_WITH_SUPPORTED_STACK_RULE_TYPES } from '../../../common/constants';
import { DEFAULT_QUERIES, DEFAULT_QUERY_STRING } from './constants';
import { DEFAULT_QUERY_STRING, EMPTY_FILTERS } from './constants';
import { ObservabilityAlertSearchBarProps } from './types';
import { buildEsQuery } from '../../utils/build_es_query';
// import { AlertStatus } from '../../../common/typings';
// const getAlertStatusQuery = (status: string): Query[] => {
// return ALERT_STATUS_QUERY[status]
// ? [{ query: ALERT_STATUS_QUERY[status], language: 'kuery' }]
// : [];
// };
const toastTitle = i18n.translate('xpack.observability.alerts.searchBar.invalidQueryTitle', {
defaultMessage: 'Invalid query string',
});
const defaultFilters: Filter[] = [];
export function ObservabilityAlertSearchBar({
appName,
defaultSearchQueries = DEFAULT_QUERIES,
defaultFilters = EMPTY_FILTERS,
onEsQueryChange,
onKueryChange,
onRangeFromChange,
@ -41,8 +34,8 @@ export function ObservabilityAlertSearchBar({
onFilterControlsChange,
showFilterBar = false,
controlConfigs,
filters = defaultFilters,
filterControls = defaultFilters,
filters = EMPTY_FILTERS,
filterControls = EMPTY_FILTERS,
savedQuery,
setSavedQuery,
kuery,
@ -81,8 +74,7 @@ export function ObservabilityAlertSearchBar({
from: rangeFrom,
},
kuery,
queries: defaultSearchQueries,
filters: [...filters, ...filterControls],
filters: [...filters, ...filterControls, ...defaultFilters],
config: getEsQueryConfig(uiSettings),
})
);
@ -97,7 +89,7 @@ export function ObservabilityAlertSearchBar({
rangeTo,
rangeFrom,
kuery,
defaultSearchQueries,
defaultFilters,
filters,
filterControls,
uiSettings,
@ -173,7 +165,7 @@ export function ObservabilityAlertSearchBar({
chainingSystem="HIERARCHICAL"
controlsUrlState={controlConfigs}
setControlsUrlState={onControlConfigsChange}
filters={filters}
filters={[...filters, ...defaultFilters]}
onFiltersChange={onFilterControlsChange}
storageKey={filterControlsStorageKey}
services={{
@ -184,11 +176,6 @@ export function ObservabilityAlertSearchBar({
}}
ControlGroupRenderer={ControlGroupRenderer}
/>
{/* <EuiFlexGroup justifyContent="spaceBetween" alignItems="center">*/}
{/* <EuiFlexItem grow={false}>*/}
{/* <AlertsStatusFilter status={status} onChange={onStatusChange} />*/}
{/* </EuiFlexItem>*/}
{/* </EuiFlexGroup>*/}
</EuiFlexItem>
</EuiFlexGroup>
);

View file

@ -5,7 +5,8 @@
* 2.0.
*/
import React from 'react';
import { Filter } from '@kbn/es-query';
import React, { useState } from 'react';
import {
alertSearchBarStateContainer,
Provider,
@ -20,6 +21,7 @@ import { useToasts } from '../../hooks/use_toast';
function AlertSearchbarWithUrlSync(props: AlertSearchBarWithUrlSyncProps) {
const { urlStorageKey, defaultState = DEFAULT_STATE, ...searchBarProps } = props;
const stateProps = useAlertSearchBarStateContainer(urlStorageKey, undefined, defaultState);
const [filterControls, setFilterControls] = useState<Filter[]>([]);
const {
data,
triggersActionsUi: { getAlertsSearchBar: AlertsSearchBar },
@ -39,6 +41,8 @@ function AlertSearchbarWithUrlSync(props: AlertSearchBarWithUrlSyncProps) {
<ObservabilityAlertSearchBar
{...stateProps}
{...searchBarProps}
filterControls={filterControls}
onFilterControlsChange={setFilterControls}
showFilterBar
services={{
timeFilterService,

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import { Query } from '@kbn/es-query';
import { Filter } from '@kbn/es-query';
import { i18n } from '@kbn/i18n';
import {
ALERT_STATUS_ACTIVE,
@ -16,7 +16,7 @@ import {
import { AlertStatusFilter } from '../../../common/typings';
import { ALERT_STATUS_ALL } from '../../../common/constants';
export const DEFAULT_QUERIES: Query[] = [];
export const EMPTY_FILTERS: Filter[] = [];
export const DEFAULT_QUERY_STRING = '';
export const ALL_ALERTS: AlertStatusFilter = {

View file

@ -17,7 +17,7 @@ import {
import { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public';
import type { SpacesPluginStart } from '@kbn/spaces-plugin/public';
import { AlertsSearchBarProps } from '@kbn/triggers-actions-ui-plugin/public/application/sections/alerts_search_bar';
import { BoolQuery, Filter, Query } from '@kbn/es-query';
import { BoolQuery, Filter } from '@kbn/es-query';
import type { IUiSettingsClient } from '@kbn/core-ui-settings-browser';
import { AlertStatus } from '../../../common/typings';
export interface AlertStatusFilterProps {
@ -88,5 +88,5 @@ interface AlertSearchBarStateTransitions {
interface CommonAlertSearchBarProps {
appName: string;
onEsQueryChange: (query: { bool: BoolQuery }) => void;
defaultSearchQueries?: Query[];
defaultFilters?: Filter[];
}

View file

@ -25,7 +25,7 @@ import {
ALERT_UUID,
TAGS,
} from '@kbn/rule-data-utils';
import { BoolQuery, Filter, type Query } from '@kbn/es-query';
import { BoolQuery, Filter } from '@kbn/es-query';
import { AlertsGrouping } from '@kbn/alerts-grouping';
import { ObservabilityFields } from '../../../../common/utils/alerting/types';
@ -69,7 +69,8 @@ interface Props {
alert?: TopAlert<ObservabilityFields>;
}
const defaultState: AlertSearchBarContainerState = { ...DEFAULT_STATE, status: 'active' };
// TODO: Bring back setting default status filter as active
const defaultState: AlertSearchBarContainerState = { ...DEFAULT_STATE };
const DEFAULT_FILTERS: Filter[] = [];
export function InternalRelatedAlerts({ alert }: Props) {
@ -95,8 +96,17 @@ export function InternalRelatedAlerts({ alert }: Props) {
const sharedFields = getSharedFields(alert?.fields);
const kuery = getRelatedAlertKuery({ tags, groups, ruleId, sharedFields });
const defaultQuery = useRef<Query[]>([
{ query: `not kibana.alert.uuid: ${alertId}`, language: 'kuery' },
const defaultFilters = useRef<Filter[]>([
{
query: {
match_phrase: {
'kibana.alert.uuid': alertId,
},
},
meta: {
negate: true,
},
},
]);
useEffect(() => {
@ -118,7 +128,7 @@ export function InternalRelatedAlerts({ alert }: Props) {
appName={RELATED_ALERTS_SEARCH_BAR_ID}
onEsQueryChange={setEsQuery}
urlStorageKey={SEARCH_BAR_URL_STORAGE_KEY}
defaultSearchQueries={defaultQuery.current}
defaultFilters={defaultFilters.current}
defaultState={{
...defaultState,
kuery,

View file

@ -16,7 +16,7 @@ import {
import { i18n } from '@kbn/i18n';
import type { RuleTypeParams } from '@kbn/alerting-plugin/common';
import type { Rule } from '@kbn/triggers-actions-ui-plugin/public';
import type { Query, BoolQuery } from '@kbn/es-query';
import type { BoolQuery } from '@kbn/es-query';
import { observabilityAlertFeatureIds } from '../../../../common';
import { useKibana } from '../../../utils/kibana_react';
import { usePluginContext } from '../../../hooks/use_plugin_context';
@ -65,8 +65,15 @@ export function RuleDetailsTabs({
} = useKibana().services;
const { observabilityRuleTypeRegistry } = usePluginContext();
const ruleQuery = useRef<Query[]>([
{ query: `kibana.alert.rule.uuid: ${ruleId}`, language: 'kuery' },
const ruleFilters = useRef<Filter[]>([
{
query: {
match_phrase: {
'kibana.alert.rule.uuid': ruleId,
},
},
meta: {},
},
]);
const tabs: EuiTabbedContentTab[] = [
@ -84,7 +91,7 @@ export function RuleDetailsTabs({
appName={RULE_DETAILS_ALERTS_SEARCH_BAR_ID}
onEsQueryChange={onEsQueryChange}
urlStorageKey={RULE_DETAILS_SEARCH_BAR_URL_STORAGE_KEY}
defaultSearchQueries={ruleQuery.current}
defaultFilters={ruleFilters.current}
/>
<EuiSpacer size="s" />