diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.gettime.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.gettime.md new file mode 100644 index 00000000000000..54e7cf92f500cf --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.gettime.md @@ -0,0 +1,27 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [getTime](./kibana-plugin-plugins-data-server.gettime.md) + +## getTime() function + +Signature: + +```typescript +export declare function getTime(indexPattern: IIndexPattern | undefined, timeRange: TimeRange, options?: { + forceNow?: Date; + fieldName?: string; +}): import("../..").RangeFilter | undefined; +``` + +## Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| indexPattern | IIndexPattern | undefined | | +| timeRange | TimeRange | | +| options | {
forceNow?: Date;
fieldName?: string;
} | | + +Returns: + +`import("../..").RangeFilter | undefined` + diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md index f492ba2843a697..c80112fb17dde5 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md @@ -23,6 +23,7 @@ | Function | Description | | --- | --- | | [getDefaultSearchParams(config)](./kibana-plugin-plugins-data-server.getdefaultsearchparams.md) | | +| [getTime(indexPattern, timeRange, options)](./kibana-plugin-plugins-data-server.gettime.md) | | | [parseInterval(interval)](./kibana-plugin-plugins-data-server.parseinterval.md) | | | [plugin(initializerContext)](./kibana-plugin-plugins-data-server.plugin.md) | Static code to be shared externally | | [shouldReadFieldFromDocValues(aggregatable, esType)](./kibana-plugin-plugins-data-server.shouldreadfieldfromdocvalues.md) | | diff --git a/src/plugins/data/common/index.ts b/src/plugins/data/common/index.ts index b40e02b709d301..0fb45fcc739d45 100644 --- a/src/plugins/data/common/index.ts +++ b/src/plugins/data/common/index.ts @@ -26,6 +26,5 @@ export * from './kbn_field_types'; export * from './query'; export * from './search'; export * from './search/aggs'; -export * from './timefilter'; export * from './types'; export * from './utils'; diff --git a/src/plugins/data/common/query/index.ts b/src/plugins/data/common/query/index.ts index 4e90f6f8bb83ec..b0dfbbb82355e0 100644 --- a/src/plugins/data/common/query/index.ts +++ b/src/plugins/data/common/query/index.ts @@ -18,5 +18,6 @@ */ export * from './filter_manager'; +export * from './timefilter'; export * from './types'; export * from './is_query'; diff --git a/src/plugins/data/public/query/timefilter/get_time.test.ts b/src/plugins/data/common/query/timefilter/get_time.test.ts similarity index 100% rename from src/plugins/data/public/query/timefilter/get_time.test.ts rename to src/plugins/data/common/query/timefilter/get_time.test.ts diff --git a/src/plugins/data/public/query/timefilter/get_time.ts b/src/plugins/data/common/query/timefilter/get_time.ts similarity index 90% rename from src/plugins/data/public/query/timefilter/get_time.ts rename to src/plugins/data/common/query/timefilter/get_time.ts index 3706972ce4a2ef..6e4eda95accc73 100644 --- a/src/plugins/data/public/query/timefilter/get_time.ts +++ b/src/plugins/data/common/query/timefilter/get_time.ts @@ -18,14 +18,16 @@ */ import dateMath from '@elastic/datemath'; -import { IIndexPattern } from '../..'; -import { TimeRange, buildRangeFilter } from '../../../common'; +import { buildRangeFilter, IIndexPattern, TimeRange, TimeRangeBounds } from '../..'; interface CalculateBoundsOptions { forceNow?: Date; } -export function calculateBounds(timeRange: TimeRange, options: CalculateBoundsOptions = {}) { +export function calculateBounds( + timeRange: TimeRange, + options: CalculateBoundsOptions = {} +): TimeRangeBounds { return { min: dateMath.parse(timeRange.from, { forceNow: options.forceNow }), max: dateMath.parse(timeRange.to, { roundUp: true, forceNow: options.forceNow }), diff --git a/src/plugins/data/common/timefilter/index.ts b/src/plugins/data/common/query/timefilter/index.ts similarity index 92% rename from src/plugins/data/common/timefilter/index.ts rename to src/plugins/data/common/query/timefilter/index.ts index e0c509e119fda1..55739511a0ef54 100644 --- a/src/plugins/data/common/timefilter/index.ts +++ b/src/plugins/data/common/query/timefilter/index.ts @@ -17,4 +17,5 @@ * under the License. */ -export { isTimeRange } from './is_time_range'; +export * from './get_time'; +export * from './is_time_range'; diff --git a/src/plugins/data/common/timefilter/is_time_range.ts b/src/plugins/data/common/query/timefilter/is_time_range.ts similarity index 100% rename from src/plugins/data/common/timefilter/is_time_range.ts rename to src/plugins/data/common/query/timefilter/is_time_range.ts diff --git a/src/plugins/data/common/timefilter/types.ts b/src/plugins/data/common/query/timefilter/types.ts similarity index 88% rename from src/plugins/data/common/timefilter/types.ts rename to src/plugins/data/common/query/timefilter/types.ts index b197b16e67dd11..60008ce6054e1b 100644 --- a/src/plugins/data/common/timefilter/types.ts +++ b/src/plugins/data/common/query/timefilter/types.ts @@ -17,6 +17,8 @@ * under the License. */ +import { Moment } from 'moment'; + export interface RefreshInterval { pause: boolean; value: number; @@ -27,3 +29,8 @@ export interface TimeRange { to: string; mode?: 'absolute' | 'relative'; } + +export interface TimeRangeBounds { + min: Moment | undefined; + max: Moment | undefined; +} diff --git a/src/plugins/data/common/query/types.ts b/src/plugins/data/common/query/types.ts index 61b5d5b2b7b4ad..6b34a1baf293bc 100644 --- a/src/plugins/data/common/query/types.ts +++ b/src/plugins/data/common/query/types.ts @@ -17,6 +17,8 @@ * under the License. */ +export * from './timefilter/types'; + export interface Query { query: string | { [key: string]: any }; language: string; diff --git a/src/plugins/data/common/types.ts b/src/plugins/data/common/types.ts index 93629c3dbaf626..e2ec1a031b0ca7 100644 --- a/src/plugins/data/common/types.ts +++ b/src/plugins/data/common/types.ts @@ -17,7 +17,6 @@ * under the License. */ -export * from './timefilter/types'; export * from './query/types'; export * from './kbn_field_types/types'; export * from './index_patterns/types'; diff --git a/src/plugins/data/public/index.ts b/src/plugins/data/public/index.ts index 030d462141b09e..2f4978da1ebd8d 100644 --- a/src/plugins/data/public/index.ts +++ b/src/plugins/data/public/index.ts @@ -420,7 +420,6 @@ export { connectToQueryState, syncQueryStateWithUrl, QueryState, - getTime, getQueryLog, getDefaultQuery, FilterManager, @@ -434,6 +433,7 @@ export { } from './query'; export { + getTime, // kbn field types castEsToKbnFieldTypeName, getKbnTypeNames, diff --git a/src/plugins/data/public/plugin.ts b/src/plugins/data/public/plugin.ts index c3c3d4cb9f4d99..c53fd2d36898c0 100644 --- a/src/plugins/data/public/plugin.ts +++ b/src/plugins/data/public/plugin.ts @@ -150,7 +150,6 @@ export class DataPublicPlugin implements Plugin { - const forceNow = parseQueryString().forceNow as string; - if (!forceNow) { - return; - } - - const ticks = Date.parse(forceNow); - if (isNaN(ticks)) { - throw new Error(`forceNow query parameter, ${forceNow}, can't be parsed by Date.parse`); - } - return new Date(ticks); + return getForceNow(); }; } diff --git a/src/plugins/data/public/query/timefilter/types.ts b/src/plugins/data/public/query/timefilter/types.ts index 8b8deea43f808e..d47a9cbb3bd609 100644 --- a/src/plugins/data/public/query/timefilter/types.ts +++ b/src/plugins/data/public/query/timefilter/types.ts @@ -16,7 +16,9 @@ * specific language governing permissions and limitations * under the License. */ + import { Moment } from 'moment'; + import { TimeRange, RefreshInterval } from '../../../common'; export interface TimefilterConfig { @@ -32,7 +34,4 @@ export type InputTimeRange = to: Moment; }; -export interface TimeRangeBounds { - min: Moment | undefined; - max: Moment | undefined; -} +export { TimeRangeBounds } from '../../../common'; diff --git a/src/plugins/data/public/search/aggs/agg_types.ts b/src/plugins/data/public/search/aggs/agg_types.ts index 2af29d36002460..68542b66e6c358 100644 --- a/src/plugins/data/public/search/aggs/agg_types.ts +++ b/src/plugins/data/public/search/aggs/agg_types.ts @@ -18,7 +18,8 @@ */ import { IUiSettingsClient } from 'src/core/public'; -import { QuerySetup } from '../../query/query_service'; +import { TimeRange, TimeRangeBounds } from '../../../common'; +import { GetInternalStartServicesFn } from '../../types'; import { getCountMetricAgg } from './metrics/count'; import { getAvgMetricAgg } from './metrics/avg'; @@ -54,18 +55,16 @@ import { getBucketAvgMetricAgg } from './metrics/bucket_avg'; import { getBucketMinMetricAgg } from './metrics/bucket_min'; import { getBucketMaxMetricAgg } from './metrics/bucket_max'; -import { GetInternalStartServicesFn } from '../../types'; - export interface AggTypesDependencies { - uiSettings: IUiSettingsClient; - query: QuerySetup; + calculateBounds: (timeRange: TimeRange) => TimeRangeBounds; getInternalStartServices: GetInternalStartServicesFn; + uiSettings: IUiSettingsClient; } export const getAggTypes = ({ - uiSettings, - query, + calculateBounds, getInternalStartServices, + uiSettings, }: AggTypesDependencies) => ({ metrics: [ getCountMetricAgg({ getInternalStartServices }), @@ -91,7 +90,7 @@ export const getAggTypes = ({ getGeoCentroidMetricAgg({ getInternalStartServices }), ], buckets: [ - getDateHistogramBucketAgg({ uiSettings, query, getInternalStartServices }), + getDateHistogramBucketAgg({ calculateBounds, uiSettings, getInternalStartServices }), getHistogramBucketAgg({ uiSettings, getInternalStartServices }), getRangeBucketAgg({ getInternalStartServices }), getDateRangeBucketAgg({ uiSettings, getInternalStartServices }), diff --git a/src/plugins/data/public/search/aggs/buckets/create_filter/date_histogram.test.ts b/src/plugins/data/public/search/aggs/buckets/create_filter/date_histogram.test.ts index bcdc003707e752..518bdbfe0c1352 100644 --- a/src/plugins/data/public/search/aggs/buckets/create_filter/date_histogram.test.ts +++ b/src/plugins/data/public/search/aggs/buckets/create_filter/date_histogram.test.ts @@ -30,7 +30,6 @@ import { import { BUCKET_TYPES } from '../bucket_agg_types'; import { RangeFilter } from '../../../../../common'; import { coreMock, notificationServiceMock } from '../../../../../../../core/public/mocks'; -import { queryServiceMock } from '../../../../query/mocks'; import { fieldFormatsServiceMock } from '../../../../field_formats/mocks'; import { InternalStartServices } from '../../../../types'; @@ -46,13 +45,13 @@ describe('AggConfig Filters', () => { const { uiSettings } = coreMock.createSetup(); aggTypesDependencies = { - uiSettings, - query: queryServiceMock.createSetupContract(), + calculateBounds: jest.fn(), getInternalStartServices: () => (({ fieldFormats: fieldFormatsServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(), } as unknown) as InternalStartServices), + uiSettings, }; mockDataServices(); diff --git a/src/plugins/data/public/search/aggs/buckets/date_histogram.ts b/src/plugins/data/public/search/aggs/buckets/date_histogram.ts index 5b0f2921570c25..e4c4bc0cedc3c4 100644 --- a/src/plugins/data/public/search/aggs/buckets/date_histogram.ts +++ b/src/plugins/data/public/search/aggs/buckets/date_histogram.ts @@ -27,28 +27,30 @@ import { BucketAggType, IBucketAggConfig } from './bucket_agg_type'; import { BUCKET_TYPES } from './bucket_agg_types'; import { createFilterDateHistogram } from './create_filter/date_histogram'; import { intervalOptions } from './_interval_options'; -import { dateHistogramInterval, TimeRange } from '../../../../common'; import { writeParams } from '../agg_params'; import { isMetricAggType } from '../metrics/metric_agg_type'; -import { KBN_FIELD_TYPES, UI_SETTINGS } from '../../../../common'; -import { TimefilterContract } from '../../../query'; -import { QuerySetup } from '../../../query/query_service'; +import { + dateHistogramInterval, + KBN_FIELD_TYPES, + TimeRange, + TimeRangeBounds, + UI_SETTINGS, +} from '../../../../common'; import { GetInternalStartServicesFn } from '../../../types'; import { BaseAggParams } from '../types'; import { ExtendedBounds } from './lib/extended_bounds'; -const detectedTimezone = moment.tz.guess(); -const tzOffset = moment().format('Z'); +type CalculateBoundsFn = (timeRange: TimeRange) => TimeRangeBounds; const updateTimeBuckets = ( agg: IBucketDateHistogramAggConfig, - timefilter: TimefilterContract, + calculateBounds: CalculateBoundsFn, customBuckets?: IBucketDateHistogramAggConfig['buckets'] ) => { const bounds = agg.params.timeRange && (agg.fieldIsTimeField() || agg.params.interval === 'auto') - ? timefilter.calculateBounds(agg.params.timeRange) + ? calculateBounds(agg.params.timeRange) : undefined; const buckets = customBuckets || agg.buckets; buckets.setBounds(bounds); @@ -56,9 +58,9 @@ const updateTimeBuckets = ( }; export interface DateHistogramBucketAggDependencies { - uiSettings: IUiSettingsClient; - query: QuerySetup; + calculateBounds: CalculateBoundsFn; getInternalStartServices: GetInternalStartServicesFn; + uiSettings: IUiSettingsClient; } export interface IBucketDateHistogramAggConfig extends IBucketAggConfig { @@ -83,9 +85,9 @@ export interface AggParamsDateHistogram extends BaseAggParams { } export const getDateHistogramBucketAgg = ({ - uiSettings, - query, + calculateBounds, getInternalStartServices, + uiSettings, }: DateHistogramBucketAggDependencies) => new BucketAggType( { @@ -123,14 +125,13 @@ export const getDateHistogramBucketAgg = ({ get() { if (buckets) return buckets; - const { timefilter } = query.timefilter; buckets = new TimeBuckets({ 'histogram:maxBars': uiSettings.get(UI_SETTINGS.HISTOGRAM_MAX_BARS), 'histogram:barTarget': uiSettings.get(UI_SETTINGS.HISTOGRAM_BAR_TARGET), dateFormat: uiSettings.get('dateFormat'), 'dateFormat:scaled': uiSettings.get('dateFormat:scaled'), }); - updateTimeBuckets(this, timefilter, buckets); + updateTimeBuckets(this, calculateBounds, buckets); return buckets; }, @@ -195,8 +196,7 @@ export const getDateHistogramBucketAgg = ({ default: 'auto', options: intervalOptions, write(agg, output, aggs) { - const { timefilter } = query.timefilter; - updateTimeBuckets(agg, timefilter); + updateTimeBuckets(agg, calculateBounds); const { useNormalizedEsInterval, scaleMetricValues } = agg.params; const interval = agg.buckets.getInterval(useNormalizedEsInterval); @@ -257,6 +257,8 @@ export const getDateHistogramBucketAgg = ({ if (!tz) { // If the index pattern typeMeta data, didn't had a time zone assigned for the selected field use the configured tz const isDefaultTimezone = uiSettings.isDefault('dateFormat:tz'); + const detectedTimezone = moment.tz.guess(); + const tzOffset = moment().format('Z'); tz = isDefaultTimezone ? detectedTimezone || tzOffset : uiSettings.get('dateFormat:tz'); diff --git a/src/plugins/data/public/search/aggs/index.test.ts b/src/plugins/data/public/search/aggs/index.test.ts index 4864a8b9d013bb..73068326ca97ee 100644 --- a/src/plugins/data/public/search/aggs/index.test.ts +++ b/src/plugins/data/public/search/aggs/index.test.ts @@ -22,7 +22,6 @@ import { getAggTypes } from './index'; import { isBucketAggType } from './buckets/bucket_agg_type'; import { isMetricAggType } from './metrics/metric_agg_type'; -import { QueryStart } from '../../query'; import { FieldFormatsStart } from '../../field_formats'; import { InternalStartServices } from '../../types'; @@ -31,13 +30,13 @@ describe('AggTypesComponent', () => { const coreStart = coreMock.createSetup(); const aggTypes = getAggTypes({ - uiSettings: coreSetup.uiSettings, - query: {} as QueryStart, + calculateBounds: jest.fn(), getInternalStartServices: () => (({ notifications: coreStart.notifications, fieldFormats: {} as FieldFormatsStart, } as unknown) as InternalStartServices), + uiSettings: coreSetup.uiSettings, }); const { buckets, metrics } = aggTypes; diff --git a/src/plugins/data/public/search/aggs/test_helpers/mock_agg_types_registry.ts b/src/plugins/data/public/search/aggs/test_helpers/mock_agg_types_registry.ts index 836aaad2cda0c3..385d0cd6c6b396 100644 --- a/src/plugins/data/public/search/aggs/test_helpers/mock_agg_types_registry.ts +++ b/src/plugins/data/public/search/aggs/test_helpers/mock_agg_types_registry.ts @@ -22,7 +22,6 @@ import { AggTypesRegistry, AggTypesRegistryStart } from '../agg_types_registry'; import { getAggTypes } from '../agg_types'; import { BucketAggType } from '../buckets/bucket_agg_type'; import { MetricAggType } from '../metrics/metric_agg_type'; -import { queryServiceMock } from '../../../query/mocks'; import { fieldFormatsServiceMock } from '../../../field_formats/mocks'; import { InternalStartServices } from '../../../types'; import { TimeBucketsConfig } from '../buckets/lib/time_buckets/time_buckets'; @@ -79,8 +78,7 @@ export function mockAggTypesRegistry | MetricAggTyp coreSetup.uiSettings.get = mockUiSettings; const aggTypes = getAggTypes({ - uiSettings: coreSetup.uiSettings, - query: queryServiceMock.createSetupContract(), + calculateBounds: jest.fn(), getInternalStartServices: () => (({ fieldFormats: fieldFormatsServiceMock.createStartContract(), @@ -88,6 +86,7 @@ export function mockAggTypesRegistry | MetricAggTyp uiSettings: coreStart.uiSettings, injectedMetadata: coreStart.injectedMetadata, } as unknown) as InternalStartServices), + uiSettings: coreSetup.uiSettings, }); aggTypes.buckets.forEach((type) => registrySetup.registerBucket(type)); diff --git a/src/plugins/data/public/search/expressions/esaggs.ts b/src/plugins/data/public/search/expressions/esaggs.ts index d9ca378811e515..e9daec0b4191b6 100644 --- a/src/plugins/data/public/search/expressions/esaggs.ts +++ b/src/plugins/data/public/search/expressions/esaggs.ts @@ -32,8 +32,16 @@ import { Adapters } from '../../../../../plugins/inspector/public'; import { IAggConfigs } from '../aggs'; import { ISearchSource } from '../search_source'; import { tabifyAggResponse } from '../tabify'; -import { Filter, Query, TimeRange, IIndexPattern, isRangeFilter } from '../../../common'; -import { FilterManager, calculateBounds, getTime } from '../../query'; +import { + calculateBounds, + Filter, + getTime, + IIndexPattern, + isRangeFilter, + Query, + TimeRange, +} from '../../../common'; +import { FilterManager } from '../../query'; import { getFieldFormats, getIndexPatterns, diff --git a/src/plugins/data/public/search/search_service.ts b/src/plugins/data/public/search/search_service.ts index 992979ad0dbb0f..134dc89c2421a0 100644 --- a/src/plugins/data/public/search/search_service.ts +++ b/src/plugins/data/public/search/search_service.ts @@ -25,10 +25,11 @@ import { ExpressionsSetup } from '../../../../plugins/expressions/public'; import { createSearchSource, SearchSource, SearchSourceDependencies } from './search_source'; import { TStrategyTypes } from './strategy_types'; import { getEsClient, LegacyApiCaller } from './legacy'; +import { getForceNow } from '../query/timefilter/lib/get_force_now'; +import { calculateBounds, TimeRange } from '../../common/query'; import { ES_SEARCH_STRATEGY, DEFAULT_SEARCH_STRATEGY } from '../../common/search'; import { esSearchStrategyProvider } from './es_search'; import { IndexPatternsContract } from '../index_patterns/index_patterns'; -import { QuerySetup } from '../query'; import { GetInternalStartServicesFn } from '../types'; import { SearchInterceptor } from './search_interceptor'; import { @@ -44,7 +45,6 @@ interface SearchServiceSetupDependencies { expressions: ExpressionsSetup; getInternalStartServices: GetInternalStartServicesFn; packageInfo: PackageInfo; - query: QuerySetup; } interface SearchServiceStartDependencies { @@ -83,9 +83,16 @@ export class SearchService implements Plugin { return strategy; }; + /** + * getForceNow uses window.location, so we must have a separate implementation + * of calculateBounds on the client and the server. + */ + private calculateBounds = (timeRange: TimeRange) => + calculateBounds(timeRange, { forceNow: getForceNow() }); + public setup( core: CoreSetup, - { expressions, packageInfo, query, getInternalStartServices }: SearchServiceSetupDependencies + { expressions, packageInfo, getInternalStartServices }: SearchServiceSetupDependencies ): ISearchSetup { this.esClient = getEsClient(core.injectedMetadata, core.http, packageInfo); @@ -98,9 +105,9 @@ export class SearchService implements Plugin { // register each agg type const aggTypes = getAggTypes({ - query, - uiSettings: core.uiSettings, + calculateBounds: this.calculateBounds, getInternalStartServices, + uiSettings: core.uiSettings, }); aggTypes.buckets.forEach((b) => aggTypesSetup.registerBucket(b)); aggTypes.metrics.forEach((m) => aggTypesSetup.registerMetric(m)); diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index 19d028c1d41e1b..6a4eb38b552ffb 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -202,6 +202,7 @@ export { castEsToKbnFieldTypeName, // query Filter, + getTime, Query, // timefilter RefreshInterval, diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index f2a40fd48d7c1e..8c6137e95333d4 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -335,6 +335,14 @@ export function getDefaultSearchParams(config: SharedGlobalConfig): { restTotalHitsAsInt: boolean; }; +// Warning: (ae-missing-release-tag) "getTime" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export function getTime(indexPattern: IIndexPattern | undefined, timeRange: TimeRange, options?: { + forceNow?: Date; + fieldName?: string; +}): import("../..").RangeFilter | undefined; + // @internal export function getTotalLoaded({ total, failed, successful }: ShardsResponse): { total: number;