From bcc4f11e0b97e991d94f5e6368dfa154f753d2ca Mon Sep 17 00:00:00 2001 From: Carlos Crespo Date: Mon, 12 Jun 2023 14:30:23 +0200 Subject: [PATCH] [Infrastructure UI] Filter control re-rendering problem fix (#159320) fixes https://github.com/elastic/kibana/issues/159317 ## Summary This PR fixes a problem in the utilization of the `ControlGroupRenderer` component in the Hosts View. The problem originated from the need to manually compare changes in the `filterPanel` object, to prevent the page from making duplicate requests https://github.com/elastic/kibana/assets/2767137/b38f5691-0519-4ae2-aab2-daaf0f72cd0d After many changes that the code has been through, the comparison mentioned above has become unnecessary. ### How to test - Start a local Kibana instance - Navigate to `Infrastructure > Hosts` - Play with the filter controls (depending on how fast the user is, it might hang for a little while, but this won't slow the whole page down) --- .../search_bar/controls_content.tsx | 34 ++++++++----------- .../components/search_bar/limit_options.tsx | 4 +-- .../search_bar/unified_search_bar.tsx | 20 ++++------- 3 files changed, 23 insertions(+), 35 deletions(-) diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/controls_content.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/controls_content.tsx index e2bd7d0c74dae..9338f15f3ece9 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/controls_content.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/controls_content.tsx @@ -12,16 +12,15 @@ import { type ControlGroupInput, } from '@kbn/controls-plugin/public'; import { ViewMode } from '@kbn/embeddable-plugin/public'; -import { compareFilters, COMPARE_ALL_OPTIONS, Filter, Query, TimeRange } from '@kbn/es-query'; +import type { Filter, Query, TimeRange } from '@kbn/es-query'; import { DataView } from '@kbn/data-views-plugin/public'; -import { skipWhile, Subscription } from 'rxjs'; +import { Subscription } from 'rxjs'; import { useControlPanels } from '../../hooks/use_control_panels_url_state'; interface Props { dataView: DataView | undefined; timeRange: TimeRange; filters: Filter[]; - selectedOptions: Filter[]; query: Query; onFiltersChange: (filters: Filter[]) => void; } @@ -30,13 +29,11 @@ export const ControlsContent: React.FC = ({ dataView, filters, query, - selectedOptions, timeRange, onFiltersChange, }) => { const [controlPanels, setControlPanels] = useControlPanels(dataView); - const inputSubscription = useRef(); - const filterSubscription = useRef(); + const subscriptions = useRef(new Subscription()); const getInitialInput = useCallback(async () => { const initialInput: Partial = { @@ -57,27 +54,24 @@ export const ControlsContent: React.FC = ({ const loadCompleteHandler = useCallback( (controlGroup: ControlGroupAPI) => { if (!controlGroup) return; - inputSubscription.current = controlGroup.onFiltersPublished$ - .pipe( - skipWhile((newFilters) => - compareFilters(selectedOptions, newFilters, COMPARE_ALL_OPTIONS) - ) - ) - .subscribe((newFilters) => { + + subscriptions.current.add( + controlGroup.onFiltersPublished$.subscribe((newFilters) => { onFiltersChange(newFilters); - }); + }) + ); - filterSubscription.current = controlGroup - .getInput$() - .subscribe(({ panels }) => setControlPanels(panels)); + subscriptions.current.add( + controlGroup.getInput$().subscribe(({ panels }) => setControlPanels(panels)) + ); }, - [onFiltersChange, setControlPanels, selectedOptions] + [onFiltersChange, setControlPanels] ); useEffect(() => { + const currentSubscriptions = subscriptions.current; return () => { - filterSubscription.current?.unsubscribe(); - inputSubscription.current?.unsubscribe(); + currentSubscriptions.unsubscribe(); }; }, []); diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/limit_options.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/limit_options.tsx index 5c77556483b77..b54d187d482e3 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/limit_options.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/limit_options.tsx @@ -27,7 +27,7 @@ interface Props { export const LimitOptions = ({ limit, onChange }: Props) => { const [idSelected, setIdSelected] = useState(limit as number); - const onSelected = (value: number) => { + const onSelected = (_id: string, value: number) => { setIdSelected(value); onChange(value); }; @@ -70,7 +70,7 @@ export const LimitOptions = ({ limit, onChange }: Props) => { })} idSelected={buildId(idSelected)} options={options} - onChange={(_, value: number) => onSelected(value)} + onChange={onSelected} /> diff --git a/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/unified_search_bar.tsx b/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/unified_search_bar.tsx index b2e82c9ef4c7f..b0f537fc3e874 100644 --- a/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/unified_search_bar.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/hosts/components/search_bar/unified_search_bar.tsx @@ -5,14 +5,8 @@ * 2.0. */ -import React, { useMemo } from 'react'; -import { - compareFilters, - COMPARE_ALL_OPTIONS, - type Query, - type TimeRange, - type Filter, -} from '@kbn/es-query'; +import React, { useCallback, useMemo } from 'react'; +import type { Query, TimeRange, Filter } from '@kbn/es-query'; import { i18n } from '@kbn/i18n'; import { EuiFlexGrid, @@ -42,11 +36,12 @@ export const UnifiedSearchBar = () => { onSubmit({ limit }); }; - const onPanelFiltersChange = (panelFilters: Filter[]) => { - if (!compareFilters(searchCriteria.panelFilters, panelFilters, COMPARE_ALL_OPTIONS)) { + const onPanelFiltersChange = useCallback( + (panelFilters: Filter[]) => { onSubmit({ panelFilters }); - } - }; + }, + [onSubmit] + ); const handleRefresh = (payload: { query?: Query; dateRange: TimeRange }, isUpdate?: boolean) => { // This makes sure `onQueryChange` is only called when the submit button is clicked @@ -83,7 +78,6 @@ export const UnifiedSearchBar = () => { dataView={dataView} query={searchCriteria.query} filters={searchCriteria.filters} - selectedOptions={searchCriteria.panelFilters} onFiltersChange={onPanelFiltersChange} />