diff --git a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx index 18996a7cdf9ca..77abd46333c68 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_documents.tsx @@ -46,7 +46,6 @@ import useObservable from 'react-use/lib/useObservable'; import type { DocViewFilterFn } from '@kbn/unified-doc-viewer/types'; import { DiscoverGridSettings } from '@kbn/saved-search-plugin/common'; import { useQuerySubscriber } from '@kbn/unified-field-list'; -import { map } from 'rxjs'; import { DiscoverGrid } from '../../../../components/discover_grid'; import { getDefaultRowsPerPage } from '../../../../../common/constants'; import { useInternalStateSelector } from '../../state_management/discover_internal_state_container'; @@ -110,6 +109,7 @@ function DiscoverDocumentsComponent({ }) { const services = useDiscoverServices(); const documents$ = stateContainer.dataState.data$.documents$; + const main$ = stateContainer.dataState.data$.main$; const savedSearch = useSavedSearchInitial(); const { dataViews, capabilities, uiSettings, uiActions, ebtManager, fieldsMetadata } = services; const [ @@ -272,17 +272,12 @@ function DiscoverDocumentsComponent({ const { filters } = useQuerySubscriber({ data: services.data }); - const timeRange = useObservable( - services.timefilter.getTimeUpdate$().pipe(map(() => services.timefilter.getTime())), - services.timefilter.getTime() - ); - const cellActionsMetadata = useAdditionalCellActions({ dataSource, dataView, query, filters, - timeRange, + timeRange: main$.getValue().timeRange, }); const renderDocumentView = useCallback( diff --git a/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx b/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx index 9aec3589c753e..7107046d73ef1 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_histogram_layout.test.tsx @@ -65,12 +65,6 @@ const mountComponent = async ({ const dataView = savedSearch?.searchSource?.getField('index') as DataView; let services = discoverServiceMock; - services.data.query.timefilter.timefilter.getAbsoluteTime = () => { - return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }; - }; - services.data.query.timefilter.timefilter.getTime = () => { - return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }; - }; (services.data.query.queryString.getDefaultQuery as jest.Mock).mockReturnValue({ language: 'kuery', query: '', @@ -86,6 +80,8 @@ const mountComponent = async ({ const main$ = new BehaviorSubject({ fetchStatus: FetchStatus.COMPLETE, foundDocuments: true, + timeRange: { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }, + timeRangeRelative: { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }, }) as DataMain$; const documents$ = new BehaviorSubject({ diff --git a/src/plugins/discover/public/application/main/components/layout/discover_layout.test.tsx b/src/plugins/discover/public/application/main/components/layout/discover_layout.test.tsx index 13a8e2c9c402a..d23a28aa7752d 100644 --- a/src/plugins/discover/public/application/main/components/layout/discover_layout.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/discover_layout.test.tsx @@ -53,12 +53,14 @@ async function mountComponent( main$: DataMain$ = new BehaviorSubject({ fetchStatus: FetchStatus.COMPLETE, foundDocuments: true, + timeRange: { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }, + timeRangeRelative: { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }, }) as DataMain$ ) { const searchSourceMock = createSearchSourceMock({ index: dataView }); const services = createDiscoverServicesMock(); const time = { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }; - services.data.query.timefilter.timefilter.getTime = () => time; + (services.data.query.queryString.getDefaultQuery as jest.Mock).mockReturnValue({ language: 'kuery', query: '', diff --git a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.test.tsx b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.test.tsx index c8f829d442444..3134bf67ef12c 100644 --- a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.test.tsx +++ b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.test.tsx @@ -24,7 +24,11 @@ import { UnifiedHistogramState, } from '@kbn/unified-histogram-plugin/public'; import { createMockUnifiedHistogramApi } from '@kbn/unified-histogram-plugin/public/mocks'; -import { checkHitCount, sendErrorTo } from '../../hooks/use_saved_search_messages'; +import { + checkHitCount, + sendErrorTo, + sendFetchStartMsg, +} from '../../hooks/use_saved_search_messages'; import type { InspectorAdapters } from '../../hooks/use_inspector'; import { UnifiedHistogramCustomization } from '../../../../customizations/customization_types/histogram_customization'; import { useDiscoverCustomization } from '../../../../customizations'; @@ -379,6 +383,23 @@ describe('useDiscoverHistogram', () => { }); expect(hook.result.current.isChartLoading).toBe(true); }); + + it('should use timerange + timeRangeRelative + query given by the data main$ observable', async () => { + const fetch$ = new Subject(); + const stateContainer = getStateContainer(); + const timeRange = { from: '2021-05-01T20:00:00Z', to: '2021-05-02T20:00:00Z' }; + const timeRangeRelative = { from: 'now-15m', to: 'now' }; + const query = { esql: 'test' }; + sendFetchStartMsg(stateContainer.dataState.data$.main$, timeRange, timeRangeRelative, query); + + const { hook } = await renderUseDiscoverHistogram({ stateContainer }); + act(() => { + fetch$.next(); + }); + expect(hook.result.current.timeRange).toBe(timeRange); + expect(hook.result.current.relativeTimeRange).toBe(timeRangeRelative); + expect(hook.result.current.query).toBe(query); + }); }); describe('refetching', () => { diff --git a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts index 3f2acf0ce933b..91ed4b68847db 100644 --- a/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts +++ b/src/plugins/discover/public/application/main/components/layout/use_discover_histogram.ts @@ -216,14 +216,9 @@ export const useDiscoverHistogram = ({ /** * Request params */ - const { query, filters } = useQuerySubscriber({ data: services.data }); + const { filters } = useQuerySubscriber({ data: services.data }); const customFilters = useInternalStateSelector((state) => state.customFilters); - const timefilter = services.data.query.timefilter.timefilter; - const timeRange = timefilter.getAbsoluteTime(); - const relativeTimeRange = useObservable( - timefilter.getTimeUpdate$().pipe(map(() => timefilter.getTime())), - timefilter.getTime() - ); + const { timeRangeRelative, timeRange, query } = useObservable(main$, main$.getValue()); // When in ES|QL mode, update the data view, query, and // columns only when documents are done fetching so the Lens suggestions @@ -337,9 +332,6 @@ export const useDiscoverHistogram = ({ return allFilters.length ? allFilters : EMPTY_FILTERS; }, [filters, customFilters]); - // eslint-disable-next-line react-hooks/exhaustive-deps - const timeRangeMemoized = useMemo(() => timeRange, [timeRange?.from, timeRange?.to]); - const onVisContextChanged = useCallback( ( nextVisContext: UnifiedHistogramVisContext | undefined, @@ -399,8 +391,8 @@ export const useDiscoverHistogram = ({ dataView: isEsqlMode ? esqlDataView : dataView, query: isEsqlMode ? esqlQuery : query, filters: filtersMemoized, - timeRange: timeRangeMemoized, - relativeTimeRange, + timeRange, + relativeTimeRange: timeRangeRelative, columns: isEsqlMode ? esqlColumns : undefined, onFilter: histogramCustomization?.onFilter, onBrushEnd: histogramCustomization?.onBrushEnd, diff --git a/src/plugins/discover/public/application/main/data_fetching/fetch_all.ts b/src/plugins/discover/public/application/main/data_fetching/fetch_all.ts index f8552411c0add..5d87ccdff73b9 100644 --- a/src/plugins/discover/public/application/main/data_fetching/fetch_all.ts +++ b/src/plugins/discover/public/application/main/data_fetching/fetch_all.ts @@ -97,6 +97,7 @@ export function fetchAll( services, sort: getAppState().sort as SortOrder[], customFilters: getInternalState().customFilters, + inputTimeRange: dataSubjects.main$.getValue().timeRange, }); } @@ -117,6 +118,7 @@ export function fetchAll( data, expressions, profilesManager, + inputTimeRange: dataSubjects.main$.getValue().timeRange, }) : fetchDocuments(searchSource, fetchDeps); const fetchType = isEsqlQuery ? 'fetchTextBased' : 'fetchDocuments'; @@ -245,6 +247,7 @@ export async function fetchMoreDocuments( services, sort: getAppState().sort as SortOrder[], customFilters: getInternalState().customFilters, + inputTimeRange: dataSubjects.main$.getValue().timeRange, }); // Fetch more documents diff --git a/src/plugins/discover/public/application/main/data_fetching/fetch_esql.ts b/src/plugins/discover/public/application/main/data_fetching/fetch_esql.ts index dca01247296a4..ad681bd969fe4 100644 --- a/src/plugins/discover/public/application/main/data_fetching/fetch_esql.ts +++ b/src/plugins/discover/public/application/main/data_fetching/fetch_esql.ts @@ -51,7 +51,7 @@ export function fetchEsql({ expressions: ExpressionsStart; profilesManager: ProfilesManager; }): Promise { - const timeRange = inputTimeRange ?? data.query.timefilter.timefilter.getTime(); + const timeRange = inputTimeRange ?? data.query.timefilter.timefilter.getAbsoluteTime(); return textBasedQueryStateToAstWithValidation({ filters, query, diff --git a/src/plugins/discover/public/application/main/data_fetching/update_search_source.ts b/src/plugins/discover/public/application/main/data_fetching/update_search_source.ts index ad79e93ec37e4..05ba512d0e716 100644 --- a/src/plugins/discover/public/application/main/data_fetching/update_search_source.ts +++ b/src/plugins/discover/public/application/main/data_fetching/update_search_source.ts @@ -7,9 +7,9 @@ * License v3.0 only", or the "Server Side Public License, v 1". */ -import { ISearchSource } from '@kbn/data-plugin/public'; -import { DataViewType, DataView } from '@kbn/data-views-plugin/public'; -import { Filter } from '@kbn/es-query'; +import type { ISearchSource } from '@kbn/data-plugin/public'; +import { DataViewType, type DataView } from '@kbn/data-views-plugin/public'; +import type { Filter, TimeRange } from '@kbn/es-query'; import type { SortOrder } from '@kbn/saved-search-plugin/public'; import { SORT_DEFAULT_ORDER_SETTING } from '@kbn/discover-utils'; import { DiscoverServices } from '../../../build_services'; @@ -25,11 +25,13 @@ export function updateVolatileSearchSource( services, sort, customFilters, + inputTimeRange, }: { dataView: DataView; services: DiscoverServices; sort?: SortOrder[]; customFilters: Filter[]; + inputTimeRange?: TimeRange; } ) { const { uiSettings, data } = services; @@ -48,7 +50,7 @@ export function updateVolatileSearchSource( if (dataView.type !== DataViewType.ROLLUP) { // Set the date range filter fields from timeFilter using the absolute format. Search sessions requires that it be converted from a relative range - const timeFilter = data.query.timefilter.timefilter.createFilter(dataView); + const timeFilter = data.query.timefilter.timefilter.createFilter(dataView, inputTimeRange); filters = timeFilter ? [...filters, timeFilter] : filters; } diff --git a/src/plugins/discover/public/application/main/hooks/use_saved_search_messages.test.ts b/src/plugins/discover/public/application/main/hooks/use_saved_search_messages.test.ts index 38f9209d10437..67c6dca4bcac9 100644 --- a/src/plugins/discover/public/application/main/hooks/use_saved_search_messages.test.ts +++ b/src/plugins/discover/public/application/main/hooks/use_saved_search_messages.test.ts @@ -17,6 +17,7 @@ import { sendLoadingMoreFinishedMsg, sendNoResultsFoundMsg, sendPartialMsg, + sendFetchStartMsg, } from './use_saved_search_messages'; import { FetchStatus } from '../../types'; import { BehaviorSubject } from 'rxjs'; @@ -188,4 +189,23 @@ describe('test useSavedSearch message generators', () => { }); checkHitCount(main$, 0); }); + + test('sendFetchStartMsg', (done) => { + const main$ = new BehaviorSubject({ + fetchStatus: FetchStatus.COMPLETE, + }); + const timeRange = { from: 'fromAbs', to: 'toAbs' }; + const timeRangeRelative = { from: 'fromRel', to: 'toRel' }; + const query = { query: 'query', language: 'test' }; + main$.subscribe((value) => { + if (value.fetchStatus === FetchStatus.LOADING) { + expect(value.fetchStatus).toBe(FetchStatus.LOADING); + expect(value.timeRange).toBe(timeRange); + expect(value.timeRangeRelative).toBe(timeRangeRelative); + expect(value.query).toBe(query); + done(); + } + }); + sendFetchStartMsg(main$, timeRange, timeRangeRelative, query); + }); }); diff --git a/src/plugins/discover/public/application/main/hooks/use_saved_search_messages.ts b/src/plugins/discover/public/application/main/hooks/use_saved_search_messages.ts index dbe7da63f5e76..0ea684107600d 100644 --- a/src/plugins/discover/public/application/main/hooks/use_saved_search_messages.ts +++ b/src/plugins/discover/public/application/main/hooks/use_saved_search_messages.ts @@ -10,6 +10,7 @@ import type { BehaviorSubject } from 'rxjs'; import type { DataTableRecord } from '@kbn/discover-utils/src/types'; import type { SearchResponseWarning } from '@kbn/search-response-warnings'; +import { AggregateQuery, Query, TimeRange } from '@kbn/es-query'; import { FetchStatus } from '../../types'; import type { DataDocuments$, @@ -37,7 +38,29 @@ export function sendCompleteMsg(main$: DataMain$, foundDocuments = true) { if (main$.getValue().fetchStatus === FetchStatus.COMPLETE) { return; } - main$.next({ fetchStatus: FetchStatus.COMPLETE, foundDocuments, error: undefined }); + main$.next({ + ...main$.getValue(), + fetchStatus: FetchStatus.COMPLETE, + foundDocuments, + error: undefined, + }); +} + +/** + * Send message when data fetching starts via main observable + */ +export function sendFetchStartMsg( + main$: DataMain$, + timeRange: TimeRange, + timeRangeRelative: TimeRange, + query: AggregateQuery | Query | undefined +) { + main$.next({ + ...main$.getValue(), + timeRange, + timeRangeRelative, + query, + }); } /** @@ -45,7 +68,7 @@ export function sendCompleteMsg(main$: DataMain$, foundDocuments = true) { */ export function sendPartialMsg(main$: DataMain$) { if (main$.getValue().fetchStatus === FetchStatus.LOADING) { - main$.next({ fetchStatus: FetchStatus.PARTIAL }); + main$.next({ ...main$.getValue(), fetchStatus: FetchStatus.PARTIAL }); } } @@ -57,7 +80,7 @@ export function sendLoadingMsg( props?: Omit ) { if (data$.getValue().fetchStatus !== FetchStatus.LOADING) { - data$.next({ ...props, fetchStatus: FetchStatus.LOADING } as T); + data$.next({ ...data$.getValue(), ...props, fetchStatus: FetchStatus.LOADING } as T); } } diff --git a/src/plugins/discover/public/application/main/state_management/discover_data_state_container.ts b/src/plugins/discover/public/application/main/state_management/discover_data_state_container.ts index 59220d7def3c1..04d9902321a04 100644 --- a/src/plugins/discover/public/application/main/state_management/discover_data_state_container.ts +++ b/src/plugins/discover/public/application/main/state_management/discover_data_state_container.ts @@ -12,7 +12,7 @@ import type { AutoRefreshDoneFn } from '@kbn/data-plugin/public'; import type { DatatableColumn } from '@kbn/expressions-plugin/common'; import { RequestAdapter } from '@kbn/inspector-plugin/common'; import type { SavedSearch } from '@kbn/saved-search-plugin/public'; -import { AggregateQuery, isOfAggregateQueryType, Query } from '@kbn/es-query'; +import { AggregateQuery, isOfAggregateQueryType, Query, TimeRange } from '@kbn/es-query'; import type { SearchResponse } from '@elastic/elasticsearch/lib/api/types'; import type { DataView } from '@kbn/data-views-plugin/common'; import { reportPerformanceMetricEvent } from '@kbn/ebt-tools'; @@ -26,7 +26,7 @@ import type { DiscoverSearchSessionManager } from './discover_search_session'; import { FetchStatus } from '../../types'; import { validateTimeRange } from './utils/validate_time_range'; import { fetchAll, fetchMoreDocuments } from '../data_fetching/fetch_all'; -import { sendResetMsg } from '../hooks/use_saved_search_messages'; +import { sendResetMsg, sendFetchStartMsg } from '../hooks/use_saved_search_messages'; import { getFetch$ } from '../data_fetching/get_fetch_observable'; import type { DiscoverInternalStateContainer } from './discover_internal_state_container'; import { getDefaultProfileState } from './utils/get_default_profile_state'; @@ -53,6 +53,8 @@ export interface DataMsg { export interface DataMainMsg extends DataMsg { foundDocuments?: boolean; + timeRange?: TimeRange; + timeRangeRelative?: TimeRange; } export interface DataDocumentsMsg extends DataMsg { @@ -235,6 +237,12 @@ export function getDataStateContainer({ abortController?.abort(); abortControllerFetchMore?.abort(); + sendFetchStartMsg( + dataSubjects.main$, + timefilter.getAbsoluteTime(), + timefilter.getTime(), + appStateContainer.getState().query + ); if (options.fetchMore) { abortControllerFetchMore = new AbortController(); diff --git a/src/plugins/unified_histogram/public/hooks/use_request_params.tsx b/src/plugins/unified_histogram/public/hooks/use_request_params.tsx index 7edd134afaeee..6eee29657052a 100644 --- a/src/plugins/unified_histogram/public/hooks/use_request_params.tsx +++ b/src/plugins/unified_histogram/public/hooks/use_request_params.tsx @@ -26,11 +26,13 @@ export const useRequestParams = ({ query: originalQuery, filters: originalFilters, timeRange: originalTimeRange, + relativeTimeRange: originalRelativeTimeRange, }: { services: UnifiedHistogramServices; query?: Query | AggregateQuery; filters?: Filter[]; timeRange?: TimeRange; + relativeTimeRange?: TimeRange; }): UseRequestParamsResult => { const { data } = services; @@ -42,14 +44,15 @@ export const useRequestParams = ({ ); const relativeTimeRange = useMemo( - () => originalTimeRange ?? data.query.timefilter.timefilter.getTimeDefaults(), - [data.query.timefilter.timefilter, originalTimeRange] + () => originalRelativeTimeRange ?? data.query.timefilter.timefilter.getTimeDefaults(), + [data.query.timefilter.timefilter, originalRelativeTimeRange] ); - const timeRange = useRef(getAbsoluteTimeRange(relativeTimeRange)); + const timeRange = useRef(originalTimeRange ?? getAbsoluteTimeRange(relativeTimeRange)); + const getTimeRange = useCallback(() => timeRange.current, []); const updateTimeRange = useStableCallback(() => { - timeRange.current = getAbsoluteTimeRange(relativeTimeRange); + timeRange.current = originalTimeRange ?? getAbsoluteTimeRange(relativeTimeRange); }); return { filters, query, getTimeRange, updateTimeRange, relativeTimeRange }; diff --git a/src/plugins/unified_histogram/public/layout/layout.tsx b/src/plugins/unified_histogram/public/layout/layout.tsx index b9d9f6fbc446f..7098958f37d54 100644 --- a/src/plugins/unified_histogram/public/layout/layout.tsx +++ b/src/plugins/unified_histogram/public/layout/layout.tsx @@ -255,6 +255,7 @@ export const UnifiedHistogramLayout = ({ query: originalQuery, filters: originalFilters, timeRange: originalTimeRange, + relativeTimeRange, }); const [lensVisService] = useState(() => new LensVisService({ services, lensSuggestionsApi }));