diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts
index 01a41d3c412c2..4f53cd467abd5 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_param_props.ts
@@ -19,8 +19,9 @@
import { Field } from 'src/plugins/data/public';
import { VisState } from 'src/legacy/core_plugins/visualizations/public';
-import { AggConfig, AggParam, EditorConfig } from '../legacy_imports';
+import { AggConfig, AggParam } from '../legacy_imports';
import { ComboBoxGroupedOptions } from '../utils';
+import { EditorConfig } from './utils';
// NOTE: we cannot export the interface with export { InterfaceName }
// as there is currently a bug on babel typescript transform plugin for it
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx
index d782c819c7c41..f271ef63376e1 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.test.tsx
@@ -36,10 +36,8 @@ const mockEditorConfig = {
};
jest.mock('ui/new_platform');
-jest.mock('ui/vis/config', () => ({
- editorConfigProviders: {
- getConfigForAgg: jest.fn(() => mockEditorConfig),
- },
+jest.mock('./utils', () => ({
+ getEditorConfig: jest.fn(() => mockEditorConfig),
}));
jest.mock('./agg_params_helper', () => ({
getAggParamsToRender: jest.fn(() => ({
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.tsx
index 47e98f175ab73..5449c9ac07c57 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.tsx
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params.tsx
@@ -23,14 +23,7 @@ import { i18n } from '@kbn/i18n';
import useUnmount from 'react-use/lib/useUnmount';
import { IndexPattern } from 'src/plugins/data/public';
-import {
- AggConfig,
- AggGroupNames,
- editorConfigProviders,
- FixedParam,
- TimeIntervalParam,
- EditorParamConfig,
-} from '../legacy_imports';
+import { AggConfig, AggGroupNames } from '../legacy_imports';
import { DefaultEditorAggSelect } from './agg_select';
import { DefaultEditorAggParam } from './agg_param';
@@ -46,6 +39,7 @@ import {
initAggParamsState,
} from './agg_params_state';
import { DefaultEditorCommonProps } from './agg_common_props';
+import { EditorParamConfig, TimeIntervalParam, FixedParam, getEditorConfig } from './utils';
const FIXED_VALUE_PROP = 'fixedValue';
const DEFAULT_PROP = 'default';
@@ -93,10 +87,12 @@ function DefaultEditorAggParams({
values: { schema: agg.schema.title },
})
: '';
-
- const editorConfig = useMemo(() => editorConfigProviders.getConfigForAgg(indexPattern, agg), [
+ const aggTypeName = agg.type?.name;
+ const fieldName = agg.params?.field?.name;
+ const editorConfig = useMemo(() => getEditorConfig(indexPattern, aggTypeName, fieldName), [
indexPattern,
- agg,
+ aggTypeName,
+ fieldName,
]);
const params = useMemo(() => getAggParamsToRender({ agg, editorConfig, metricAggs, state }), [
agg,
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts
index 6f584b4329500..40c76961cb594 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.test.ts
@@ -19,20 +19,14 @@
import { IndexPattern, Field } from 'src/plugins/data/public';
import { VisState } from 'src/legacy/core_plugins/visualizations/public';
-import {
- AggConfig,
- AggType,
- AggGroupNames,
- BUCKET_TYPES,
- IndexedArray,
- EditorConfig,
-} from '../legacy_imports';
+import { AggConfig, AggType, AggGroupNames, BUCKET_TYPES, IndexedArray } from '../legacy_imports';
import {
getAggParamsToRender,
getAggTypeOptions,
isInvalidParamsTouched,
} from './agg_params_helper';
import { FieldParamEditor, OrderByParamEditor } from './controls';
+import { EditorConfig } from './utils';
jest.mock('../utils', () => ({
groupAndSortBy: jest.fn(() => ['indexedFields']),
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts
index 21154bd7ad603..4b3b9084a4eef 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/agg_params_helper.ts
@@ -33,8 +33,8 @@ import {
AggParam,
FieldParamType,
AggType,
- EditorConfig,
} from '../legacy_imports';
+import { EditorConfig } from './utils';
interface ParamInstanceBase {
agg: AggConfig;
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts b/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts
index 4e811f4543412..0e6c30101d065 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/test_utils.ts
@@ -18,7 +18,8 @@
*/
import { VisState } from 'src/legacy/core_plugins/visualizations/public';
-import { AggConfig, AggParam, EditorConfig } from '../../legacy_imports';
+import { AggConfig, AggParam } from '../../legacy_imports';
+import { EditorConfig } from '../utils';
export const aggParamCommonPropsMock = {
agg: {} as AggConfig,
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx b/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx
index 6168890c2f2da..5da0d6462a8ba 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/controls/time_interval.tsx
@@ -107,7 +107,7 @@ function TimeIntervalParamEditor({
const onChange = (opts: EuiComboBoxOptionProps[]) => {
const selectedOpt: ComboBoxOption = get(opts, '0');
- setValue(selectedOpt ? selectedOpt.key : selectedOpt);
+ setValue(selectedOpt ? selectedOpt.key : '');
if (selectedOpt) {
agg.write();
diff --git a/src/legacy/core_plugins/vis_default_editor/public/components/utils/editor_config.ts b/src/legacy/core_plugins/vis_default_editor/public/components/utils/editor_config.ts
new file mode 100644
index 0000000000000..d6e6326afdec1
--- /dev/null
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/utils/editor_config.ts
@@ -0,0 +1,135 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { i18n } from '@kbn/i18n';
+import { IndexPattern } from 'src/plugins/data/public';
+
+/**
+ * A hidden parameter can be hidden from the UI completely.
+ */
+interface Param {
+ hidden?: boolean;
+ help?: string;
+}
+
+/**
+ * A fixed parameter has a fixed value for a specific field.
+ * It can optionally also be hidden.
+ */
+export type FixedParam = Partial & {
+ fixedValue: any;
+};
+
+/**
+ * Numeric interval parameters must always be set in the editor to a multiple of
+ * the specified base. It can optionally also be hidden.
+ */
+export type NumericIntervalParam = Partial & {
+ base: number;
+};
+
+/**
+ * Time interval parameters must always be set in the editor to a multiple of
+ * the specified base. It can optionally also be hidden.
+ */
+export type TimeIntervalParam = Partial & {
+ default: string;
+ timeBase: string;
+};
+
+export type EditorParamConfig = NumericIntervalParam | TimeIntervalParam | FixedParam | Param;
+
+export interface EditorConfig {
+ [paramName: string]: EditorParamConfig;
+}
+
+export function getEditorConfig(
+ indexPattern: IndexPattern,
+ aggTypeName: string,
+ fieldName: string
+): EditorConfig {
+ const aggRestrictions = indexPattern.getAggregationRestrictions();
+
+ if (!aggRestrictions || !aggTypeName || !fieldName) {
+ return {};
+ }
+
+ // Exclude certain param options for terms:
+ // otherBucket, missingBucket, orderBy, orderAgg
+ if (aggTypeName === 'terms') {
+ return {
+ otherBucket: {
+ hidden: true,
+ },
+ missingBucket: {
+ hidden: true,
+ },
+ };
+ }
+
+ const fieldAgg = aggRestrictions[aggTypeName] && aggRestrictions[aggTypeName][fieldName];
+
+ if (!fieldAgg) {
+ return {};
+ }
+
+ // Set interval and base interval for histograms based on agg restrictions
+ if (aggTypeName === 'histogram') {
+ const interval = fieldAgg.interval;
+ return interval
+ ? {
+ intervalBase: {
+ fixedValue: interval,
+ },
+ interval: {
+ base: interval,
+ help: i18n.translate('visDefaultEditor.editorConfig.histogram.interval.helpText', {
+ defaultMessage: 'Must be a multiple of rollup configuration interval: {interval}',
+ values: { interval },
+ }),
+ },
+ }
+ : {};
+ }
+
+ // Set date histogram time zone based on rollup capabilities
+ if (aggTypeName === 'date_histogram') {
+ // Interval is deprecated on date_histogram rollups, but may still be present
+ // See https://github.com/elastic/kibana/pull/36310
+ const interval = fieldAgg.calendar_interval || fieldAgg.fixed_interval;
+ return {
+ useNormalizedEsInterval: {
+ fixedValue: false,
+ },
+ interval: {
+ default: interval,
+ timeBase: interval,
+ help: i18n.translate(
+ 'visDefaultEditor.editorConfig.dateHistogram.customInterval.helpText',
+ {
+ defaultMessage: 'Must be a multiple of configuration interval: {interval}',
+ values: { interval },
+ }
+ ),
+ },
+ };
+ }
+
+ return {};
+}
diff --git a/src/legacy/ui/public/vis/config/index.ts b/src/legacy/core_plugins/vis_default_editor/public/components/utils/index.ts
similarity index 86%
rename from src/legacy/ui/public/vis/config/index.ts
rename to src/legacy/core_plugins/vis_default_editor/public/components/utils/index.ts
index ee7385518a85d..14570356103b1 100644
--- a/src/legacy/ui/public/vis/config/index.ts
+++ b/src/legacy/core_plugins/vis_default_editor/public/components/utils/index.ts
@@ -17,5 +17,4 @@
* under the License.
*/
-export { editorConfigProviders, EditorConfigProviderRegistry } from './editor_config_providers';
-export * from './types';
+export * from './editor_config';
diff --git a/src/legacy/core_plugins/vis_default_editor/public/legacy_imports.ts b/src/legacy/core_plugins/vis_default_editor/public/legacy_imports.ts
index 5c617f3dc8681..6d7be59c4ec13 100644
--- a/src/legacy/core_plugins/vis_default_editor/public/legacy_imports.ts
+++ b/src/legacy/core_plugins/vis_default_editor/public/legacy_imports.ts
@@ -55,4 +55,3 @@ export { getDocLink } from 'ui/documentation_links';
export { documentationLinks } from 'ui/documentation_links/documentation_links';
export { move } from 'ui/utils/collection';
export * from 'ui/vis/lib';
-export * from 'ui/vis/config';
diff --git a/src/legacy/ui/public/vis/config/editor_config_providers.test.ts b/src/legacy/ui/public/vis/config/editor_config_providers.test.ts
deleted file mode 100644
index 9d93930c09ebc..0000000000000
--- a/src/legacy/ui/public/vis/config/editor_config_providers.test.ts
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { AggConfig } from 'ui/agg_types';
-import { EditorConfigProviderRegistry } from './editor_config_providers';
-import { EditorParamConfig, FixedParam, NumericIntervalParam, TimeIntervalParam } from './types';
-
-jest.mock('ui/new_platform');
-
-describe('EditorConfigProvider', () => {
- let registry: EditorConfigProviderRegistry;
- const indexPattern = {
- id: '1234',
- title: 'logstash-*',
- fields: [
- {
- name: 'response',
- type: 'number',
- esTypes: ['integer'],
- aggregatable: true,
- filterable: true,
- searchable: true,
- },
- ],
- } as any;
-
- beforeEach(() => {
- registry = new EditorConfigProviderRegistry();
- });
-
- it('should call registered providers with given parameters', () => {
- const provider = jest.fn(() => ({}));
- registry.register(provider);
- expect(provider).not.toHaveBeenCalled();
- const aggConfig = {} as AggConfig;
- registry.getConfigForAgg(indexPattern, aggConfig);
- expect(provider).toHaveBeenCalledWith(indexPattern, aggConfig);
- });
-
- it('should call all registered providers with given parameters', () => {
- const provider = jest.fn(() => ({}));
- const provider2 = jest.fn(() => ({}));
- registry.register(provider);
- registry.register(provider2);
- expect(provider).not.toHaveBeenCalled();
- expect(provider2).not.toHaveBeenCalled();
- const aggConfig = {} as AggConfig;
- registry.getConfigForAgg(indexPattern, aggConfig);
- expect(provider).toHaveBeenCalledWith(indexPattern, aggConfig);
- expect(provider2).toHaveBeenCalledWith(indexPattern, aggConfig);
- });
-
- describe('merging configs', () => {
- function singleConfig(paramConfig: EditorParamConfig) {
- return () => ({ singleParam: paramConfig });
- }
-
- function getOutputConfig(reg: EditorConfigProviderRegistry) {
- return reg.getConfigForAgg(indexPattern, {} as AggConfig).singleParam;
- }
-
- it('should have hidden true if at least one config was hidden true', () => {
- registry.register(singleConfig({ hidden: false }));
- registry.register(singleConfig({ hidden: true }));
- registry.register(singleConfig({ hidden: false }));
- const config = getOutputConfig(registry);
- expect(config.hidden).toBe(true);
- });
-
- it('should merge the same fixed values', () => {
- registry.register(singleConfig({ fixedValue: 'foo' }));
- registry.register(singleConfig({ fixedValue: 'foo' }));
- const config = getOutputConfig(registry) as FixedParam;
- expect(config).toHaveProperty('fixedValue');
- expect(config.fixedValue).toBe('foo');
- });
-
- it('should throw having different fixed values', () => {
- registry.register(singleConfig({ fixedValue: 'foo' }));
- registry.register(singleConfig({ fixedValue: 'bar' }));
- expect(() => {
- getOutputConfig(registry);
- }).toThrowError();
- });
-
- it('should allow same base values', () => {
- registry.register(singleConfig({ base: 5 }));
- registry.register(singleConfig({ base: 5 }));
- const config = getOutputConfig(registry) as NumericIntervalParam;
- expect(config).toHaveProperty('base');
- expect(config.base).toBe(5);
- });
-
- it('should merge multiple base values, using least common multiple', () => {
- registry.register(singleConfig({ base: 2 }));
- registry.register(singleConfig({ base: 5 }));
- registry.register(singleConfig({ base: 8 }));
- const config = getOutputConfig(registry) as NumericIntervalParam;
- expect(config).toHaveProperty('base');
- expect(config.base).toBe(40);
- });
-
- it('should throw on combining fixedValue with base', () => {
- registry.register(singleConfig({ fixedValue: 'foo' }));
- registry.register(singleConfig({ base: 5 }));
- expect(() => {
- getOutputConfig(registry);
- }).toThrowError();
- });
-
- it('should allow same timeBase values', () => {
- registry.register(singleConfig({ timeBase: '2h', default: '2h' }));
- registry.register(singleConfig({ timeBase: '2h', default: '2h' }));
- const config = getOutputConfig(registry) as TimeIntervalParam;
- expect(config).toHaveProperty('timeBase');
- expect(config).toHaveProperty('default');
- expect(config.timeBase).toBe('2h');
- expect(config.default).toBe('2h');
- });
-
- it('should merge multiple compatible timeBase values, using least common interval', () => {
- registry.register(singleConfig({ timeBase: '2h', default: '2h' }));
- registry.register(singleConfig({ timeBase: '3h', default: '3h' }));
- registry.register(singleConfig({ timeBase: '4h', default: '4h' }));
- const config = getOutputConfig(registry) as TimeIntervalParam;
- expect(config).toHaveProperty('timeBase');
- expect(config).toHaveProperty('default');
- expect(config.timeBase).toBe('12h');
- expect(config.default).toBe('12h');
- });
-
- it('should throw on combining incompatible timeBase values', () => {
- registry.register(singleConfig({ timeBase: '2h', default: '2h' }));
- registry.register(singleConfig({ timeBase: '1d', default: '1d' }));
- expect(() => {
- getOutputConfig(registry);
- }).toThrowError();
- });
-
- it('should throw on invalid timeBase values', () => {
- registry.register(singleConfig({ timeBase: '2w', default: '2w' }));
- expect(() => {
- getOutputConfig(registry);
- }).toThrowError();
- });
-
- it('should throw if timeBase and default are different', () => {
- registry.register(singleConfig({ timeBase: '1h', default: '2h' }));
- expect(() => {
- getOutputConfig(registry);
- }).toThrowError();
- });
-
- it('should merge hidden together with fixedValue', () => {
- registry.register(singleConfig({ fixedValue: 'foo', hidden: true }));
- registry.register(singleConfig({ fixedValue: 'foo', hidden: false }));
- const config = getOutputConfig(registry) as FixedParam;
- expect(config).toHaveProperty('fixedValue');
- expect(config).toHaveProperty('hidden');
- expect(config.fixedValue).toBe('foo');
- expect(config.hidden).toBe(true);
- });
-
- it('should merge hidden together with base', () => {
- registry.register(singleConfig({ base: 2, hidden: false }));
- registry.register(singleConfig({ base: 13, hidden: false }));
- const config = getOutputConfig(registry) as NumericIntervalParam;
- expect(config).toHaveProperty('base');
- expect(config).toHaveProperty('hidden');
- expect(config.base).toBe(26);
- expect(config.hidden).toBe(false);
- });
-
- it('should merge hidden together with timeBase', () => {
- registry.register(singleConfig({ timeBase: '2h', default: '2h', hidden: false }));
- registry.register(singleConfig({ timeBase: '4h', default: '4h', hidden: false }));
- const config = getOutputConfig(registry) as TimeIntervalParam;
- expect(config).toHaveProperty('timeBase');
- expect(config).toHaveProperty('default');
- expect(config).toHaveProperty('hidden');
- expect(config.timeBase).toBe('4h');
- expect(config.default).toBe('4h');
- expect(config.hidden).toBe(false);
- });
-
- it('should merge helps together into one string', () => {
- registry.register(singleConfig({ help: 'Warning' }));
- registry.register(singleConfig({ help: 'Another help' }));
- const config = getOutputConfig(registry);
- expect(config).toHaveProperty('help');
- expect(config.help).toBe('Warning\n\nAnother help');
- });
- });
-});
diff --git a/src/legacy/ui/public/vis/config/editor_config_providers.ts b/src/legacy/ui/public/vis/config/editor_config_providers.ts
deleted file mode 100644
index 1e82a3ca2762e..0000000000000
--- a/src/legacy/ui/public/vis/config/editor_config_providers.ts
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { IndexPattern } from 'src/plugins/data/public';
-import { AggConfig } from 'ui/agg_types';
-import { parseEsInterval } from '../../../../core_plugins/data/public';
-import {
- TimeIntervalParam,
- EditorConfig,
- EditorParamConfig,
- FixedParam,
- NumericIntervalParam,
-} from './types';
-import { leastCommonInterval, leastCommonMultiple } from '../lib';
-
-type EditorConfigProvider = (indexPattern: IndexPattern, aggConfig: AggConfig) => EditorConfig;
-
-class EditorConfigProviderRegistry {
- private providers: Set = new Set();
-
- public register(configProvider: EditorConfigProvider): void {
- this.providers.add(configProvider);
- }
-
- public getConfigForAgg(indexPattern: IndexPattern, aggConfig: AggConfig): EditorConfig {
- const configs = Array.from(this.providers).map(provider => provider(indexPattern, aggConfig));
- return this.mergeConfigs(configs);
- }
-
- private isTimeBaseParam(config: EditorParamConfig): config is TimeIntervalParam {
- return config.hasOwnProperty('default') && config.hasOwnProperty('timeBase');
- }
-
- private isBaseParam(config: EditorParamConfig): config is NumericIntervalParam {
- return config.hasOwnProperty('base');
- }
-
- private isFixedParam(config: EditorParamConfig): config is FixedParam {
- return config.hasOwnProperty('fixedValue');
- }
-
- private mergeHidden(current: EditorParamConfig, merged: EditorParamConfig): boolean {
- return Boolean(current.hidden || merged.hidden);
- }
-
- private mergeHelp(current: EditorParamConfig, merged: EditorParamConfig): string | undefined {
- if (!current.help) {
- return merged.help;
- }
-
- return merged.help ? `${merged.help}\n\n${current.help}` : current.help;
- }
-
- private mergeFixedAndBase(
- current: EditorParamConfig,
- merged: EditorParamConfig,
- paramName: string
- ): { fixedValue: unknown } | { base: number } | {} {
- if (
- this.isFixedParam(current) &&
- this.isFixedParam(merged) &&
- current.fixedValue !== merged.fixedValue
- ) {
- // In case multiple configurations provided a fixedValue, these must all be the same.
- // If not we'll throw an error.
- throw new Error(`Two EditorConfigProviders provided different fixed values for field ${paramName}:
- ${merged.fixedValue} !== ${current.fixedValue}`);
- }
-
- if (
- (this.isFixedParam(current) && this.isBaseParam(merged)) ||
- (this.isBaseParam(current) && this.isFixedParam(merged))
- ) {
- // In case one config tries to set a fixed value and another setting a base value,
- // we'll throw an error. This could be solved more elegantly, by allowing fixedValues
- // that are the multiple of the specific base value, but since there is no use-case for that
- // right now, this isn't implemented.
- throw new Error(`Tried to provide a fixedValue and a base for param ${paramName}.`);
- }
-
- if (this.isBaseParam(current) && this.isBaseParam(merged)) {
- // In case where both had interval values, just use the least common multiple between both interval
- return {
- base: leastCommonMultiple(current.base, merged.base),
- };
- }
-
- // In this case we haven't had a fixed value of base for that param yet, we use the one specified
- // in the current config
- if (this.isFixedParam(current)) {
- return {
- fixedValue: current.fixedValue,
- };
- }
- if (this.isBaseParam(current)) {
- return {
- base: current.base,
- };
- }
-
- return {};
- }
-
- private mergeTimeBase(
- current: TimeIntervalParam,
- merged: EditorParamConfig,
- paramName: string
- ): { timeBase: string; default: string } {
- if (current.default !== current.timeBase) {
- throw new Error(`Tried to provide differing default and timeBase values for ${paramName}.`);
- }
-
- if (this.isTimeBaseParam(merged)) {
- // In case both had where interval values, just use the least common multiple between both intervals
- const timeBase = leastCommonInterval(current.timeBase, merged.timeBase);
- return {
- default: timeBase,
- timeBase,
- };
- }
-
- // This code is simply here to throw an error in case the `timeBase` is not a valid ES interval
- parseEsInterval(current.timeBase);
- return {
- default: current.timeBase,
- timeBase: current.timeBase,
- };
- }
-
- private mergeConfigs(configs: EditorConfig[]): EditorConfig {
- return configs.reduce((output, conf) => {
- Object.entries(conf).forEach(([paramName, paramConfig]) => {
- if (!output[paramName]) {
- output[paramName] = {};
- }
-
- output[paramName] = {
- hidden: this.mergeHidden(paramConfig, output[paramName]),
- help: this.mergeHelp(paramConfig, output[paramName]),
- ...(this.isTimeBaseParam(paramConfig)
- ? this.mergeTimeBase(paramConfig, output[paramName], paramName)
- : this.mergeFixedAndBase(paramConfig, output[paramName], paramName)),
- };
- });
- return output;
- }, {});
- }
-}
-
-const editorConfigProviders = new EditorConfigProviderRegistry();
-
-export { editorConfigProviders, EditorConfigProviderRegistry };
diff --git a/src/legacy/ui/public/vis/config/types.ts b/src/legacy/ui/public/vis/config/types.ts
deleted file mode 100644
index 61c0ced3cd519..0000000000000
--- a/src/legacy/ui/public/vis/config/types.ts
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * A hidden parameter can be hidden from the UI completely.
- */
-interface Param {
- hidden?: boolean;
- help?: string;
-}
-
-/**
- * A fixed parameter has a fixed value for a specific field.
- * It can optionally also be hidden.
- */
-export type FixedParam = Partial & {
- fixedValue: any;
-};
-
-/**
- * Numeric interval parameters must always be set in the editor to a multiple of
- * the specified base. It can optionally also be hidden.
- */
-export type NumericIntervalParam = Partial & {
- base: number;
-};
-
-/**
- * Time interval parameters must always be set in the editor to a multiple of
- * the specified base. It can optionally also be hidden.
- */
-export type TimeIntervalParam = Partial & {
- default: string;
- timeBase: string;
-};
-
-export type EditorParamConfig = NumericIntervalParam | TimeIntervalParam | FixedParam | Param;
-
-export interface EditorConfig {
- [paramName: string]: EditorParamConfig;
-}
diff --git a/src/plugins/data/public/index_patterns/index.ts b/src/plugins/data/public/index_patterns/index.ts
index 7444126ee6cae..3d902ebbb7c23 100644
--- a/src/plugins/data/public/index_patterns/index.ts
+++ b/src/plugins/data/public/index_patterns/index.ts
@@ -47,4 +47,10 @@ export const indexPatterns = {
export { Field, FieldList, IFieldList } from './fields';
// TODO: figure out how to replace IndexPatterns in get_inner_angular.
-export { IndexPattern, IndexPatterns, IndexPatternsContract } from './index_patterns';
+export {
+ IndexPattern,
+ IndexPatterns,
+ IndexPatternsContract,
+ TypeMeta,
+ AggregationRestrictions,
+} from './index_patterns';
diff --git a/src/plugins/data/public/index_patterns/index_patterns/index.ts b/src/plugins/data/public/index_patterns/index_patterns/index.ts
index 4ca7e053a4492..fca82025cdc66 100644
--- a/src/plugins/data/public/index_patterns/index_patterns/index.ts
+++ b/src/plugins/data/public/index_patterns/index_patterns/index.ts
@@ -22,3 +22,4 @@ export * from './format_hit';
export * from './index_pattern';
export * from './index_patterns';
export * from './index_patterns_api_client';
+export * from './types';
diff --git a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts
index 5c09e22b6dbb4..c09c9f4828799 100644
--- a/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts
+++ b/src/plugins/data/public/index_patterns/index_patterns/index_pattern.ts
@@ -38,6 +38,7 @@ import { formatHitProvider } from './format_hit';
import { flattenHitWrapper } from './flatten_hit';
import { IIndexPatternsApiClient } from './index_patterns_api_client';
import { getNotifications, getFieldFormats } from '../../services';
+import { TypeMeta } from './types';
const MAX_ATTEMPTS_TO_RESOLVE_CONFLICTS = 3;
const type = 'index-pattern';
@@ -49,7 +50,7 @@ export class IndexPattern implements IIndexPattern {
public title: string = '';
public type?: string;
public fieldFormatMap: any;
- public typeMeta: any;
+ public typeMeta?: TypeMeta;
public fields: IFieldList;
public timeFieldName: string | undefined;
public formatHit: any;
@@ -336,6 +337,10 @@ export class IndexPattern implements IIndexPattern {
return this.fields.getByName(name);
}
+ getAggregationRestrictions() {
+ return this.typeMeta?.aggs;
+ }
+
isWildcard() {
return _.includes(this.title, '*');
}
diff --git a/src/plugins/data/public/index_patterns/index_patterns/types.ts b/src/plugins/data/public/index_patterns/index_patterns/types.ts
new file mode 100644
index 0000000000000..70cddcfb641ff
--- /dev/null
+++ b/src/plugins/data/public/index_patterns/index_patterns/types.ts
@@ -0,0 +1,37 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export type AggregationRestrictions = Record<
+ string,
+ {
+ agg?: string;
+ interval?: number;
+ fixed_interval?: string;
+ calendar_interval?: string;
+ delay?: string;
+ time_zone?: string;
+ }
+>;
+
+export interface TypeMeta {
+ aggs?: Record;
+ params?: {
+ [key: string]: any;
+ };
+}
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/loader.ts b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/loader.ts
index c9473c1869868..f0692f120f9b5 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/loader.ts
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/loader.ts
@@ -15,13 +15,12 @@ import {
IndexPatternPersistedState,
IndexPatternPrivateState,
IndexPatternField,
- AggregationRestrictions,
} from './types';
import { updateLayerIndexPattern } from './state_helpers';
import { DateRange, ExistingFields } from '../../common/types';
import { BASE_API_URL } from '../../common';
import { documentField } from './document_field';
-import { isNestedField, IFieldType } from '../../../../../../src/plugins/data/public';
+import { isNestedField, IFieldType, TypeMeta } from '../../../../../../src/plugins/data/public';
interface SavedIndexPatternAttributes extends SavedObjectAttributes {
title: string;
@@ -31,12 +30,7 @@ interface SavedIndexPatternAttributes extends SavedObjectAttributes {
typeMeta: string;
}
-interface SavedRestrictionsObject {
- aggs: Record;
-}
-
type SetState = StateSetter;
-type SavedRestrictionsInfo = SavedRestrictionsObject | undefined;
type SavedObjectsClient = Pick;
type ErrorHandler = (err: Error) => void;
@@ -275,9 +269,7 @@ function fromSavedObject(
fields: (JSON.parse(attributes.fields) as IFieldType[])
.filter(field => !isNestedField(field) && (!!field.aggregatable || !!field.scripted))
.concat(documentField) as IndexPatternField[],
- typeMeta: attributes.typeMeta
- ? (JSON.parse(attributes.typeMeta) as SavedRestrictionsInfo)
- : undefined,
+ typeMeta: attributes.typeMeta ? (JSON.parse(attributes.typeMeta) as TypeMeta) : undefined,
fieldFormatMap: attributes.fieldFormatMap ? JSON.parse(attributes.fieldFormatMap) : undefined,
};
@@ -286,21 +278,23 @@ function fromSavedObject(
return indexPattern;
}
- const aggs = Object.keys(typeMeta.aggs);
-
const newFields = [...(indexPattern.fields as IndexPatternField[])];
- newFields.forEach((field, index) => {
- const restrictionsObj: IndexPatternField['aggregationRestrictions'] = {};
- aggs.forEach(agg => {
- const restriction = typeMeta.aggs[agg] && typeMeta.aggs[agg][field.name];
- if (restriction) {
- restrictionsObj[agg] = restriction;
+
+ if (typeMeta.aggs) {
+ const aggs = Object.keys(typeMeta.aggs);
+ newFields.forEach((field, index) => {
+ const restrictionsObj: IndexPatternField['aggregationRestrictions'] = {};
+ aggs.forEach(agg => {
+ const restriction = typeMeta.aggs && typeMeta.aggs[agg] && typeMeta.aggs[agg][field.name];
+ if (restriction) {
+ restrictionsObj[agg] = restriction;
+ }
+ });
+ if (Object.keys(restrictionsObj).length) {
+ newFields[index] = { ...field, aggregationRestrictions: restrictionsObj };
}
});
- if (Object.keys(restrictionsObj).length) {
- newFields[index] = { ...field, aggregationRestrictions: restrictionsObj };
- }
- });
+ }
return {
id: indexPattern.id,
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/date_histogram.tsx b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/date_histogram.tsx
index dbb6278352f09..07e348535ab02 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/date_histogram.tsx
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/operations/definitions/date_histogram.tsx
@@ -27,7 +27,7 @@ import { updateColumnParam } from '../../state_helpers';
import { OperationDefinition } from '.';
import { FieldBasedIndexPatternColumn } from './column_types';
import { autoIntervalFromDateRange } from '../../auto_date';
-import { AggregationRestrictions } from '../../types';
+import { AggregationRestrictions } from '../../../../../../../../src/plugins/data/public';
const autoInterval = 'auto';
const calendarOnlyIntervals = new Set(['w', 'M', 'q', 'y']);
diff --git a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/types.ts b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/types.ts
index e556ddda10679..546d148be1e29 100644
--- a/x-pack/legacy/plugins/lens/public/indexpattern_plugin/types.ts
+++ b/x-pack/legacy/plugins/lens/public/indexpattern_plugin/types.ts
@@ -5,6 +5,7 @@
*/
import { IndexPatternColumn } from './operations';
+import { AggregationRestrictions } from '../../../../../../src/plugins/data/public';
export interface IndexPattern {
id: string;
@@ -20,18 +21,6 @@ export interface IndexPattern {
>;
}
-export type AggregationRestrictions = Record<
- string,
- {
- agg?: string;
- interval?: number;
- fixed_interval?: string;
- calendar_interval?: string;
- delay?: string;
- time_zone?: string;
- }
->;
-
export interface IndexPatternField {
name: string;
type: string;
diff --git a/x-pack/legacy/plugins/rollup/public/legacy.ts b/x-pack/legacy/plugins/rollup/public/legacy.ts
index a2738372ff346..e52b5c3ae30e6 100644
--- a/x-pack/legacy/plugins/rollup/public/legacy.ts
+++ b/x-pack/legacy/plugins/rollup/public/legacy.ts
@@ -5,7 +5,6 @@
*/
import { npSetup, npStart } from 'ui/new_platform';
-import { editorConfigProviders } from 'ui/vis/config';
import { aggTypeFilters } from 'ui/agg_types/filter';
import { aggTypeFieldFilters } from 'ui/agg_types/param_types/filter';
import { addSearchStrategy } from '../../../../../src/plugins/data/public';
@@ -20,7 +19,6 @@ export const setup = plugin.setup(npSetup.core, {
__LEGACY: {
aggTypeFilters,
aggTypeFieldFilters,
- editorConfigProviders,
addSearchStrategy,
addBadgeExtension,
addToggleExtension,
diff --git a/x-pack/legacy/plugins/rollup/public/legacy_imports.ts b/x-pack/legacy/plugins/rollup/public/legacy_imports.ts
index 981f97963591e..d77e3c98b49d9 100644
--- a/x-pack/legacy/plugins/rollup/public/legacy_imports.ts
+++ b/x-pack/legacy/plugins/rollup/public/legacy_imports.ts
@@ -9,4 +9,3 @@ export { findIllegalCharactersInIndexName, INDEX_ILLEGAL_CHARACTERS_VISIBLE } fr
export { AggTypeFilters } from 'ui/agg_types/filter';
export { AggTypeFieldFilters } from 'ui/agg_types/param_types/filter';
-export { EditorConfigProviderRegistry } from 'ui/vis/config';
diff --git a/x-pack/legacy/plugins/rollup/public/plugin.ts b/x-pack/legacy/plugins/rollup/public/plugin.ts
index 97c03fd1fdfc2..4dae078c90f57 100644
--- a/x-pack/legacy/plugins/rollup/public/plugin.ts
+++ b/x-pack/legacy/plugins/rollup/public/plugin.ts
@@ -6,11 +6,7 @@
import { i18n } from '@kbn/i18n';
import { CoreSetup, CoreStart, Plugin } from 'kibana/public';
-import {
- EditorConfigProviderRegistry,
- AggTypeFilters,
- AggTypeFieldFilters,
-} from './legacy_imports';
+import { AggTypeFilters, AggTypeFieldFilters } from './legacy_imports';
import { SearchStrategyProvider } from '../../../../../src/plugins/data/public';
import { ManagementSetup as ManagementSetupLegacy } from '../../../../../src/legacy/core_plugins/management/public/np_ready';
import { rollupBadgeExtension, rollupToggleExtension } from './extend_index_management';
@@ -23,8 +19,6 @@ import { getRollupSearchStrategy } from './search/rollup_search_strategy';
import { initAggTypeFilter } from './visualize/agg_type_filter';
// @ts-ignore
import { initAggTypeFieldFilter } from './visualize/agg_type_field_filter';
-// @ts-ignore
-import { initEditorConfig } from './visualize/editor_config';
import { CONFIG_ROLLUPS } from '../common';
import {
FeatureCatalogueCategory,
@@ -42,7 +36,6 @@ export interface RollupPluginSetupDependencies {
__LEGACY: {
aggTypeFilters: AggTypeFilters;
aggTypeFieldFilters: AggTypeFieldFilters;
- editorConfigProviders: EditorConfigProviderRegistry;
addSearchStrategy: (searchStrategy: SearchStrategyProvider) => void;
managementLegacy: ManagementSetupLegacy;
addBadgeExtension: (badgeExtension: any) => void;
@@ -59,7 +52,6 @@ export class RollupPlugin implements Plugin {
__LEGACY: {
aggTypeFilters,
aggTypeFieldFilters,
- editorConfigProviders,
addSearchStrategy,
managementLegacy,
addBadgeExtension,
@@ -81,7 +73,6 @@ export class RollupPlugin implements Plugin {
addSearchStrategy(getRollupSearchStrategy(core.http.fetch));
initAggTypeFilter(aggTypeFilters);
initAggTypeFieldFilter(aggTypeFieldFilters);
- initEditorConfig(editorConfigProviders);
}
if (home) {
diff --git a/x-pack/legacy/plugins/rollup/public/visualize/editor_config.js b/x-pack/legacy/plugins/rollup/public/visualize/editor_config.js
deleted file mode 100644
index 5c1eb7c8ee3b7..0000000000000
--- a/x-pack/legacy/plugins/rollup/public/visualize/editor_config.js
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { i18n } from '@kbn/i18n';
-
-export function initEditorConfig(editorConfigProviders) {
- // Limit agg params based on rollup capabilities
- editorConfigProviders.register((indexPattern, aggConfig) => {
- if (indexPattern.type !== 'rollup') {
- return {};
- }
-
- const aggTypeName = aggConfig.type && aggConfig.type.name;
-
- // Exclude certain param options for terms:
- // otherBucket, missingBucket, orderBy, orderAgg
- if (aggTypeName === 'terms') {
- return {
- otherBucket: {
- hidden: true,
- },
- missingBucket: {
- hidden: true,
- },
- };
- }
-
- const rollupAggs = indexPattern.typeMeta && indexPattern.typeMeta.aggs;
- const field = aggConfig.params && aggConfig.params.field && aggConfig.params.field.name;
- const fieldAgg =
- rollupAggs && field && rollupAggs[aggTypeName] && rollupAggs[aggTypeName][field];
-
- if (!rollupAggs || !field || !fieldAgg) {
- return {};
- }
-
- // Set interval and base interval for histograms based on rollup capabilities
- if (aggTypeName === 'histogram') {
- const interval = fieldAgg.interval;
- return interval
- ? {
- intervalBase: {
- fixedValue: interval,
- },
- interval: {
- base: interval,
- help: i18n.translate('xpack.rollupJobs.editorConfig.histogram.interval.helpText', {
- defaultMessage: 'Must be a multiple of rollup configuration interval: {interval}',
- values: { interval },
- }),
- },
- }
- : {};
- }
-
- // Set date histogram time zone based on rollup capabilities
- if (aggTypeName === 'date_histogram') {
- // Interval is deprecated on date_histogram rollups, but may still be present
- // See https://github.com/elastic/kibana/pull/36310
- const interval = fieldAgg.calendar_interval || fieldAgg.fixed_interval || fieldAgg.interval;
- return {
- useNormalizedEsInterval: {
- fixedValue: false,
- },
- interval: {
- default: interval,
- timeBase: interval,
- help: i18n.translate(
- 'xpack.rollupJobs.editorConfig.dateHistogram.customInterval.helpText',
- {
- defaultMessage: 'Must be a multiple of rollup configuration interval: {interval}',
- values: { interval },
- }
- ),
- },
- };
- }
-
- return {};
- });
-}