diff --git a/components/webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx b/components/webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx index b67283fcfc..4e810c4982 100644 --- a/components/webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx +++ b/components/webui/client/src/pages/SearchPage/SearchQueryStatus/Results.tsx @@ -19,16 +19,19 @@ type TextTypes = GetProps["type"]; * @return */ const Results = () => { + const numSearchResultsMetadata = useSearchStore((state) => state.numSearchResultsMetadata); const numSearchResultsTimeline = useSearchStore((state) => state.numSearchResultsTimeline); const numSearchResultsTable = useSearchStore((state) => state.numSearchResultsTable); const searchUiState = useSearchStore((state) => state.searchUiState); - // Number of results is the maximum of the number of results in the timeline and table. The - // timeline may have more results since the table results are capped. Having two sources may - // provide more timely updates to the user. + // Number of results is the maximum from timeline, table, and server metadata sources. + // Multiple sources provide more timely updates. Source behavior differs by query engine: + // - clp/clp-s: table and server metadata counts are capped + // - presto: table count is capped, no timeline count available const numResults = useMemo( - () => Math.max(numSearchResultsTimeline, numSearchResultsTable), + () => Math.max(numSearchResultsMetadata, numSearchResultsTimeline, numSearchResultsTable), [ + numSearchResultsMetadata, numSearchResultsTimeline, numSearchResultsTable, ] diff --git a/components/webui/client/src/pages/SearchPage/SearchQueryStatus/index.tsx b/components/webui/client/src/pages/SearchPage/SearchQueryStatus/index.tsx index ee152f39fc..f65bb13f43 100644 --- a/components/webui/client/src/pages/SearchPage/SearchQueryStatus/index.tsx +++ b/components/webui/client/src/pages/SearchPage/SearchQueryStatus/index.tsx @@ -24,7 +24,8 @@ const SearchQueryStatus = () => { {(searchUiState === SEARCH_UI_STATE.QUERYING || searchUiState === SEARCH_UI_STATE.DONE) && ( - Search job # + Search job + {" "} {searchJobId} {" "} found diff --git a/components/webui/client/src/pages/SearchPage/SearchState/index.tsx b/components/webui/client/src/pages/SearchPage/SearchState/index.tsx index 8189bcced0..8fc97841bf 100644 --- a/components/webui/client/src/pages/SearchPage/SearchState/index.tsx +++ b/components/webui/client/src/pages/SearchPage/SearchState/index.tsx @@ -18,6 +18,7 @@ import {SEARCH_UI_STATE} from "./typings"; const SEARCH_STATE_DEFAULT = Object.freeze({ aggregationJobId: null, cachedDataset: null, + numSearchResultsMetadata: 0, numSearchResultsTable: 0, numSearchResultsTimeline: 0, queryIsCaseSensitive: false, @@ -43,6 +44,11 @@ interface SearchState { */ cachedDataset: Nullable; + /** + * The number of search results from server metadata. + */ + numSearchResultsMetadata: number; + /** * The number of search table results. */ @@ -97,6 +103,7 @@ interface SearchState { updateAggregationJobId: (id: string | null) => void; updateCachedDataset: (dataset: string) => void; + updateNumSearchResultsMetadata: (num: number) => void; updateNumSearchResultsTable: (num: number) => void; updateNumSearchResultsTimeline: (num: number) => void; updateQueryIsCaseSensitive: (newValue: boolean) => void; @@ -117,6 +124,9 @@ const useSearchStore = create((set) => ({ updateCachedDataset: (dataset) => { set({cachedDataset: dataset}); }, + updateNumSearchResultsMetadata: (num) => { + set({numSearchResultsMetadata: num}); + }, updateNumSearchResultsTable: (num) => { set({numSearchResultsTable: num}); }, diff --git a/components/webui/client/src/pages/SearchPage/SearchState/useUpdateStateWithMetadata.ts b/components/webui/client/src/pages/SearchPage/SearchState/useUpdateStateWithMetadata.ts index d1d5652b83..9ad49de8ec 100644 --- a/components/webui/client/src/pages/SearchPage/SearchState/useUpdateStateWithMetadata.ts +++ b/components/webui/client/src/pages/SearchPage/SearchState/useUpdateStateWithMetadata.ts @@ -17,18 +17,25 @@ import {useResultsMetadata} from "./useResultsMetadata"; const PRESTO_CANCEL_ERROR_NAME = "USER_CANCELED"; /** - * Custom hook to update the UI state to `DONE` when the results metadata signal indicates - * that the query is complete, or `FAILED` if the query fails. If there is an error, it will - * also display a notification with the error message. + * Custom hook to update the client state based on results metadata from the server. + * - Sets the UI state to `DONE` when the results metadata signal indicates that the query is + * complete, or `FAILED` if the query fails. If there is an error, it will display a notification + * with the error message. + * - Updates the number of search results from the metadata. */ -const useUiUpdateOnDoneSignal = () => { - const {updateSearchUiState} = useSearchStore(); +const useUpdateStateWithMetadata = () => { + const {updateSearchUiState, updateNumSearchResultsMetadata} = useSearchStore(); const resultsMetadata = useResultsMetadata(); + useEffect(() => { if (null === resultsMetadata) { return; } + if ("undefined" !== typeof resultsMetadata.numTotalResults) { + updateNumSearchResultsMetadata(resultsMetadata.numTotalResults); + } + switch (resultsMetadata.lastSignal) { case SEARCH_SIGNAL.RESP_DONE: case PRESTO_SEARCH_SIGNAL.FINISHED: @@ -59,7 +66,8 @@ const useUiUpdateOnDoneSignal = () => { }, [ resultsMetadata, updateSearchUiState, + updateNumSearchResultsMetadata, ]); }; -export {useUiUpdateOnDoneSignal}; +export {useUpdateStateWithMetadata}; diff --git a/components/webui/client/src/pages/SearchPage/index.tsx b/components/webui/client/src/pages/SearchPage/index.tsx index d49a358801..ef78f1a068 100644 --- a/components/webui/client/src/pages/SearchPage/index.tsx +++ b/components/webui/client/src/pages/SearchPage/index.tsx @@ -8,7 +8,7 @@ import SearchControls from "./SearchControls"; import SearchQueryStatus from "./SearchQueryStatus"; import SearchResultsTable from "./SearchResults/SearchResultsTable"; import SearchResultsTimeline from "./SearchResults/SearchResultsTimeline"; -import {useUiUpdateOnDoneSignal} from "./SearchState/useUpdateStateWithMetadata"; +import {useUpdateStateWithMetadata} from "./SearchState/useUpdateStateWithMetadata"; /** @@ -17,7 +17,7 @@ import {useUiUpdateOnDoneSignal} from "./SearchState/useUpdateStateWithMetadata" * @return */ const SearchPage = () => { - useUiUpdateOnDoneSignal(); + useUpdateStateWithMetadata(); return ( <>