Fix saving controlConfigs in URL and set status query config in controls

This commit is contained in:
Maryam Saeidi 2025-01-07 10:50:21 +01:00
parent 9d50cc5c94
commit c6cad2dbe1
5 changed files with 44 additions and 83 deletions

View file

@ -36,13 +36,13 @@ export function ObservabilityAlertSearchBar({
onKueryChange,
onRangeFromChange,
onRangeToChange,
onControlFiltersChange,
// onStatusChange,
onControlConfigsChange,
onFiltersChange,
onFilterControlsChange,
showFilterBar = false,
controlFilters = [],
controlConfigs,
filters = defaultFilters,
filterControls = defaultFilters,
savedQuery,
setSavedQuery,
kuery,
@ -58,8 +58,7 @@ export function ObservabilityAlertSearchBar({
useToasts,
uiSettings,
},
}: // status,
ObservabilityAlertSearchBarProps) {
}: ObservabilityAlertSearchBarProps) {
const toasts = useToasts();
const [spaceId, setSpaceId] = useState<string>();
@ -67,42 +66,6 @@ ObservabilityAlertSearchBarProps) {
() => (setSavedQuery ? setSavedQuery(undefined) : null),
[setSavedQuery]
);
// const onAlertStatusChange = useCallback(
// (alertStatus: AlertStatus) => {
// try {
// onEsQueryChange(
// buildEsQuery({
// timeRange: {
// to: rangeTo,
// from: rangeFrom,
// },
// kuery,
// queries: [...getAlertStatusQuery(alertStatus), ...defaultSearchQueries],
// config: getEsQueryConfig(uiSettings),
// })
// );
// } catch (error) {
// toasts.addError(error, {
// title: toastTitle,
// });
// onKueryChange(DEFAULT_QUERY_STRING);
// }
// },
// [
// onEsQueryChange,
// rangeTo,
// rangeFrom,
// kuery,
// defaultSearchQueries,
// uiSettings,
// toasts,
// onKueryChange,
// ]
// );
// useEffect(() => {
// onAlertStatusChange(status);
// }, [onAlertStatusChange, status]);
const filterControlsStorageKey = useMemo(
() => ['observabilitySearchBar', spaceId, appName, 'filterControls'].filter(Boolean).join('.'),
@ -119,7 +82,7 @@ ObservabilityAlertSearchBarProps) {
},
kuery,
queries: defaultSearchQueries,
filters: [...filters, ...controlFilters],
filters: [...filters, ...filterControls],
config: getEsQueryConfig(uiSettings),
})
);
@ -136,7 +99,7 @@ ObservabilityAlertSearchBarProps) {
kuery,
defaultSearchQueries,
filters,
controlFilters,
filterControls,
uiSettings,
toasts,
onKueryChange,
@ -209,8 +172,9 @@ ObservabilityAlertSearchBarProps) {
spaceId={spaceId}
chainingSystem="HIERARCHICAL"
controlsUrlState={controlConfigs}
filters={controlFilters}
onFiltersChange={onControlFiltersChange}
setControlsUrlState={onControlConfigsChange}
filters={filters}
onFiltersChange={onFilterControlsChange}
storageKey={filterControlsStorageKey}
services={{
http,

View file

@ -5,14 +5,13 @@
* 2.0.
*/
import { FilterControlConfig as ControlConfig } from '@kbn/alerts-ui-shared';
import { type FilterControlConfig } from '@kbn/alerts-ui-shared';
import { Filter } from '@kbn/es-query';
import {
createStateContainer,
createStateContainerReactHelpers,
} from '@kbn/kibana-utils-plugin/public';
import { AlertStatus } from '../../../../common/typings';
import { ALL_ALERTS } from '../constants';
import { AlertSearchBarContainerState } from '../types';
interface AlertSearchBarStateTransitions {
@ -34,22 +33,16 @@ interface AlertSearchBarStateTransitions {
setSavedQueryId: (
state: AlertSearchBarContainerState
) => (savedQueryId?: string) => AlertSearchBarContainerState;
setControlFilters: (
state: AlertSearchBarContainerState
) => (controlFilters: Filter[]) => AlertSearchBarContainerState;
setControlConfigs: (
state: AlertSearchBarContainerState
) => (controlConfigs: ControlConfig[]) => AlertSearchBarContainerState;
) => (controlConfigs: FilterControlConfig[]) => AlertSearchBarContainerState;
}
const DEFAULT_STATE: AlertSearchBarContainerState = {
rangeFrom: 'now-24h',
rangeTo: 'now',
kuery: '',
status: ALL_ALERTS.status,
filters: [],
controlFilters: [],
controlConfigs: [],
};
const transitions: AlertSearchBarStateTransitions = {
@ -59,7 +52,6 @@ const transitions: AlertSearchBarStateTransitions = {
setStatus: (state) => (status) => ({ ...state, status }),
setFilters: (state) => (filters) => ({ ...state, filters }),
setSavedQueryId: (state) => (savedQueryId) => ({ ...state, savedQueryId }),
setControlFilters: (state) => (controlFilters) => ({ ...state, controlFilters }),
setControlConfigs: (state) => (controlConfigs) => ({ ...state, controlConfigs }),
};

View file

@ -10,7 +10,7 @@ import { pipe } from 'fp-ts/pipeable';
import * as t from 'io-ts';
import { useEffect, useState } from 'react';
import { useHistory } from 'react-router-dom';
import { ALERT_STATUS_ACTIVE, ALERT_STATUS_RECOVERED } from '@kbn/rule-data-utils';
import { ALERT_STATUS_ACTIVE, ALERT_STATUS_RECOVERED, ALERT_STATUS } from '@kbn/rule-data-utils';
import { SavedQuery, TimefilterContract } from '@kbn/data-plugin/public';
import {
createKbnUrlStateStorage,
@ -57,19 +57,10 @@ export function useAlertSearchBarStateContainer(
setStatus,
setFilters,
setSavedQueryId,
setControlFilters,
setControlConfigs,
} = stateContainer.transitions;
const {
rangeFrom,
rangeTo,
kuery,
status,
filters,
savedQueryId,
controlFilters,
controlConfigs,
} = useContainerSelector(stateContainer, (state) => state);
const { rangeFrom, rangeTo, kuery, status, filters, savedQueryId, controlConfigs } =
useContainerSelector(stateContainer, (state) => state);
useEffect(() => {
if (!savedQuery) {
@ -108,9 +99,7 @@ export function useAlertSearchBarStateContainer(
onRangeToChange: setRangeTo,
onStatusChange: setStatus,
onFiltersChange: setFilters,
onControlFiltersChange: setControlFilters,
onControlConfigsChange: setControlConfigs,
controlFilters,
controlConfigs,
filters,
rangeFrom,
@ -194,7 +183,9 @@ function initializeUrlAndStateContainer(
const urlState = alertSearchBarState.decode(
urlStateStorage.get<Partial<AlertSearchBarContainerState>>(urlStorageKey)
);
const validUrlState = isRight(urlState) ? pipe(urlState).right : {};
const validUrlState: Partial<AlertSearchBarContainerState> = isRight(urlState)
? pipe(urlState).right
: {};
const timeFilterTime = timefilterService.getTime();
const timeFilterState = timefilterService.isTimeTouched()
? {
@ -203,6 +194,18 @@ function initializeUrlAndStateContainer(
}
: {};
// This part is for backward compatibility. Previously, we saved status in the status query
// parameter. Now, we save it in the controlConfigs.
if (validUrlState.status !== undefined && validUrlState.controlConfigs) {
const statusControl = validUrlState.controlConfigs.find(
(control) => control.fieldName === ALERT_STATUS
);
if (statusControl) {
statusControl.selectedOptions = [validUrlState.status];
validUrlState.status = undefined;
}
}
const currentState = {
...defaultState,
...timeFilterState,

View file

@ -6,7 +6,7 @@
*/
import { ReactElement } from 'react';
import { FilterControlConfig as ControlConfig } from '@kbn/alerts-ui-shared';
import { type FilterControlConfig } from '@kbn/alerts-ui-shared';
import type { HttpStart } from '@kbn/core-http-browser';
import { type NotificationsStart, ToastsStart } from '@kbn/core-notifications-browser';
import {
@ -58,20 +58,21 @@ export interface ObservabilityAlertSearchBarProps
extends AlertSearchBarContainerState,
AlertSearchBarStateTransitions,
CommonAlertSearchBarProps {
showFilterBar?: boolean;
savedQuery?: SavedQuery;
services: Services;
filterControls: Filter[];
onFilterControlsChange: (controlConfigs: Filter[]) => void;
savedQuery?: SavedQuery;
showFilterBar?: boolean;
}
export interface AlertSearchBarContainerState {
rangeFrom: string;
rangeTo: string;
kuery: string;
status: AlertStatus;
status?: AlertStatus;
filters?: Filter[];
savedQueryId?: string;
controlFilters?: Filter[];
controlConfigs?: ControlConfig[];
controlConfigs?: FilterControlConfig[];
}
interface AlertSearchBarStateTransitions {
@ -81,8 +82,7 @@ interface AlertSearchBarStateTransitions {
onStatusChange: (status: AlertStatus) => void;
onFiltersChange?: (filters: Filter[]) => void;
setSavedQuery?: (savedQueryId?: SavedQuery) => void;
onControlFiltersChange: (controlFilters: Filter[]) => void;
onControlConfigsChange: (controlConfigs: ControlConfig[]) => void;
onControlConfigsChange?: (controlConfigs: FilterControlConfig[]) => void;
}
interface CommonAlertSearchBarProps {

View file

@ -17,7 +17,6 @@ import { DEFAULT_APP_CATEGORIES } from '@kbn/core-application-common';
import { AlertsGrouping } from '@kbn/alerts-grouping';
import { rulesLocatorID } from '../../../common';
import { ALERT_STATUS_FILTER } from '../../components/alert_search_bar/constants';
import { renderGroupPanel } from '../../components/alerts_table/grouping/render_group_panel';
import { getGroupStats } from '../../components/alerts_table/grouping/get_group_stats';
import { getAggregationsByGroupingField } from '../../components/alerts_table/grouping/get_aggregations_by_grouping_field';
@ -85,6 +84,7 @@ function InternalAlertsPage() {
},
} = data;
const { ObservabilityPageTemplate, observabilityRuleTypeRegistry } = usePluginContext();
const [filterControls, setFilterControls] = useState<Filter[]>([]);
const alertSearchBarStateProps = useAlertSearchBarStateContainer(ALERTS_URL_STORAGE_KEY, {
replace: false,
});
@ -248,6 +248,8 @@ function InternalAlertsPage() {
{...alertSearchBarStateProps}
appName={ALERTS_SEARCH_BAR_ID}
onEsQueryChange={setEsQuery}
filterControls={filterControls}
onFilterControlsChange={setFilterControls}
showFilterBar
services={{
timeFilterService,
@ -277,12 +279,12 @@ function InternalAlertsPage() {
<AlertsGrouping<AlertsByGroupingAgg>
ruleTypeIds={OBSERVABILITY_RULE_TYPE_IDS_WITH_SUPPORTED_STACK_RULE_TYPES}
consumers={observabilityAlertFeatureIds}
defaultFilters={
ALERT_STATUS_FILTER[alertSearchBarStateProps.status] ?? DEFAULT_FILTERS
}
from={alertSearchBarStateProps.rangeFrom}
to={alertSearchBarStateProps.rangeTo}
globalFilters={alertSearchBarStateProps.filters ?? DEFAULT_FILTERS}
globalFilters={[
...(alertSearchBarStateProps.filters ?? DEFAULT_FILTERS),
...filterControls,
]}
globalQuery={{ query: alertSearchBarStateProps.kuery, language: 'kuery' }}
groupingId={ALERTS_PAGE_ALERTS_TABLE_CONFIG_ID}
defaultGroupingOptions={DEFAULT_GROUPING_OPTIONS}