From 520465a2663a112c861d61cf4bf3e761b43ca093 Mon Sep 17 00:00:00 2001 From: Umberto Pepato Date: Mon, 16 Dec 2024 16:43:13 +0100 Subject: [PATCH] [ResponseOps][Rules] Add loading state to rule params data views selector (#203654) ## Summary Introduces a loading state in the data views select popover and renders a loading indicator when DVs are not available yet. This makes sure that even if the `savedObjectsClient.find` call of the data views service takes a long time, we don't show an empty popover in the meantime. https://github.com/user-attachments/assets/5bbe0c68-3ceb-4d7f-91fd-357db4caa5c1 ## References Fixes #198502 ## Release note Fix race condition in alerting rules data view selector --- .../components/data_view_select_popover.tsx | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/stack_alerts/public/rule_types/components/data_view_select_popover.tsx b/x-pack/plugins/stack_alerts/public/rule_types/components/data_view_select_popover.tsx index 988afb8d2182b..97b614a5b5785 100644 --- a/x-pack/plugins/stack_alerts/public/rule_types/components/data_view_select_popover.tsx +++ b/x-pack/plugins/stack_alerts/public/rule_types/components/data_view_select_popover.tsx @@ -18,6 +18,7 @@ import { EuiPopover, EuiPopoverFooter, EuiPopoverTitle, + EuiLoadingSpinner, EuiText, useEuiPaddingCSS, useIsWithinBreakpoints, @@ -63,6 +64,7 @@ export const DataViewSelectPopover: React.FunctionComponent { + const [loadingDataViews, setLoadingDataViews] = useState(false); const [dataViewItems, setDataViewsItems] = useState([]); const [dataViewPopoverOpen, setDataViewPopoverOpen] = useState(false); @@ -71,7 +73,7 @@ export const DataViewSelectPopover: React.FunctionComponent void | undefined>(); const allDataViewItems = useMemo( - () => [...dataViewItems, ...metadata.adHocDataViewList.map(toDataViewListItem)], + () => [...(dataViewItems ?? []), ...metadata.adHocDataViewList.map(toDataViewListItem)], [dataViewItems, metadata.adHocDataViewList] ); @@ -87,10 +89,16 @@ export const DataViewSelectPopover: React.FunctionComponent { - const ids = await dataViews.getIds(); - const dataViewsList = await Promise.all(ids.map((id) => dataViews.get(id))); - - setDataViewsItems(dataViewsList.map(toDataViewListItem)); + setLoadingDataViews(true); + try { + // Calling getIds with refresh = true to make sure we don't get stale data + const ids = await dataViews.getIds(true); + const dataViewsList = await Promise.all(ids.map((id) => dataViews.get(id))); + setDataViewsItems(dataViewsList.map(toDataViewListItem)); + } catch (e) { + // Error fetching data views + } + setLoadingDataViews(false); }, [dataViews]); const onAddAdHocDataView = useCallback( @@ -153,8 +161,10 @@ export const DataViewSelectPopover: React.FunctionComponent; } return (