Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { FormattedMessage } from '@kbn/i18n-react';
import type { TimeRange } from '@kbn/es-query';
import { useLinkProps } from '@kbn/observability-shared-plugin/public';
import { decodeOrThrow } from '@kbn/io-ts-utils';
import { useTimeRange } from '../../../../hooks/use_time_range';
import { ServicesAPIResponseRT } from '../../../../../common/http_api';
import { isPending, useFetcher } from '../../../../hooks/use_fetcher';
import { Section } from '../../components/section';
Expand Down Expand Up @@ -44,13 +45,18 @@ export const ServicesContent = ({
app: 'apm',
pathname: '/onboarding',
});

const parsedDateRange = useTimeRange({
rangeFrom: dateRange.from,
rangeTo: dateRange.to,
});

const params = useMemo(
() => ({
filters: { [HOST_NAME_FIELD]: hostName },
from: dateRange.from,
to: dateRange.to,
...parsedDateRange,
}),
[hostName, dateRange.from, dateRange.to]
[hostName, parsedDateRange]
);

const query = useMemo(() => ({ ...params, filters: JSON.stringify(params.filters) }), [params]);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { renderHook } from '@testing-library/react-hooks';
import { useTimeRange } from './use_time_range';
import * as datemath from '../utils/datemath';

jest.mock('../utils/datemath');

describe('useTimeRange', () => {
const mockParseDateRange = datemath.parseDateRange as jest.Mock;

beforeEach(() => {
Date.now = jest.fn(() => new Date(Date.UTC(2021, 0, 1, 12)).valueOf());
});

afterEach(() => {
jest.clearAllMocks();
});

it('returns default timestamps when rangeFrom and rangeTo are not provided', () => {
const { result } = renderHook(() => useTimeRange({}));

const now = Date.now();
const expectedFrom = new Date(now - 15 * 60000).toISOString();
const expectedTo = new Date(now).toISOString();

expect(result.current.from).toBe(expectedFrom);
expect(result.current.to).toBe(expectedTo);
});

it('returns parsed date range when rangeFrom and rangeTo are provided', () => {
const mockFrom = '2021-01-01T00:00:00.000Z';
const mockTo = '2021-01-01T01:00:00.000Z';
mockParseDateRange.mockReturnValue({ from: mockFrom, to: mockTo });

const { result } = renderHook(() => useTimeRange({ rangeFrom: 'now-15m', rangeTo: 'now' }));

expect(result.current.from).toBe(mockFrom);
expect(result.current.to).toBe(mockTo);
});

it('returns default timestamps when parseDateRange returns undefined values', () => {
mockParseDateRange.mockReturnValue({ from: undefined, to: undefined });

const { result } = renderHook(() => useTimeRange({ rangeFrom: 'now-15m', rangeTo: 'now' }));

const now = Date.now();
const expectedFrom = new Date(now - 15 * 60000).toISOString();
const expectedTo = new Date(now).toISOString();

expect(result.current.from).toBe(expectedFrom);
expect(result.current.to).toBe(expectedTo);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { useMemo } from 'react';
import { parseDateRange } from '../utils/datemath';

const DEFAULT_FROM_IN_MILLISECONDS = 15 * 60000;

const getDefaultTimestamps = () => {
const now = Date.now();

return {
from: new Date(now - DEFAULT_FROM_IN_MILLISECONDS).toISOString(),
to: new Date(now).toISOString(),
};
};

export const useTimeRange = ({ rangeFrom, rangeTo }: { rangeFrom?: string; rangeTo?: string }) => {
const parsedDateRange = useMemo(() => {
const defaults = getDefaultTimestamps();

if (!rangeFrom || !rangeTo) {
return defaults;
}

const { from = defaults.from, to = defaults.to } = parseDateRange({
from: rangeFrom,
to: rangeTo,
});

return { from, to };
}, [rangeFrom, rangeTo]);

return parsedDateRange;
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@
* 2.0.
*/
import createContainer from 'constate';
import { useCallback, useEffect, useMemo, useState } from 'react';
import { useCallback, useEffect, useState } from 'react';
import { buildEsQuery, Filter, fromKueryExpression, TimeRange, type Query } from '@kbn/es-query';
import { Subscription, map, tap } from 'rxjs';
import deepEqual from 'fast-deep-equal';
import useEffectOnce from 'react-use/lib/useEffectOnce';
import { useKibanaQuerySettings } from '@kbn/observability-shared-plugin/public';
import { useTimeRange } from '../../../../hooks/use_time_range';
import { useSearchSessionContext } from '../../../../hooks/use_search_session';
import { parseDateRange } from '../../../../utils/datemath';
import { useKibanaContextForPlugin } from '../../../../hooks/use_kibana';
import { telemetryTimeRangeFormatter } from '../../../../../common/formatters/telemetry_time_range';
import { useMetricsDataViewContext } from '../../../../containers/metrics_source';
Expand All @@ -38,17 +38,6 @@ const buildQuerySubmittedPayload = (
};
};

const DEFAULT_FROM_IN_MILLISECONDS = 15 * 60000;

const getDefaultTimestamps = () => {
const now = Date.now();

return {
from: new Date(now - DEFAULT_FROM_IN_MILLISECONDS).toISOString(),
to: new Date(now).toISOString(),
};
};

export const useUnifiedSearch = () => {
const [error, setError] = useState<Error | null>(null);
const [searchCriteria, setSearch] = useHostsUrlState();
Expand All @@ -57,6 +46,11 @@ export const useUnifiedSearch = () => {
const { services } = useKibanaContextForPlugin();
const kibanaQuerySettings = useKibanaQuerySettings();

const parsedDateRange = useTimeRange({
rangeFrom: searchCriteria.dateRange.from,
rangeTo: searchCriteria.dateRange.to,
});

const {
data: {
query: { filterManager: filterManagerService, queryString: queryStringService },
Expand Down Expand Up @@ -120,14 +114,6 @@ export const useUnifiedSearch = () => {
[onDateRangeChange, updateSearchSessionId]
);

const parsedDateRange = useMemo(() => {
const defaults = getDefaultTimestamps();

const { from = defaults.from, to = defaults.to } = parseDateRange(searchCriteria.dateRange);

return { from, to };
}, [searchCriteria.dateRange]);

const getDateRangeAsTimestamp = useCallback(() => {
const from = new Date(parsedDateRange.from).getTime();
const to = new Date(parsedDateRange.to).getTime();
Expand Down