From 8cf6e00b1bc19d410134ebb102882713123f43f2 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Wed, 30 Jun 2021 12:30:35 +0200 Subject: [PATCH 1/9] [APM] use conventional error rate color for correlations (#103500) --- .../public/components/app/correlations/error_correlations.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/plugins/apm/public/components/app/correlations/error_correlations.tsx b/x-pack/plugins/apm/public/components/app/correlations/error_correlations.tsx index 7fb7444a52f84..526aad56e743e 100644 --- a/x-pack/plugins/apm/public/components/app/correlations/error_correlations.tsx +++ b/x-pack/plugins/apm/public/components/app/correlations/error_correlations.tsx @@ -248,6 +248,7 @@ function ErrorTimeseriesChart({ yAccessors={['y']} data={overallData?.overall?.timeseries ?? []} curve={CurveType.CURVE_MONOTONE_X} + color={theme.eui.euiColorVis7} /> {correlationsData && selectedSignificantTerm ? ( From a63084b8de1e32170a61dc4f35dce14d77b8d3ec Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Wed, 30 Jun 2021 12:52:47 +0200 Subject: [PATCH 2/9] [Transform] Fix default naming and sorting fields suggestion for `top_metrics` agg (#103690) * [ML] remove advanced settings * [ML] fix getUpdatedItem for switching to single field agg * [ML] incremental naming for top aggs * [ML] set default sorting field based on date type * [ML] set desc order by default * [ML] fix TS * [ML] change sorting direction init --- .../transform/public/app/common/pivot_aggs.ts | 7 +- .../aggregation_list/popover_form.tsx | 17 +++- .../components/top_metrics_agg_form.tsx | 80 +------------------ .../common/top_metrics_agg/config.ts | 3 + .../step_define/hooks/use_pivot_config.ts | 56 ++++++++++++- 5 files changed, 76 insertions(+), 87 deletions(-) diff --git a/x-pack/plugins/transform/public/app/common/pivot_aggs.ts b/x-pack/plugins/transform/public/app/common/pivot_aggs.ts index 97685096a5d22..6f3d3de79c391 100644 --- a/x-pack/plugins/transform/public/app/common/pivot_aggs.ts +++ b/x-pack/plugins/transform/public/app/common/pivot_aggs.ts @@ -18,6 +18,7 @@ import { isPopulatedObject } from '../../../common/shared_imports'; import { getAggFormConfig } from '../sections/create_transform/components/step_define/common/get_agg_form_config'; import { PivotAggsConfigFilter } from '../sections/create_transform/components/step_define/common/filter_agg/types'; +import { PivotAggsConfigTopMetrics } from '../sections/create_transform/components/step_define/common/top_metrics_agg/types'; export function isPivotSupportedAggs(arg: unknown): arg is PivotSupportedAggs { return ( @@ -240,12 +241,16 @@ export function isPivotAggsConfigWithUiSupport(arg: unknown): arg is PivotAggsCo /** * Union type for agg configs with extended forms */ -type PivotAggsConfigWithExtendedForm = PivotAggsConfigFilter; +type PivotAggsConfigWithExtendedForm = PivotAggsConfigFilter | PivotAggsConfigTopMetrics; export function isPivotAggsWithExtendedForm(arg: unknown): arg is PivotAggsConfigWithExtendedForm { return isPopulatedObject(arg, ['AggFormComponent']); } +export function isPivotAggConfigTopMetric(arg: unknown): arg is PivotAggsConfigTopMetrics { + return isPivotAggsWithExtendedForm(arg) && arg.agg === PIVOT_SUPPORTED_AGGS.TOP_METRICS; +} + export function isPivotAggsConfigPercentiles(arg: unknown): arg is PivotAggsConfigPercentiles { return ( isPopulatedObject(arg, ['agg', 'field', 'percents']) && diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx index fd11255374a51..831ee17371910 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/aggregation_list/popover_form.tsx @@ -126,19 +126,30 @@ export const PopoverForm: React.FC = ({ defaultData, otherAggNames, onCha function getUpdatedItem(): PivotAggsConfig { let updatedItem: PivotAggsConfig; + + let resultField = field; + if ( + isPivotAggsConfigWithUiSupport(aggConfigDef) && + !aggConfigDef.isMultiField && + Array.isArray(field) + ) { + // reset to a single field in case agg doesn't support multiple fields + resultField = field[0]; + } + if (agg !== PIVOT_SUPPORTED_AGGS.PERCENTILES) { updatedItem = { ...aggConfigDef, agg, aggName, - field, + field: resultField, dropDownName: defaultData.dropDownName, }; } else { updatedItem = { agg, aggName, - field, + field: resultField, dropDownName: defaultData.dropDownName, percents, }; @@ -286,7 +297,7 @@ export const PopoverForm: React.FC = ({ defaultData, otherAggNames, onCha { + onChange={(update: typeof aggConfigDef.aggConfig) => { setAggConfigDef({ ...aggConfigDef, aggConfig: update, diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/top_metrics_agg/components/top_metrics_agg_form.tsx b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/top_metrics_agg/components/top_metrics_agg_form.tsx index 0ec66a3d59a11..6af319274a5c2 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/top_metrics_agg/components/top_metrics_agg_form.tsx +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/top_metrics_agg/components/top_metrics_agg_form.tsx @@ -8,18 +8,13 @@ import React, { useCallback, useContext } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiFormRow, EuiSelect, EuiButtonGroup, EuiAccordion, EuiSpacer } from '@elastic/eui'; +import { EuiFormRow, EuiSelect, EuiButtonGroup, EuiSpacer } from '@elastic/eui'; import { PivotAggsConfigTopMetrics, TopMetricsAggConfig } from '../types'; import { PivotConfigurationContext } from '../../../../pivot_configuration/pivot_configuration'; import { isSpecialSortField, - KbnNumericType, - NUMERIC_TYPES_OPTIONS, SORT_DIRECTION, - SORT_MODE, SortDirection, - SortMode, - SortNumericFieldType, TOP_METRICS_SORT_FIELD_TYPES, TOP_METRICS_SPECIAL_SORT_FIELDS, } from '../../../../../../../common/pivot_aggs'; @@ -48,13 +43,6 @@ export const TopMetricsAggForm: PivotAggsConfigTopMetrics['AggFormComponent'] = label: v, })); - const sortModeOptions = Object.values(SORT_MODE).map((v) => ({ - id: v, - label: v, - })); - - const sortFieldType = fields.find((f) => f.name === aggConfig.sortField)?.type; - const sortSettings = aggConfig.sortSettings ?? {}; const updateSortSettings = useCallback( @@ -120,72 +108,6 @@ export const TopMetricsAggForm: PivotAggsConfigTopMetrics['AggFormComponent'] = - - - } - > - - } - helpText={ - - } - > - { - updateSortSettings({ mode: id as SortMode }); - }} - color="text" - /> - - - {sortFieldType && NUMERIC_TYPES_OPTIONS.hasOwnProperty(sortFieldType) ? ( - - } - > - ({ - text: v, - name: v, - }))} - value={sortSettings.numericType} - onChange={(e) => { - updateSortSettings({ - numericType: e.target.value as SortNumericFieldType, - }); - }} - data-test-subj="transformSortNumericTypeTopMetricsLabel" - /> - - ) : null} - )} diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/top_metrics_agg/config.ts b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/top_metrics_agg/config.ts index 56d17e7973e16..354a326f38659 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/top_metrics_agg/config.ts +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/common/top_metrics_agg/config.ts @@ -17,6 +17,7 @@ import { import { PivotAggsConfigTopMetrics } from './types'; import { TopMetricsAggForm } from './components/top_metrics_agg_form'; import { isPopulatedObject } from '../../../../../../../../common/shared_imports'; +import { PIVOT_SUPPORTED_AGGS } from '../../../../../../../../common/types/pivot_aggs'; /** * Gets initial basic configuration of the top_metrics aggregation. @@ -30,6 +31,8 @@ export function getTopMetricsAggConfig( isMultiField: true, field: isPivotAggsConfigWithUiSupport(commonConfig) ? commonConfig.field : '', AggFormComponent: TopMetricsAggForm, + /** Default name */ + aggName: PIVOT_SUPPORTED_AGGS.TOP_METRICS, aggConfig: {}, getEsAggConfig() { // ensure the configuration has been completed diff --git a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_pivot_config.ts b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_pivot_config.ts index 0c31b4fe2da81..a291f648a835e 100644 --- a/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_pivot_config.ts +++ b/x-pack/plugins/transform/public/app/sections/create_transform/components/step_define/hooks/use_pivot_config.ts @@ -13,8 +13,9 @@ import { dictionaryToArray } from '../../../../../../../common/types/common'; import { useToastNotifications } from '../../../../../app_dependencies'; import { - getRequestPayload, DropDownLabel, + getRequestPayload, + isPivotGroupByConfigWithUiSupport, PivotAggsConfig, PivotAggsConfigDict, PivotGroupByConfig, @@ -26,8 +27,14 @@ import { StepDefineExposedState, } from '../common'; import { StepDefineFormProps } from '../step_define_form'; -import { isPivotAggsWithExtendedForm } from '../../../../../common/pivot_aggs'; +import { + isPivotAggConfigTopMetric, + isPivotAggsWithExtendedForm, +} from '../../../../../common/pivot_aggs'; import { TransformPivotConfig } from '../../../../../../../common/types/transform'; +import { PIVOT_SUPPORTED_AGGS } from '../../../../../../../common/types/pivot_aggs'; +import { KBN_FIELD_TYPES } from '../../../../../../../../../../src/plugins/data/common'; +import { isPivotAggConfigWithUiSupport } from '../../../../../common/pivot_group_by'; /** * Clones aggregation configuration and updates parent references @@ -165,7 +172,48 @@ export const usePivotConfig = ( (d: DropDownLabel[]) => { const label: AggName = d[0].label; const config: PivotAggsConfig = aggOptionsData[label]; - const aggName: AggName = config.aggName; + + let aggName: AggName = config.aggName; + + if (isPivotAggConfigTopMetric(config)) { + let suggestedSortField = [ + ...new Set( + Object.values(groupByList).map((v) => + isPivotGroupByConfigWithUiSupport(v) ? v.field : undefined + ) + ), + ].find((v) => fields.find((x) => x.name === v)?.type === KBN_FIELD_TYPES.DATE); + + if (!suggestedSortField) { + suggestedSortField = [ + ...new Set( + Object.values(aggList) + .map((v) => (isPivotAggConfigWithUiSupport(v) ? v.field : undefined)) + .flat() + ), + ].find((v) => fields.find((x) => x.name === v)?.type === KBN_FIELD_TYPES.DATE); + } + + if (suggestedSortField) { + config.aggConfig.sortField = suggestedSortField; + config.aggConfig.sortSettings = {}; + config.aggConfig.sortSettings.order = 'desc'; + } + } + + if (aggList[aggName] && aggName === PIVOT_SUPPORTED_AGGS.TOP_METRICS) { + // handle special case for naming top_metric aggs + const regExp = new RegExp(`^${PIVOT_SUPPORTED_AGGS.TOP_METRICS}(\\d)*$`); + const increment: number = Object.keys(aggList).reduce((acc, curr) => { + const match = curr.match(regExp); + if (!match || !match[1]) return acc; + const n = Number(match[1]); + return n > acc ? n : acc; + }, 0 as number); + + aggName = `${PIVOT_SUPPORTED_AGGS.TOP_METRICS}${increment + 1}`; + config.aggName = aggName; + } const aggNameConflictMessages = getAggNameConflictToastMessages( aggName, @@ -180,7 +228,7 @@ export const usePivotConfig = ( aggList[aggName] = config; setAggList({ ...aggList }); }, - [aggList, aggOptionsData, groupByList, toastNotifications] + [aggList, aggOptionsData, groupByList, toastNotifications, fields] ); /** From 1d02a0d6c1f237320917bd0e3eefec0102269d64 Mon Sep 17 00:00:00 2001 From: Tim Roes Date: Wed, 30 Jun 2021 13:37:16 +0200 Subject: [PATCH 3/9] Fix telemetry advanced setting style (#103838) --- ...telemetry_management_section.test.tsx.snap | 246 +++++++++--------- .../telemetry_management_section.tsx | 85 +++--- 2 files changed, 160 insertions(+), 171 deletions(-) diff --git a/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap b/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap index c4cee25a33b7f..014142a2a3d06 100644 --- a/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap +++ b/src/plugins/telemetry_management_section/public/components/__snapshots__/telemetry_management_section.test.tsx.snap @@ -47,139 +47,137 @@ exports[`TelemetryManagementSectionComponent does not show the endpoint link whe exports[`TelemetryManagementSectionComponent renders as expected 1`] = ` - - - - -

- -

-
-
-
- + <_EuiSplitPanelInner + color="subdued" + > + +

- - , - } - } + defaultMessage="Usage Data" + id="telemetry.usageDataTitle" + values={Object {}} /> -

- } - /> - - -

- - - , - } +

+
+ + <_EuiSplitPanelInner> + + + + , } - /> -

-

- - - , - "endpointSecurityData": - - , + } + /> +

+ } + /> + + +

+ + + , + } } - } - /> -

- , - "displayName": "Provide usage statistics", - "isCustom": true, - "isOverridden": false, - "name": "telemetry:enabled", - "requiresPageReload": false, - "type": "boolean", - "value": true, + /> +

+

+ + + , + "endpointSecurityData": + + , + } + } + /> +

+ , + "displayName": "Provide usage statistics", + "isCustom": true, + "isOverridden": false, + "name": "telemetry:enabled", + "requiresPageReload": false, + "type": "boolean", + "value": true, + } } - } - toasts={ - Object { - "add": [MockFunction], - "addDanger": [MockFunction], - "addError": [MockFunction], - "addInfo": [MockFunction], - "addSuccess": [MockFunction], - "addWarning": [MockFunction], - "get$": [MockFunction], - "remove": [MockFunction], + toasts={ + Object { + "add": [MockFunction], + "addDanger": [MockFunction], + "addError": [MockFunction], + "addInfo": [MockFunction], + "addSuccess": [MockFunction], + "addWarning": [MockFunction], + "get$": [MockFunction], + "remove": [MockFunction], + } } - } - /> + /> +
-
+
`; diff --git a/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx index e9ddc4cf82dfc..b0d1b42a9b892 100644 --- a/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx +++ b/src/plugins/telemetry_management_section/public/components/telemetry_management_section.tsx @@ -7,16 +7,7 @@ */ import React, { Component, Fragment } from 'react'; -import { - EuiCallOut, - EuiPanel, - EuiForm, - EuiFlexGroup, - EuiFlexItem, - EuiLink, - EuiSpacer, - EuiText, -} from '@elastic/eui'; +import { EuiCallOut, EuiForm, EuiLink, EuiSpacer, EuiSplitPanel, EuiTitle } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; @@ -116,46 +107,46 @@ export class TelemetryManagementSection extends Component { )} - + - - - -

- -

-
-
-
+ + +

+ +

+
+
- {this.maybeGetAppliesSettingMessage()} - - + + {this.maybeGetAppliesSettingMessage()} + + +
-
+ ); } From 0ef542041b175afb173b31e4c2c70a2fb27ff21d Mon Sep 17 00:00:00 2001 From: Dave Snider Date: Wed, 30 Jun 2021 07:47:53 -0400 Subject: [PATCH 4/9] Remove add data button from nav (#103810) * Remove add data button from nav * remove unused imports Co-authored-by: Michail Yasonik --- .../collapsible_nav.test.tsx.snap | 89 ------------------- .../chrome/ui/header/collapsible_nav.tsx | 12 --- 2 files changed, 101 deletions(-) diff --git a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap index a653fbc5e40bd..9e890f5bce408 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap @@ -1917,95 +1917,6 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` /> - -
- - -
-
- - - - - -
-
-
-
-
diff --git a/src/core/public/chrome/ui/header/collapsible_nav.tsx b/src/core/public/chrome/ui/header/collapsible_nav.tsx index 2ce5cf2ee4933..eaddc6b94bd46 100644 --- a/src/core/public/chrome/ui/header/collapsible_nav.tsx +++ b/src/core/public/chrome/ui/header/collapsible_nav.tsx @@ -16,10 +16,8 @@ import { EuiListGroupItem, EuiShowFor, EuiCollapsibleNavProps, - EuiButton, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { FormattedMessage } from '@kbn/i18n/react'; import { groupBy, sortBy } from 'lodash'; import React, { Fragment, useRef } from 'react'; import useObservable from 'react-use/lib/useObservable'; @@ -325,16 +323,6 @@ export function CollapsibleNav({ - {/* Quick addition of that "ADD DATA" button everyone wants :) Feel free to remove though. */} - - {/* Span fakes the nav group into not being the first item and therefore adding a top border */} - - - - - - - ); } From 2bc801c8ef26c357a4be437852bd1fd6745724a4 Mon Sep 17 00:00:00 2001 From: Liza Katz Date: Wed, 30 Jun 2021 13:07:27 +0100 Subject: [PATCH 5/9] [Query] Es query/field base (#103177) * remove es query dependency on format.convert * FieldBase * fix types * types * Fix type imports * test types * fix jest * rename * docs * comment --- ...na-plugin-plugins-data-public.esfilters.md | 8 ++-- ...gin-plugins-data-public.ifieldtype.lang.md | 11 ----- ...a-plugin-plugins-data-public.ifieldtype.md | 8 +--- ...gin-plugins-data-public.ifieldtype.name.md | 11 ----- ...n-plugins-data-public.ifieldtype.script.md | 11 ----- ...plugins-data-public.ifieldtype.scripted.md | 11 ----- ...-plugins-data-public.ifieldtype.subtype.md | 11 ----- ...gin-plugins-data-public.ifieldtype.type.md | 11 ----- ...lugins-data-public.iindexpattern.fields.md | 11 +++++ ...lugin-plugins-data-public.iindexpattern.md | 1 + ...indexpattern.getaggregationrestrictions.md | 8 +++- ...n-plugins-data-public.indexpatternfield.md | 2 +- ...s-data-public.indexpatternfield.subtype.md | 2 +- ...ns-data-public.indexpatternfield.tojson.md | 4 +- ...na-plugin-plugins-data-server.esfilters.md | 8 ++-- ...gin-plugins-data-server.ifieldtype.lang.md | 11 ----- ...a-plugin-plugins-data-server.ifieldtype.md | 8 +--- ...gin-plugins-data-server.ifieldtype.name.md | 11 ----- ...n-plugins-data-server.ifieldtype.script.md | 11 ----- ...plugins-data-server.ifieldtype.scripted.md | 11 ----- ...-plugins-data-server.ifieldtype.subtype.md | 11 ----- ...gin-plugins-data-server.ifieldtype.type.md | 11 ----- ...indexpattern.getaggregationrestrictions.md | 8 +++- .../es_query/es_query/filter_matches_index.ts | 3 +- .../es_query/handle_nested_filter.test.ts | 9 ++-- .../data/common/es_query/es_query/index.ts | 2 +- .../data/common/es_query/es_query/types.ts | 27 +++++++++++- .../common/es_query/filters/build_filters.ts | 7 ++-- .../common/es_query/filters/exists_filter.ts | 5 +-- .../common/es_query/filters/phrase_filter.ts | 9 ++-- .../common/es_query/filters/phrases_filter.ts | 5 +-- .../es_query/filters/range_filter.test.ts | 14 +++---- .../common/es_query/filters/range_filter.ts | 11 +++-- .../common/es_query/kuery/functions/exists.ts | 7 ++-- .../kuery/functions/geo_bounding_box.ts | 6 +-- .../es_query/kuery/functions/geo_polygon.ts | 6 +-- .../common/es_query/kuery/functions/is.ts | 4 +- .../common/es_query/kuery/functions/range.ts | 4 +- .../kuery/functions/utils/get_fields.test.ts | 14 +++---- .../utils/get_full_field_name_node.ts | 4 +- .../common/index_patterns/fields/types.ts | 11 +---- .../data/common/index_patterns/types.ts | 24 ++--------- src/plugins/data/public/public.api.md | 41 ++++++++----------- src/plugins/data/server/server.api.md | 27 ++++-------- 44 files changed, 148 insertions(+), 292 deletions(-) delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.lang.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.name.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.script.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.scripted.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.subtype.md delete mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.type.md create mode 100644 docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpattern.fields.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.lang.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.name.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.script.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.scripted.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.subtype.md delete mode 100644 docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.type.md diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esfilters.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esfilters.md index 80c321ce6b320..d06ce1b2ef2bc 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esfilters.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.esfilters.md @@ -13,11 +13,11 @@ esFilters: { FILTERS: typeof FILTERS; FilterStateStore: typeof FilterStateStore; buildEmptyFilter: (isPinned: boolean, index?: string | undefined) => import("../common").Filter; - buildPhrasesFilter: (field: import("../common").IFieldType, params: any[], indexPattern: import("../common").IndexPatternBase) => import("../common").PhrasesFilter; - buildExistsFilter: (field: import("../common").IFieldType, indexPattern: import("../common").IndexPatternBase) => import("../common").ExistsFilter; - buildPhraseFilter: (field: import("../common").IFieldType, value: any, indexPattern: import("../common").IndexPatternBase) => import("../common").PhraseFilter; + buildPhrasesFilter: (field: import("../common").IndexPatternFieldBase, params: any[], indexPattern: import("../common").IndexPatternBase) => import("../common").PhrasesFilter; + buildExistsFilter: (field: import("../common").IndexPatternFieldBase, indexPattern: import("../common").IndexPatternBase) => import("../common").ExistsFilter; + buildPhraseFilter: (field: import("../common").IndexPatternFieldBase, value: any, indexPattern: import("../common").IndexPatternBase) => import("../common").PhraseFilter; buildQueryFilter: (query: any, index: string, alias: string) => import("../common").QueryStringFilter; - buildRangeFilter: (field: import("../common").IFieldType, params: import("../common").RangeFilterParams, indexPattern: import("../common").IndexPatternBase, formattedValue?: string | undefined) => import("../common").RangeFilter; + buildRangeFilter: (field: import("../common").IndexPatternFieldBase, params: import("../common").RangeFilterParams, indexPattern: import("../common").IndexPatternBase, formattedValue?: string | undefined) => import("../common").RangeFilter; isPhraseFilter: (filter: any) => filter is import("../common").PhraseFilter; isExistsFilter: (filter: any) => filter is import("../common").ExistsFilter; isPhrasesFilter: (filter: any) => filter is import("../common").PhrasesFilter; diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.lang.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.lang.md deleted file mode 100644 index f99e7ba8b967e..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.lang.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IFieldType](./kibana-plugin-plugins-data-public.ifieldtype.md) > [lang](./kibana-plugin-plugins-data-public.ifieldtype.lang.md) - -## IFieldType.lang property - -Signature: - -```typescript -lang?: estypes.ScriptLanguage; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.md index 29377ff8fd392..e1acea53ea5e0 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.md @@ -12,7 +12,7 @@ Signature: ```typescript -export interface IFieldType +export interface IFieldType extends IndexPatternFieldBase ``` ## Properties @@ -26,15 +26,9 @@ export interface IFieldType | [esTypes](./kibana-plugin-plugins-data-public.ifieldtype.estypes.md) | string[] | | | [filterable](./kibana-plugin-plugins-data-public.ifieldtype.filterable.md) | boolean | | | [format](./kibana-plugin-plugins-data-public.ifieldtype.format.md) | any | | -| [lang](./kibana-plugin-plugins-data-public.ifieldtype.lang.md) | estypes.ScriptLanguage | | -| [name](./kibana-plugin-plugins-data-public.ifieldtype.name.md) | string | | | [readFromDocValues](./kibana-plugin-plugins-data-public.ifieldtype.readfromdocvalues.md) | boolean | | -| [script](./kibana-plugin-plugins-data-public.ifieldtype.script.md) | string | | -| [scripted](./kibana-plugin-plugins-data-public.ifieldtype.scripted.md) | boolean | | | [searchable](./kibana-plugin-plugins-data-public.ifieldtype.searchable.md) | boolean | | | [sortable](./kibana-plugin-plugins-data-public.ifieldtype.sortable.md) | boolean | | -| [subType](./kibana-plugin-plugins-data-public.ifieldtype.subtype.md) | IFieldSubType | | | [toSpec](./kibana-plugin-plugins-data-public.ifieldtype.tospec.md) | (options?: {
getFormatterForField?: IndexPattern['getFormatterForField'];
}) => FieldSpec | | -| [type](./kibana-plugin-plugins-data-public.ifieldtype.type.md) | string | | | [visualizable](./kibana-plugin-plugins-data-public.ifieldtype.visualizable.md) | boolean | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.name.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.name.md deleted file mode 100644 index 1c01484372fd3..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.name.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IFieldType](./kibana-plugin-plugins-data-public.ifieldtype.md) > [name](./kibana-plugin-plugins-data-public.ifieldtype.name.md) - -## IFieldType.name property - -Signature: - -```typescript -name: string; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.script.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.script.md deleted file mode 100644 index 252c2c3822046..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.script.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IFieldType](./kibana-plugin-plugins-data-public.ifieldtype.md) > [script](./kibana-plugin-plugins-data-public.ifieldtype.script.md) - -## IFieldType.script property - -Signature: - -```typescript -script?: string; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.scripted.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.scripted.md deleted file mode 100644 index 33bbd0c2c20cb..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.scripted.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IFieldType](./kibana-plugin-plugins-data-public.ifieldtype.md) > [scripted](./kibana-plugin-plugins-data-public.ifieldtype.scripted.md) - -## IFieldType.scripted property - -Signature: - -```typescript -scripted?: boolean; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.subtype.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.subtype.md deleted file mode 100644 index d0c26186da085..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.subtype.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IFieldType](./kibana-plugin-plugins-data-public.ifieldtype.md) > [subType](./kibana-plugin-plugins-data-public.ifieldtype.subtype.md) - -## IFieldType.subType property - -Signature: - -```typescript -subType?: IFieldSubType; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.type.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.type.md deleted file mode 100644 index 26228cbe4bfdb..0000000000000 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.ifieldtype.type.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IFieldType](./kibana-plugin-plugins-data-public.ifieldtype.md) > [type](./kibana-plugin-plugins-data-public.ifieldtype.type.md) - -## IFieldType.type property - -Signature: - -```typescript -type: string; -``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpattern.fields.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpattern.fields.md new file mode 100644 index 0000000000000..792bee44f96a8 --- /dev/null +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpattern.fields.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-public](./kibana-plugin-plugins-data-public.md) > [IIndexPattern](./kibana-plugin-plugins-data-public.iindexpattern.md) > [fields](./kibana-plugin-plugins-data-public.iindexpattern.fields.md) + +## IIndexPattern.fields property + +Signature: + +```typescript +fields: IFieldType[]; +``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpattern.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpattern.md index ec29ef81a6e69..c441073781169 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpattern.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.iindexpattern.md @@ -20,6 +20,7 @@ export interface IIndexPattern extends IndexPatternBase | Property | Type | Description | | --- | --- | --- | | [fieldFormatMap](./kibana-plugin-plugins-data-public.iindexpattern.fieldformatmap.md) | Record<string, SerializedFieldFormat<unknown> | undefined> | | +| [fields](./kibana-plugin-plugins-data-public.iindexpattern.fields.md) | IFieldType[] | | | [getFormatterForField](./kibana-plugin-plugins-data-public.iindexpattern.getformatterforfield.md) | (field: IndexPatternField | IndexPatternField['spec'] | IFieldType) => FieldFormat | Look up a formatter for a given field | | [timeFieldName](./kibana-plugin-plugins-data-public.iindexpattern.timefieldname.md) | string | | | [title](./kibana-plugin-plugins-data-public.iindexpattern.title.md) | string | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getaggregationrestrictions.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getaggregationrestrictions.md index e42980bb53af4..1bbe0b594ecf0 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getaggregationrestrictions.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpattern.getaggregationrestrictions.md @@ -9,7 +9,9 @@ ```typescript getAggregationRestrictions(): Recordboolean | | | [sortable](./kibana-plugin-plugins-data-public.indexpatternfield.sortable.md) | | boolean | | | [spec](./kibana-plugin-plugins-data-public.indexpatternfield.spec.md) | | FieldSpec | | -| [subType](./kibana-plugin-plugins-data-public.indexpatternfield.subtype.md) | | import("../types").IFieldSubType | undefined | | +| [subType](./kibana-plugin-plugins-data-public.indexpatternfield.subtype.md) | | import("../..").IFieldSubType | undefined | | | [type](./kibana-plugin-plugins-data-public.indexpatternfield.type.md) | | string | | | [visualizable](./kibana-plugin-plugins-data-public.indexpatternfield.visualizable.md) | | boolean | | diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.subtype.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.subtype.md index 5c3c4d54ad099..6cd5247291602 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.subtype.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.subtype.md @@ -7,5 +7,5 @@ Signature: ```typescript -get subType(): import("../types").IFieldSubType | undefined; +get subType(): import("../..").IFieldSubType | undefined; ``` diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tojson.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tojson.md index 8882fa05ce0c2..b77f3d1f374fb 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tojson.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.indexpatternfield.tojson.md @@ -19,7 +19,7 @@ toJSON(): { searchable: boolean; aggregatable: boolean; readFromDocValues: boolean; - subType: import("../types").IFieldSubType | undefined; + subType: import("../..").IFieldSubType | undefined; customLabel: string | undefined; }; ``` @@ -37,7 +37,7 @@ toJSON(): { searchable: boolean; aggregatable: boolean; readFromDocValues: boolean; - subType: import("../types").IFieldSubType | undefined; + subType: import("../..").IFieldSubType | undefined; customLabel: string | undefined; }` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.esfilters.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.esfilters.md index d009cad9ec601..594afcf9ee0dd 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.esfilters.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.esfilters.md @@ -11,11 +11,11 @@ esFilters: { buildQueryFilter: (query: any, index: string, alias: string) => import("../common").QueryStringFilter; buildCustomFilter: typeof buildCustomFilter; buildEmptyFilter: (isPinned: boolean, index?: string | undefined) => import("../common").Filter; - buildExistsFilter: (field: import("../common").IFieldType, indexPattern: import("../common").IndexPatternBase) => import("../common").ExistsFilter; + buildExistsFilter: (field: import("../common").IndexPatternFieldBase, indexPattern: import("../common").IndexPatternBase) => import("../common").ExistsFilter; buildFilter: typeof buildFilter; - buildPhraseFilter: (field: import("../common").IFieldType, value: any, indexPattern: import("../common").IndexPatternBase) => import("../common").PhraseFilter; - buildPhrasesFilter: (field: import("../common").IFieldType, params: any[], indexPattern: import("../common").IndexPatternBase) => import("../common").PhrasesFilter; - buildRangeFilter: (field: import("../common").IFieldType, params: import("../common").RangeFilterParams, indexPattern: import("../common").IndexPatternBase, formattedValue?: string | undefined) => import("../common").RangeFilter; + buildPhraseFilter: (field: import("../common").IndexPatternFieldBase, value: any, indexPattern: import("../common").IndexPatternBase) => import("../common").PhraseFilter; + buildPhrasesFilter: (field: import("../common").IndexPatternFieldBase, params: any[], indexPattern: import("../common").IndexPatternBase) => import("../common").PhrasesFilter; + buildRangeFilter: (field: import("../common").IndexPatternFieldBase, params: import("../common").RangeFilterParams, indexPattern: import("../common").IndexPatternBase, formattedValue?: string | undefined) => import("../common").RangeFilter; isFilterDisabled: (filter: import("../common").Filter) => boolean; } ``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.lang.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.lang.md deleted file mode 100644 index 3d5a757cb8f18..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.lang.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IFieldType](./kibana-plugin-plugins-data-server.ifieldtype.md) > [lang](./kibana-plugin-plugins-data-server.ifieldtype.lang.md) - -## IFieldType.lang property - -Signature: - -```typescript -lang?: estypes.ScriptLanguage; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.md index bbc4cc2135d40..9f14bedf92008 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.md @@ -12,7 +12,7 @@ Signature: ```typescript -export interface IFieldType +export interface IFieldType extends IndexPatternFieldBase ``` ## Properties @@ -26,15 +26,9 @@ export interface IFieldType | [esTypes](./kibana-plugin-plugins-data-server.ifieldtype.estypes.md) | string[] | | | [filterable](./kibana-plugin-plugins-data-server.ifieldtype.filterable.md) | boolean | | | [format](./kibana-plugin-plugins-data-server.ifieldtype.format.md) | any | | -| [lang](./kibana-plugin-plugins-data-server.ifieldtype.lang.md) | estypes.ScriptLanguage | | -| [name](./kibana-plugin-plugins-data-server.ifieldtype.name.md) | string | | | [readFromDocValues](./kibana-plugin-plugins-data-server.ifieldtype.readfromdocvalues.md) | boolean | | -| [script](./kibana-plugin-plugins-data-server.ifieldtype.script.md) | string | | -| [scripted](./kibana-plugin-plugins-data-server.ifieldtype.scripted.md) | boolean | | | [searchable](./kibana-plugin-plugins-data-server.ifieldtype.searchable.md) | boolean | | | [sortable](./kibana-plugin-plugins-data-server.ifieldtype.sortable.md) | boolean | | -| [subType](./kibana-plugin-plugins-data-server.ifieldtype.subtype.md) | IFieldSubType | | | [toSpec](./kibana-plugin-plugins-data-server.ifieldtype.tospec.md) | (options?: {
getFormatterForField?: IndexPattern['getFormatterForField'];
}) => FieldSpec | | -| [type](./kibana-plugin-plugins-data-server.ifieldtype.type.md) | string | | | [visualizable](./kibana-plugin-plugins-data-server.ifieldtype.visualizable.md) | boolean | | diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.name.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.name.md deleted file mode 100644 index 8be33a3f56d97..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.name.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IFieldType](./kibana-plugin-plugins-data-server.ifieldtype.md) > [name](./kibana-plugin-plugins-data-server.ifieldtype.name.md) - -## IFieldType.name property - -Signature: - -```typescript -name: string; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.script.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.script.md deleted file mode 100644 index b54a952a11253..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.script.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IFieldType](./kibana-plugin-plugins-data-server.ifieldtype.md) > [script](./kibana-plugin-plugins-data-server.ifieldtype.script.md) - -## IFieldType.script property - -Signature: - -```typescript -script?: string; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.scripted.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.scripted.md deleted file mode 100644 index f7a8ed9aee0df..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.scripted.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IFieldType](./kibana-plugin-plugins-data-server.ifieldtype.md) > [scripted](./kibana-plugin-plugins-data-server.ifieldtype.scripted.md) - -## IFieldType.scripted property - -Signature: - -```typescript -scripted?: boolean; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.subtype.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.subtype.md deleted file mode 100644 index fa78b23a2b558..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.subtype.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IFieldType](./kibana-plugin-plugins-data-server.ifieldtype.md) > [subType](./kibana-plugin-plugins-data-server.ifieldtype.subtype.md) - -## IFieldType.subType property - -Signature: - -```typescript -subType?: IFieldSubType; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.type.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.type.md deleted file mode 100644 index ef6a4dcc167c5..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.ifieldtype.type.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [IFieldType](./kibana-plugin-plugins-data-server.ifieldtype.md) > [type](./kibana-plugin-plugins-data-server.ifieldtype.type.md) - -## IFieldType.type property - -Signature: - -```typescript -type: string; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getaggregationrestrictions.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getaggregationrestrictions.md index b655e779e4fa4..70a3da86e9fbd 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getaggregationrestrictions.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.indexpattern.getaggregationrestrictions.md @@ -9,7 +9,9 @@ ```typescript getAggregationRestrictions(): Record field.name === filter.meta.key); + return indexPattern.fields.some((field) => field.name === filter.meta.key); } diff --git a/src/plugins/data/common/es_query/es_query/handle_nested_filter.test.ts b/src/plugins/data/common/es_query/es_query/handle_nested_filter.test.ts index d312d034df564..24852ebf33bda 100644 --- a/src/plugins/data/common/es_query/es_query/handle_nested_filter.test.ts +++ b/src/plugins/data/common/es_query/es_query/handle_nested_filter.test.ts @@ -10,7 +10,6 @@ import { handleNestedFilter } from './handle_nested_filter'; import { fields } from '../../index_patterns/mocks'; import { buildPhraseFilter, buildQueryFilter } from '../filters'; import { IndexPatternBase } from './types'; -import { IFieldType } from '../../index_patterns'; describe('handleNestedFilter', function () { const indexPattern: IndexPatternBase = { @@ -45,8 +44,12 @@ describe('handleNestedFilter', function () { }); it('should return filter untouched if it does not target a field from the given index pattern', () => { - const field = { ...getField('extension'), name: 'notarealfield' }; - const filter = buildPhraseFilter(field as IFieldType, 'jpg', indexPattern); + const field = getField('extension'); + const unrealField = { + ...field!, + name: 'notarealfield', + }; + const filter = buildPhraseFilter(unrealField, 'jpg', indexPattern); const result = handleNestedFilter(filter, indexPattern); expect(result).toBe(filter); }); diff --git a/src/plugins/data/common/es_query/es_query/index.ts b/src/plugins/data/common/es_query/es_query/index.ts index c10ea5846ae3f..ecc7c8ba5a9f5 100644 --- a/src/plugins/data/common/es_query/es_query/index.ts +++ b/src/plugins/data/common/es_query/es_query/index.ts @@ -11,4 +11,4 @@ export { buildQueryFromFilters } from './from_filters'; export { luceneStringToDsl } from './lucene_string_to_dsl'; export { decorateQuery } from './decorate_query'; export { getEsQueryConfig } from './get_es_query_config'; -export { IndexPatternBase } from './types'; +export { IndexPatternBase, IndexPatternFieldBase, IFieldSubType } from './types'; diff --git a/src/plugins/data/common/es_query/es_query/types.ts b/src/plugins/data/common/es_query/es_query/types.ts index 2133736516049..9282072cd444d 100644 --- a/src/plugins/data/common/es_query/es_query/types.ts +++ b/src/plugins/data/common/es_query/es_query/types.ts @@ -6,9 +6,32 @@ * Side Public License, v 1. */ -import { IFieldType } from '../../index_patterns'; +import type { estypes } from '@elastic/elasticsearch'; + +export interface IFieldSubType { + multi?: { parent: string }; + nested?: { path: string }; +} +export interface IndexPatternFieldBase { + name: string; + /** + * Kibana field type + */ + type: string; + subType?: IFieldSubType; + /** + * Scripted field painless script + */ + script?: string; + /** + * Scripted field langauge + * Painless is the only valid scripted field language + */ + lang?: estypes.ScriptLanguage; + scripted?: boolean; +} export interface IndexPatternBase { - fields: IFieldType[]; + fields: IndexPatternFieldBase[]; id?: string; } diff --git a/src/plugins/data/common/es_query/filters/build_filters.ts b/src/plugins/data/common/es_query/filters/build_filters.ts index 369f9530fb92b..1d8d67b6e937f 100644 --- a/src/plugins/data/common/es_query/filters/build_filters.ts +++ b/src/plugins/data/common/es_query/filters/build_filters.ts @@ -6,7 +6,8 @@ * Side Public License, v 1. */ -import { IFieldType, IndexPatternBase } from '../..'; +import { IndexPatternFieldBase, IndexPatternBase } from '../..'; + import { Filter, FILTERS, @@ -20,7 +21,7 @@ import { export function buildFilter( indexPattern: IndexPatternBase, - field: IFieldType, + field: IndexPatternFieldBase, type: FILTERS, negate: boolean, disabled: boolean, @@ -60,7 +61,7 @@ export function buildCustomFilter( function buildBaseFilter( indexPattern: IndexPatternBase, - field: IFieldType, + field: IndexPatternFieldBase, type: FILTERS, params: any ): Filter { diff --git a/src/plugins/data/common/es_query/filters/exists_filter.ts b/src/plugins/data/common/es_query/filters/exists_filter.ts index 4836950c3bb27..7a09adb7d9ed6 100644 --- a/src/plugins/data/common/es_query/filters/exists_filter.ts +++ b/src/plugins/data/common/es_query/filters/exists_filter.ts @@ -7,8 +7,7 @@ */ import { Filter, FilterMeta } from './meta_filter'; -import { IFieldType } from '../../index_patterns'; -import { IndexPatternBase } from '..'; +import { IndexPatternFieldBase, IndexPatternBase } from '..'; export type ExistsFilterMeta = FilterMeta; @@ -27,7 +26,7 @@ export const getExistsFilterField = (filter: ExistsFilter) => { return filter.exists && filter.exists.field; }; -export const buildExistsFilter = (field: IFieldType, indexPattern: IndexPatternBase) => { +export const buildExistsFilter = (field: IndexPatternFieldBase, indexPattern: IndexPatternBase) => { return { meta: { index: indexPattern.id, diff --git a/src/plugins/data/common/es_query/filters/phrase_filter.ts b/src/plugins/data/common/es_query/filters/phrase_filter.ts index 27c1e85562097..68ad16cb31d42 100644 --- a/src/plugins/data/common/es_query/filters/phrase_filter.ts +++ b/src/plugins/data/common/es_query/filters/phrase_filter.ts @@ -8,8 +8,7 @@ import type { estypes } from '@elastic/elasticsearch'; import { get, isPlainObject } from 'lodash'; import { Filter, FilterMeta } from './meta_filter'; -import { IFieldType } from '../../index_patterns'; -import { IndexPatternBase } from '..'; +import { IndexPatternFieldBase, IndexPatternBase } from '..'; export type PhraseFilterMeta = FilterMeta & { params?: { @@ -59,7 +58,7 @@ export const getPhraseFilterValue = (filter: PhraseFilter): PhraseFilterValue => }; export const buildPhraseFilter = ( - field: IFieldType, + field: IndexPatternFieldBase, value: any, indexPattern: IndexPatternBase ): PhraseFilter => { @@ -82,7 +81,7 @@ export const buildPhraseFilter = ( } }; -export const getPhraseScript = (field: IFieldType, value: string) => { +export const getPhraseScript = (field: IndexPatternFieldBase, value: string) => { const convertedValue = getConvertedValueForField(field, value); const script = buildInlineScriptForPhraseFilter(field); @@ -106,7 +105,7 @@ export const getPhraseScript = (field: IFieldType, value: string) => { * https://github.com/elastic/elasticsearch/issues/20941 * https://github.com/elastic/elasticsearch/pull/22201 **/ -export const getConvertedValueForField = (field: IFieldType, value: any) => { +export const getConvertedValueForField = (field: IndexPatternFieldBase, value: any) => { if (typeof value !== 'boolean' && field.type === 'boolean') { if ([1, 'true'].includes(value)) { return true; diff --git a/src/plugins/data/common/es_query/filters/phrases_filter.ts b/src/plugins/data/common/es_query/filters/phrases_filter.ts index 2694461fc1930..7f7831e1c7978 100644 --- a/src/plugins/data/common/es_query/filters/phrases_filter.ts +++ b/src/plugins/data/common/es_query/filters/phrases_filter.ts @@ -9,8 +9,7 @@ import { Filter, FilterMeta } from './meta_filter'; import { getPhraseScript } from './phrase_filter'; import { FILTERS } from './index'; -import { IFieldType } from '../../index_patterns'; -import { IndexPatternBase } from '../es_query'; +import { IndexPatternFieldBase, IndexPatternBase } from '../es_query'; export type PhrasesFilterMeta = FilterMeta & { params: string[]; // The unformatted values @@ -33,7 +32,7 @@ export const getPhrasesFilterField = (filter: PhrasesFilter) => { // Creates a filter where the given field matches one or more of the given values // params should be an array of values export const buildPhrasesFilter = ( - field: IFieldType, + field: IndexPatternFieldBase, params: any[], indexPattern: IndexPatternBase ) => { diff --git a/src/plugins/data/common/es_query/filters/range_filter.test.ts b/src/plugins/data/common/es_query/filters/range_filter.test.ts index bb7ecc09ebc34..30e52b21d52b7 100644 --- a/src/plugins/data/common/es_query/filters/range_filter.test.ts +++ b/src/plugins/data/common/es_query/filters/range_filter.test.ts @@ -9,15 +9,15 @@ import { each } from 'lodash'; import { buildRangeFilter, getRangeFilterField, RangeFilter } from './range_filter'; import { fields, getField } from '../../index_patterns/mocks'; -import { IIndexPattern, IFieldType } from '../../index_patterns'; +import { IndexPatternBase, IndexPatternFieldBase } from '../es_query'; describe('Range filter builder', () => { - let indexPattern: IIndexPattern; + let indexPattern: IndexPatternBase; beforeEach(() => { indexPattern = { id: 'id', - } as IIndexPattern; + } as IndexPatternBase; }); it('should be a function', () => { @@ -130,7 +130,7 @@ describe('Range filter builder', () => { }); describe('when given params where one side is infinite', () => { - let field: IFieldType; + let field: IndexPatternFieldBase; let filter: RangeFilter; beforeEach(() => { @@ -160,7 +160,7 @@ describe('Range filter builder', () => { }); describe('when given params where both sides are infinite', () => { - let field: IFieldType; + let field: IndexPatternFieldBase; let filter: RangeFilter; beforeEach(() => { @@ -186,9 +186,9 @@ describe('Range filter builder', () => { }); describe('getRangeFilterField', function () { - const indexPattern: IIndexPattern = ({ + const indexPattern: IndexPatternBase = ({ fields, - } as unknown) as IIndexPattern; + } as unknown) as IndexPatternBase; test('should return the name of the field a range query is targeting', () => { const field = indexPattern.fields.find((patternField) => patternField.name === 'bytes'); diff --git a/src/plugins/data/common/es_query/filters/range_filter.ts b/src/plugins/data/common/es_query/filters/range_filter.ts index 9f1d9a5d08926..e44e23f64936e 100644 --- a/src/plugins/data/common/es_query/filters/range_filter.ts +++ b/src/plugins/data/common/es_query/filters/range_filter.ts @@ -8,8 +8,7 @@ import type { estypes } from '@elastic/elasticsearch'; import { map, reduce, mapValues, get, keys, pickBy } from 'lodash'; import { Filter, FilterMeta } from './meta_filter'; -import { IFieldType } from '../../index_patterns'; -import { IndexPatternBase } from '..'; +import { IndexPatternBase, IndexPatternFieldBase } from '..'; const OPERANDS_IN_RANGE = 2; @@ -83,13 +82,13 @@ export const getRangeFilterField = (filter: RangeFilter) => { return filter.range && Object.keys(filter.range)[0]; }; -const formatValue = (field: IFieldType, params: any[]) => +const formatValue = (params: any[]) => map(params, (val: any, key: string) => get(operators, key) + val).join(' '); // Creates a filter where the value for the given field is in the given range // params should be an object containing `lt`, `lte`, `gt`, and/or `gte` export const buildRangeFilter = ( - field: IFieldType, + field: IndexPatternFieldBase, params: RangeFilterParams, indexPattern: IndexPatternBase, formattedValue?: string @@ -124,7 +123,7 @@ export const buildRangeFilter = ( filter.meta.field = field.name; } else if (field.scripted) { filter.script = getRangeScript(field, params); - filter.script.script.params.value = formatValue(field, filter.script.script.params); + filter.script.script.params.value = formatValue(filter.script.script.params); filter.meta.field = field.name; } else { @@ -135,7 +134,7 @@ export const buildRangeFilter = ( return filter as RangeFilter; }; -export const getRangeScript = (field: IFieldType, params: RangeFilterParams) => { +export const getRangeScript = (field: IndexPatternFieldBase, params: RangeFilterParams) => { const knownParams = mapValues( pickBy(params, (val, key: any) => key in operators), (value) => (field.type === 'number' && typeof value === 'string' ? parseFloat(value) : value) diff --git a/src/plugins/data/common/es_query/kuery/functions/exists.ts b/src/plugins/data/common/es_query/kuery/functions/exists.ts index fa6c37e6ba18f..4df566d874d8b 100644 --- a/src/plugins/data/common/es_query/kuery/functions/exists.ts +++ b/src/plugins/data/common/es_query/kuery/functions/exists.ts @@ -6,9 +6,8 @@ * Side Public License, v 1. */ -import { get } from 'lodash'; import * as literal from '../node_types/literal'; -import { KueryNode, IFieldType, IndexPatternBase } from '../../..'; +import { KueryNode, IndexPatternFieldBase, IndexPatternBase } from '../../..'; export function buildNodeParams(fieldName: string) { return { @@ -30,9 +29,9 @@ export function toElasticsearchQuery( value: context?.nested ? `${context.nested.path}.${fieldNameArg.value}` : fieldNameArg.value, }; const fieldName = literal.toElasticsearchQuery(fullFieldNameArg); - const field = get(indexPattern, 'fields', []).find((fld: IFieldType) => fld.name === fieldName); + const field = indexPattern?.fields?.find((fld: IndexPatternFieldBase) => fld.name === fieldName); - if (field && (field as IFieldType).scripted) { + if (field?.scripted) { throw new Error(`Exists query does not support scripted fields`); } return { diff --git a/src/plugins/data/common/es_query/kuery/functions/geo_bounding_box.ts b/src/plugins/data/common/es_query/kuery/functions/geo_bounding_box.ts index 38a433b1b80ab..79bef10b14f71 100644 --- a/src/plugins/data/common/es_query/kuery/functions/geo_bounding_box.ts +++ b/src/plugins/data/common/es_query/kuery/functions/geo_bounding_box.ts @@ -9,7 +9,7 @@ import _ from 'lodash'; import { nodeTypes } from '../node_types'; import * as ast from '../ast'; -import { IndexPatternBase, KueryNode, IFieldType, LatLon } from '../../..'; +import { IndexPatternBase, KueryNode, LatLon } from '../../..'; export function buildNodeParams(fieldName: string, params: any) { params = _.pick(params, 'topLeft', 'bottomRight'); @@ -36,8 +36,8 @@ export function toElasticsearchQuery( value: context?.nested ? `${context.nested.path}.${fieldNameArg.value}` : fieldNameArg.value, }; const fieldName = nodeTypes.literal.toElasticsearchQuery(fullFieldNameArg) as string; - const fieldList: IFieldType[] = indexPattern?.fields ?? []; - const field = fieldList.find((fld: IFieldType) => fld.name === fieldName); + const fieldList = indexPattern?.fields ?? []; + const field = fieldList.find((fld) => fld.name === fieldName); const queryParams = args.reduce((acc: any, arg: any) => { const snakeArgName = _.snakeCase(arg.name); diff --git a/src/plugins/data/common/es_query/kuery/functions/geo_polygon.ts b/src/plugins/data/common/es_query/kuery/functions/geo_polygon.ts index 69de7248a7b38..2e3280138502a 100644 --- a/src/plugins/data/common/es_query/kuery/functions/geo_polygon.ts +++ b/src/plugins/data/common/es_query/kuery/functions/geo_polygon.ts @@ -8,7 +8,7 @@ import { nodeTypes } from '../node_types'; import * as ast from '../ast'; -import { IndexPatternBase, KueryNode, IFieldType, LatLon } from '../../..'; +import { IndexPatternBase, KueryNode, LatLon } from '../../..'; import { LiteralTypeBuildNode } from '../node_types/types'; export function buildNodeParams(fieldName: string, points: LatLon[]) { @@ -35,8 +35,8 @@ export function toElasticsearchQuery( value: context?.nested ? `${context.nested.path}.${fieldNameArg.value}` : fieldNameArg.value, }; const fieldName = nodeTypes.literal.toElasticsearchQuery(fullFieldNameArg) as string; - const fieldList: IFieldType[] = indexPattern?.fields ?? []; - const field = fieldList.find((fld: IFieldType) => fld.name === fieldName); + const fieldList = indexPattern?.fields ?? []; + const field = fieldList.find((fld) => fld.name === fieldName); const queryParams = { points: points.map((point: LiteralTypeBuildNode) => { return ast.toElasticsearchQuery(point, indexPattern, config, context); diff --git a/src/plugins/data/common/es_query/kuery/functions/is.ts b/src/plugins/data/common/es_query/kuery/functions/is.ts index 55d036c2156f9..381913670c26a 100644 --- a/src/plugins/data/common/es_query/kuery/functions/is.ts +++ b/src/plugins/data/common/es_query/kuery/functions/is.ts @@ -11,7 +11,7 @@ import { getPhraseScript } from '../../filters'; import { getFields } from './utils/get_fields'; import { getTimeZoneFromSettings } from '../../utils'; import { getFullFieldNameNode } from './utils/get_full_field_name_node'; -import { IndexPatternBase, KueryNode, IFieldType } from '../../..'; +import { IndexPatternBase, KueryNode, IndexPatternFieldBase } from '../../..'; import * as ast from '../ast'; @@ -100,7 +100,7 @@ export function toElasticsearchQuery( return { match_all: {} }; } - const queries = fields!.reduce((accumulator: any, field: IFieldType) => { + const queries = fields!.reduce((accumulator: any, field: IndexPatternFieldBase) => { const wrapWithNestedQuery = (query: any) => { // Wildcards can easily include nested and non-nested fields. There isn't a good way to let // users handle this themselves so we automatically add nested queries in this scenario. diff --git a/src/plugins/data/common/es_query/kuery/functions/range.ts b/src/plugins/data/common/es_query/kuery/functions/range.ts index caefa7e5373ca..b134434dc182b 100644 --- a/src/plugins/data/common/es_query/kuery/functions/range.ts +++ b/src/plugins/data/common/es_query/kuery/functions/range.ts @@ -13,7 +13,7 @@ import { getRangeScript, RangeFilterParams } from '../../filters'; import { getFields } from './utils/get_fields'; import { getTimeZoneFromSettings } from '../../utils'; import { getFullFieldNameNode } from './utils/get_full_field_name_node'; -import { IndexPatternBase, KueryNode, IFieldType } from '../../..'; +import { IndexPatternBase, KueryNode } from '../../..'; export function buildNodeParams(fieldName: string, params: RangeFilterParams) { const paramsToMap = _.pick(params, 'gt', 'lt', 'gte', 'lte', 'format'); @@ -62,7 +62,7 @@ export function toElasticsearchQuery( }); } - const queries = fields!.map((field: IFieldType) => { + const queries = fields!.map((field) => { const wrapWithNestedQuery = (query: any) => { // Wildcards can easily include nested and non-nested fields. There isn't a good way to let // users handle this themselves so we automatically add nested queries in this scenario. diff --git a/src/plugins/data/common/es_query/kuery/functions/utils/get_fields.test.ts b/src/plugins/data/common/es_query/kuery/functions/utils/get_fields.test.ts index 47fe677454cbf..949f94d043553 100644 --- a/src/plugins/data/common/es_query/kuery/functions/utils/get_fields.test.ts +++ b/src/plugins/data/common/es_query/kuery/functions/utils/get_fields.test.ts @@ -6,21 +6,21 @@ * Side Public License, v 1. */ +import { IndexPatternBase } from '../../..'; import { fields } from '../../../../index_patterns/mocks'; import { nodeTypes } from '../../index'; -import { IIndexPattern, IFieldType } from '../../../../index_patterns'; // @ts-ignore import { getFields } from './get_fields'; describe('getFields', () => { - let indexPattern: IIndexPattern; + let indexPattern: IndexPatternBase; beforeEach(() => { indexPattern = ({ fields, - } as unknown) as IIndexPattern; + } as unknown) as IndexPatternBase; }); describe('field names without a wildcard', () => { @@ -41,14 +41,14 @@ describe('getFields', () => { }); test('should not match a wildcard in a literal node', () => { - const indexPatternWithWildField = { + const indexPatternWithWildField: IndexPatternBase = ({ title: 'wildIndex', fields: [ { name: 'foo*', }, ], - } as IIndexPattern; + } as unknown) as IndexPatternBase; const fieldNameNode = nodeTypes.literal.buildNode('foo*'); const results = getFields(fieldNameNode, indexPatternWithWildField); @@ -76,8 +76,8 @@ describe('getFields', () => { expect(Array.isArray(results)).toBeTruthy(); expect(results).toHaveLength(2); - expect(results!.find((field: IFieldType) => field.name === 'machine.os')).toBeDefined(); - expect(results!.find((field: IFieldType) => field.name === 'machine.os.raw')).toBeDefined(); + expect(results!.find((field) => field.name === 'machine.os')).toBeDefined(); + expect(results!.find((field) => field.name === 'machine.os.raw')).toBeDefined(); }); }); }); diff --git a/src/plugins/data/common/es_query/kuery/functions/utils/get_full_field_name_node.ts b/src/plugins/data/common/es_query/kuery/functions/utils/get_full_field_name_node.ts index 644791637aa70..2a31ebeee2fab 100644 --- a/src/plugins/data/common/es_query/kuery/functions/utils/get_full_field_name_node.ts +++ b/src/plugins/data/common/es_query/kuery/functions/utils/get_full_field_name_node.ts @@ -7,7 +7,7 @@ */ import { getFields } from './get_fields'; -import { IndexPatternBase, IFieldType, KueryNode } from '../../../..'; +import { IndexPatternBase, IndexPatternFieldBase, KueryNode } from '../../../..'; export function getFullFieldNameNode( rootNameNode: any, @@ -27,7 +27,7 @@ export function getFullFieldNameNode( } const fields = getFields(fullFieldNameNode, indexPattern); - const errors = fields!.reduce((acc: any, field: IFieldType) => { + const errors = fields!.reduce((acc: any, field: IndexPatternFieldBase) => { const nestedPathFromField = field.subType && field.subType.nested ? field.subType.nested.path : undefined; diff --git a/src/plugins/data/common/index_patterns/fields/types.ts b/src/plugins/data/common/index_patterns/fields/types.ts index 0fb7a46c2cf73..3b2e25d3d80a6 100644 --- a/src/plugins/data/common/index_patterns/fields/types.ts +++ b/src/plugins/data/common/index_patterns/fields/types.ts @@ -5,18 +5,13 @@ * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ -import type { estypes } from '@elastic/elasticsearch'; -import { FieldSpec, IFieldSubType, IndexPattern } from '../..'; +import { IndexPatternFieldBase, FieldSpec, IndexPattern } from '../..'; /** * @deprecated * Use IndexPatternField or FieldSpec instead */ -export interface IFieldType { - name: string; - type: string; - script?: string; - lang?: estypes.ScriptLanguage; +export interface IFieldType extends IndexPatternFieldBase { count?: number; // esTypes might be undefined on old index patterns that have not been refreshed since we added // this prop. It is also undefined on scripted fields. @@ -27,8 +22,6 @@ export interface IFieldType { sortable?: boolean; visualizable?: boolean; readFromDocValues?: boolean; - scripted?: boolean; - subType?: IFieldSubType; displayName?: string; customLabel?: string; format?: any; diff --git a/src/plugins/data/common/index_patterns/types.ts b/src/plugins/data/common/index_patterns/types.ts index a88f029c0c7cd..b03e745df74a6 100644 --- a/src/plugins/data/common/index_patterns/types.ts +++ b/src/plugins/data/common/index_patterns/types.ts @@ -9,7 +9,7 @@ import type { estypes } from '@elastic/elasticsearch'; import { ToastInputFields, ErrorToastOptions } from 'src/core/public/notifications'; // eslint-disable-next-line import type { SavedObject } from 'src/core/server'; -import type { IndexPatternBase } from '../es_query'; +import type { IndexPatternFieldBase, IFieldSubType, IndexPatternBase } from '../es_query'; import { IFieldType } from './fields'; import { RUNTIME_FIELD_TYPES } from './constants'; import { SerializedFieldFormat } from '../../../expressions/common'; @@ -32,6 +32,7 @@ export interface RuntimeField { */ export interface IIndexPattern extends IndexPatternBase { title: string; + fields: IFieldType[]; /** * Type is used for identifying rollup indices, otherwise left undefined */ @@ -149,12 +150,6 @@ export type AggregationRestrictions = Record< time_zone?: string; } >; - -export interface IFieldSubType { - multi?: { parent: string }; - nested?: { path: string }; -} - export interface TypeMeta { aggs?: Record; [key: string]: any; @@ -183,30 +178,17 @@ export interface FieldSpecExportFmt { /** * Serialized version of IndexPatternField */ -export interface FieldSpec { +export interface FieldSpec extends IndexPatternFieldBase { /** * Popularity count is used by discover */ count?: number; - /** - * Scripted field painless script - */ - script?: string; - /** - * Scripted field langauge - * Painless is the only valid scripted field language - */ - lang?: estypes.ScriptLanguage; conflictDescriptions?: Record; format?: SerializedFieldFormat; - name: string; - type: string; esTypes?: string[]; - scripted?: boolean; searchable: boolean; aggregatable: boolean; readFromDocValues?: boolean; - subType?: IFieldSubType; indexed?: boolean; customLabel?: string; runtimeField?: RuntimeField; diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index 6a49fab0e33ff..35094fac1cc0f 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -808,11 +808,11 @@ export const esFilters: { FILTERS: typeof FILTERS; FilterStateStore: typeof FilterStateStore; buildEmptyFilter: (isPinned: boolean, index?: string | undefined) => import("../common").Filter; - buildPhrasesFilter: (field: import("../common").IFieldType, params: any[], indexPattern: import("../common").IndexPatternBase) => import("../common").PhrasesFilter; - buildExistsFilter: (field: import("../common").IFieldType, indexPattern: import("../common").IndexPatternBase) => import("../common").ExistsFilter; - buildPhraseFilter: (field: import("../common").IFieldType, value: any, indexPattern: import("../common").IndexPatternBase) => import("../common").PhraseFilter; + buildPhrasesFilter: (field: import("../common").IndexPatternFieldBase, params: any[], indexPattern: import("../common").IndexPatternBase) => import("../common").PhrasesFilter; + buildExistsFilter: (field: import("../common").IndexPatternFieldBase, indexPattern: import("../common").IndexPatternBase) => import("../common").ExistsFilter; + buildPhraseFilter: (field: import("../common").IndexPatternFieldBase, value: any, indexPattern: import("../common").IndexPatternBase) => import("../common").PhraseFilter; buildQueryFilter: (query: any, index: string, alias: string) => import("../common").QueryStringFilter; - buildRangeFilter: (field: import("../common").IFieldType, params: import("../common").RangeFilterParams, indexPattern: import("../common").IndexPatternBase, formattedValue?: string | undefined) => import("../common").RangeFilter; + buildRangeFilter: (field: import("../common").IndexPatternFieldBase, params: import("../common").RangeFilterParams, indexPattern: import("../common").IndexPatternBase, formattedValue?: string | undefined) => import("../common").RangeFilter; isPhraseFilter: (filter: any) => filter is import("../common").PhraseFilter; isExistsFilter: (filter: any) => filter is import("../common").ExistsFilter; isPhrasesFilter: (filter: any) => filter is import("../common").PhrasesFilter; @@ -1242,10 +1242,11 @@ export interface IFieldSubType { }; } +// Warning: (ae-forgotten-export) The symbol "IndexPatternFieldBase" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "IFieldType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) -export interface IFieldType { +export interface IFieldType extends IndexPatternFieldBase { // (undocumented) aggregatable?: boolean; // (undocumented) @@ -1261,28 +1262,16 @@ export interface IFieldType { // (undocumented) format?: any; // (undocumented) - lang?: estypes.ScriptLanguage; - // (undocumented) - name: string; - // (undocumented) readFromDocValues?: boolean; // (undocumented) - script?: string; - // (undocumented) - scripted?: boolean; - // (undocumented) searchable?: boolean; // (undocumented) sortable?: boolean; // (undocumented) - subType?: IFieldSubType; - // (undocumented) toSpec?: (options?: { getFormatterForField?: IndexPattern['getFormatterForField']; }) => FieldSpec; // (undocumented) - type: string; - // (undocumented) visualizable?: boolean; } @@ -1295,6 +1284,8 @@ export interface IIndexPattern extends IndexPatternBase { // // (undocumented) fieldFormatMap?: Record | undefined>; + // (undocumented) + fields: IFieldType[]; getFormatterForField?: (field: IndexPatternField | IndexPatternField['spec'] | IFieldType) => FieldFormat; // (undocumented) getTimeField?(): IFieldType | undefined; @@ -1394,7 +1385,9 @@ export class IndexPattern implements IIndexPattern { // (undocumented) getAggregationRestrictions(): Record import("../common").QueryStringFilter; buildCustomFilter: typeof buildCustomFilter; buildEmptyFilter: (isPinned: boolean, index?: string | undefined) => import("../common").Filter; - buildExistsFilter: (field: import("../common").IFieldType, indexPattern: import("../common").IndexPatternBase) => import("../common").ExistsFilter; + buildExistsFilter: (field: import("../common").IndexPatternFieldBase, indexPattern: import("../common").IndexPatternBase) => import("../common").ExistsFilter; buildFilter: typeof buildFilter; - buildPhraseFilter: (field: import("../common").IFieldType, value: any, indexPattern: import("../common").IndexPatternBase) => import("../common").PhraseFilter; - buildPhrasesFilter: (field: import("../common").IFieldType, params: any[], indexPattern: import("../common").IndexPatternBase) => import("../common").PhrasesFilter; - buildRangeFilter: (field: import("../common").IFieldType, params: import("../common").RangeFilterParams, indexPattern: import("../common").IndexPatternBase, formattedValue?: string | undefined) => import("../common").RangeFilter; + buildPhraseFilter: (field: import("../common").IndexPatternFieldBase, value: any, indexPattern: import("../common").IndexPatternBase) => import("../common").PhraseFilter; + buildPhrasesFilter: (field: import("../common").IndexPatternFieldBase, params: any[], indexPattern: import("../common").IndexPatternBase) => import("../common").PhrasesFilter; + buildRangeFilter: (field: import("../common").IndexPatternFieldBase, params: import("../common").RangeFilterParams, indexPattern: import("../common").IndexPatternBase, formattedValue?: string | undefined) => import("../common").RangeFilter; isFilterDisabled: (filter: import("../common").Filter) => boolean; }; @@ -693,10 +693,11 @@ export interface IFieldSubType { }; } +// Warning: (ae-forgotten-export) The symbol "IndexPatternFieldBase" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "IFieldType" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public @deprecated (undocumented) -export interface IFieldType { +export interface IFieldType extends IndexPatternFieldBase { // (undocumented) aggregatable?: boolean; // (undocumented) @@ -712,21 +713,11 @@ export interface IFieldType { // (undocumented) format?: any; // (undocumented) - lang?: estypes.ScriptLanguage; - // (undocumented) - name: string; - // (undocumented) readFromDocValues?: boolean; // (undocumented) - script?: string; - // (undocumented) - scripted?: boolean; - // (undocumented) searchable?: boolean; // (undocumented) sortable?: boolean; - // (undocumented) - subType?: IFieldSubType; // Warning: (ae-forgotten-export) The symbol "FieldSpec" needs to be exported by the entry point index.d.ts // // (undocumented) @@ -734,8 +725,6 @@ export interface IFieldType { getFormatterForField?: IndexPattern['getFormatterForField']; }) => FieldSpec; // (undocumented) - type: string; - // (undocumented) visualizable?: boolean; } @@ -780,7 +769,9 @@ export class IndexPattern implements IIndexPattern { // (undocumented) getAggregationRestrictions(): Record Date: Wed, 30 Jun 2021 15:43:18 +0300 Subject: [PATCH 6/9] [TSVB] Metric count is depicted as `-` instead of 0 (#103717) * [TSVB] Metric count is depicted as - instead of 0 * Rename extractData to mapEmptyToZero and remove unnecessary intervalString undefined assignment in get_bucket_size.js Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../lib/vis_data/helpers/get_bucket_size.js | 2 - .../server/lib/vis_data/helpers/index.js | 2 +- .../server/lib/vis_data/helpers/map_bucket.js | 13 ----- ...cket.test.js => map_empty_to_zero.test.ts} | 52 +++++++++++-------- .../lib/vis_data/helpers/map_empty_to_zero.ts | 25 +++++++++ .../response_processors/series/math.js | 7 +-- .../response_processors/series/std_metric.js | 7 +-- .../response_processors/table/std_metric.js | 6 +-- 8 files changed, 62 insertions(+), 52 deletions(-) delete mode 100644 src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_bucket.js rename src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/{map_bucket.test.js => map_empty_to_zero.test.ts} (53%) create mode 100644 src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_empty_to_zero.ts diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_bucket_size.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_bucket_size.js index b9ce76f7176b4..ad20f434bedf5 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_bucket_size.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/get_bucket_size.js @@ -45,8 +45,6 @@ const calculateBucketData = (timeInterval, capabilities) => { if (converted) { intervalString = converted.value + converted.unit; } - - intervalString = undefined; } else { intervalString = '1ms'; } diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/index.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/index.js index de93ff22fa598..e2211e4843bd6 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/index.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/index.js @@ -15,6 +15,6 @@ export { getLastMetric } from './get_last_metric'; export { getSiblingAggValue } from './get_sibling_agg_value'; export { getSplits } from './get_splits'; export { getTimerange } from './get_timerange'; -export { mapBucket } from './map_bucket'; export { parseSettings } from './parse_settings'; +export { mapEmptyToZero } from './map_empty_to_zero'; export { overwrite } from './overwrite'; diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_bucket.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_bucket.js deleted file mode 100644 index dd48aa3705d41..0000000000000 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_bucket.js +++ /dev/null @@ -1,13 +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 - * 2.0 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { getAggValue } from './get_agg_value'; - -export function mapBucket(metric) { - return (bucket) => [bucket.key, getAggValue(bucket, metric)]; -} diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_bucket.test.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_empty_to_zero.test.ts similarity index 53% rename from src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_bucket.test.js rename to src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_empty_to_zero.test.ts index 63ba294b7dc46..b5f1adc3f0202 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_bucket.test.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_empty_to_zero.test.ts @@ -6,39 +6,47 @@ * Side Public License, v 1. */ -import { mapBucket } from './map_bucket'; +import { mapEmptyToZero } from './map_empty_to_zero'; -describe('mapBucket(metric)', () => { +describe('mapEmptyToZero(metric, buckets)', () => { test('returns bucket key and value for basic metric', () => { const metric = { id: 'AVG', type: 'avg' }; - const bucket = { - key: 1234, - AVG: { value: 1 }, - }; - expect(mapBucket(metric)(bucket)).toEqual([1234, 1]); + const buckets = [ + { + key: 1234, + AVG: { value: 1 }, + }, + ]; + expect(mapEmptyToZero(metric, buckets)).toEqual([[1234, 1]]); }); test('returns bucket key and value for std_deviation', () => { const metric = { id: 'STDDEV', type: 'std_deviation' }; - const bucket = { - key: 1234, - STDDEV: { std_deviation: 1 }, - }; - expect(mapBucket(metric)(bucket)).toEqual([1234, 1]); + const buckets = [ + { + key: 1234, + STDDEV: { std_deviation: 1 }, + }, + ]; + expect(mapEmptyToZero(metric, buckets)).toEqual([[1234, 1]]); }); test('returns bucket key and value for percentiles', () => { const metric = { id: 'PCT', type: 'percentile', percent: 50 }; - const bucket = { - key: 1234, - PCT: { values: { '50.0': 1 } }, - }; - expect(mapBucket(metric)(bucket)).toEqual([1234, 1]); + const buckets = [ + { + key: 1234, + PCT: { values: { '50.0': 1 } }, + }, + ]; + expect(mapEmptyToZero(metric, buckets)).toEqual([[1234, 1]]); }); test('returns bucket key and value for derivative', () => { const metric = { id: 'DERV', type: 'derivative', field: 'io', unit: '1s' }; - const bucket = { - key: 1234, - DERV: { value: 100, normalized_value: 1 }, - }; - expect(mapBucket(metric)(bucket)).toEqual([1234, 1]); + const buckets = [ + { + key: 1234, + DERV: { value: 100, normalized_value: 1 }, + }, + ]; + expect(mapEmptyToZero(metric, buckets)).toEqual([[1234, 1]]); }); }); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_empty_to_zero.ts b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_empty_to_zero.ts new file mode 100644 index 0000000000000..0490193a76e81 --- /dev/null +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/helpers/map_empty_to_zero.ts @@ -0,0 +1,25 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +// @ts-expect-error not typed yet +import { getAggValue } from './get_agg_value'; +import { METRIC_TYPES } from '../../../../../data/common'; +import type { Metric } from '../../../../common/types'; + +export const mapEmptyToZero = (metric: Metric, buckets: any[]) => { + // Metric types where an empty set equals `zero` + const isSettableToZero = [ + METRIC_TYPES.COUNT, + METRIC_TYPES.CARDINALITY, + METRIC_TYPES.SUM, + ].includes(metric.type as METRIC_TYPES); + + return isSettableToZero && !buckets.length + ? [[undefined, 0]] + : buckets.map((bucket) => [bucket.key, getAggValue(bucket, metric)]); +}; diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.js index d3cff76524ee3..a6addc8ba0e53 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/math.js @@ -10,10 +10,7 @@ import { convertIntervalToUnit } from '../../helpers/unit_to_seconds'; const percentileValueMatch = /\[([0-9\.]+)\]$/; import { startsWith, flatten, values, first, last } from 'lodash'; -import { getDefaultDecoration } from '../../helpers/get_default_decoration'; -import { getSiblingAggValue } from '../../helpers/get_sibling_agg_value'; -import { getSplits } from '../../helpers/get_splits'; -import { mapBucket } from '../../helpers/map_bucket'; +import { getDefaultDecoration, getSiblingAggValue, getSplits, mapEmptyToZero } from '../../helpers'; import { evaluate } from '@kbn/tinymath'; export function mathAgg(resp, panel, series, meta, extractFields) { @@ -44,7 +41,7 @@ export function mathAgg(resp, panel, series, meta, extractFields) { } else { const percentileMatch = v.field.match(percentileValueMatch); const m = percentileMatch ? { ...metric, percent: percentileMatch[1] } : { ...metric }; - acc[v.name] = split.timeseries.buckets.map(mapBucket(m)); + acc[v.name] = mapEmptyToZero(m, split.timeseries.buckets); } return acc; }, {}); diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.js index b9a4139a72313..cc406041ad874 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/series/std_metric.js @@ -6,10 +6,7 @@ * Side Public License, v 1. */ -import { getDefaultDecoration } from '../../helpers/get_default_decoration'; -import { getSplits } from '../../helpers/get_splits'; -import { getLastMetric } from '../../helpers/get_last_metric'; -import { mapBucket } from '../../helpers/map_bucket'; +import { getDefaultDecoration, getSplits, getLastMetric, mapEmptyToZero } from '../../helpers'; import { METRIC_TYPES } from '../../../../../common/enums'; export function stdMetric(resp, panel, series, meta, extractFields) { @@ -26,7 +23,7 @@ export function stdMetric(resp, panel, series, meta, extractFields) { const decoration = getDefaultDecoration(series); (await getSplits(resp, panel, series, meta, extractFields)).forEach((split) => { - const data = split.timeseries.buckets.map(mapBucket(metric)); + const data = mapEmptyToZero(metric, split.timeseries.buckets); results.push({ id: `${split.id}`, label: split.label, diff --git a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_metric.js b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_metric.js index a648258745a15..140212c2ec907 100644 --- a/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_metric.js +++ b/src/plugins/vis_type_timeseries/server/lib/vis_data/response_processors/table/std_metric.js @@ -6,9 +6,7 @@ * Side Public License, v 1. */ -import { getSplits } from '../../helpers/get_splits'; -import { getLastMetric } from '../../helpers/get_last_metric'; -import { mapBucket } from '../../helpers/map_bucket'; +import { getSplits, getLastMetric, mapEmptyToZero } from '../../helpers'; import { METRIC_TYPES } from '../../../../../common/enums'; export function stdMetric(bucket, panel, series, meta, extractFields) { @@ -32,7 +30,7 @@ export function stdMetric(bucket, panel, series, meta, extractFields) { }; (await getSplits(fakeResp, panel, series, meta, extractFields)).forEach((split) => { - const data = split.timeseries.buckets.map(mapBucket(metric)); + const data = mapEmptyToZero(metric, split.timeseries.buckets); results.push({ id: split.id, label: split.label, From fd7dc18f35afae1292470794614a6c46180190c4 Mon Sep 17 00:00:00 2001 From: Jen Huang Date: Wed, 30 Jun 2021 05:44:00 -0700 Subject: [PATCH 7/9] Allow zero (0) to unset unenroll_timeout field (#103790) --- .../components/agent_policy_form.tsx | 23 ++-- .../components/settings/index.tsx | 113 ++++++++++-------- .../fleet/server/services/agent_policy.ts | 5 +- .../fleet/server/types/models/agent_policy.ts | 2 +- 4 files changed, 81 insertions(+), 62 deletions(-) diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx index e9094be534452..475d5a47e3e9a 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/components/agent_policy_form.tsx @@ -159,10 +159,6 @@ export const AgentPolicyForm: React.FunctionComponent = ({ ); }); - const unenrollmentTimeoutText = i18n.translate( - 'xpack.fleet.agentPolicyForm.unenrollmentTimeoutLabel', - { defaultMessage: 'Unenrollment timeout' } - ); const advancedOptionsContent = ( <> @@ -303,7 +299,14 @@ export const AgentPolicyForm: React.FunctionComponent = ({ /> {unenrollmentTimeoutText}} + title={ +

+ +

+ } description={ = ({ updateAgentPolicy({ unenroll_timeout: Number(e.target.value) })} + value={agentPolicy.unenroll_timeout || ''} + onChange={(e) => { + updateAgentPolicy({ + unenroll_timeout: e.target.value ? Number(e.target.value) : 0, + }); + }} isInvalid={Boolean(touchedFields.unenroll_timeout && validation.unenroll_timeout)} onBlur={() => setTouchedFields({ ...touchedFields, unenroll_timeout: true })} - placeholder={unenrollmentTimeoutText} />
diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/settings/index.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/settings/index.tsx index 0c6451e3f34a2..ff704bba70ff4 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/settings/index.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/details_page/components/settings/index.tsx @@ -8,7 +8,14 @@ import React, { memo, useState } from 'react'; import { useHistory } from 'react-router-dom'; import styled from 'styled-components'; -import { EuiBottomBar, EuiFlexGroup, EuiFlexItem, EuiButtonEmpty, EuiButton } from '@elastic/eui'; +import { + EuiBottomBar, + EuiFlexGroup, + EuiFlexItem, + EuiButtonEmpty, + EuiButton, + EuiSpacer, +} from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -145,58 +152,62 @@ export const SettingsView = memo<{ agentPolicy: AgentPolicy }>( /> {hasChanges ? ( - - - - - - - - - { - setAgentPolicy({ ...originalAgentPolicy }); - setHasChanges(false); - }} - > - - - - - 0 - } - iconType="save" - color="primary" - fill - > - {isLoading ? ( - - ) : ( + <> + + + + + + + + + + + { + setAgentPolicy({ ...originalAgentPolicy }); + setHasChanges(false); + }} + > - )} - - - - - - + + + + 0 + } + iconType="save" + color="primary" + fill + > + {isLoading ? ( + + ) : ( + + )} + + + + + + + ) : null} ); diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index 465075cca7a0b..cff70737be6ee 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -642,9 +642,12 @@ class AgentPolicyService { data: (fullPolicy as unknown) as FleetServerPolicy['data'], policy_id: fullPolicy.id, default_fleet_server: policy.is_default_fleet_server === true, - unenroll_timeout: policy.unenroll_timeout, }; + if (policy.unenroll_timeout) { + fleetServerPolicy.unenroll_timeout = policy.unenroll_timeout; + } + await esClient.create({ index: AGENT_POLICY_INDEX, body: fleetServerPolicy, diff --git a/x-pack/plugins/fleet/server/types/models/agent_policy.ts b/x-pack/plugins/fleet/server/types/models/agent_policy.ts index 48aea1b5cbcc4..2a47c002736b5 100644 --- a/x-pack/plugins/fleet/server/types/models/agent_policy.ts +++ b/x-pack/plugins/fleet/server/types/models/agent_policy.ts @@ -16,7 +16,7 @@ export const AgentPolicyBaseSchema = { namespace: NamespaceSchema, description: schema.maybe(schema.string()), is_managed: schema.maybe(schema.boolean()), - unenroll_timeout: schema.maybe(schema.number({ min: 1 })), + unenroll_timeout: schema.maybe(schema.number()), monitoring_enabled: schema.maybe( schema.arrayOf( schema.oneOf([schema.literal(dataTypes.Logs), schema.literal(dataTypes.Metrics)]) From 0636c9bc82c3017f7f846544564bf33d1c830b48 Mon Sep 17 00:00:00 2001 From: Ashokaditya Date: Wed, 30 Jun 2021 14:54:14 +0200 Subject: [PATCH 8/9] [Security Solution][Endpoint] Allow activity log scrolling on small screens (#103852) --- .../endpoint_hosts/view/details/endpoint_activity_log.tsx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_activity_log.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_activity_log.tsx index f1701054c4d5f..360d6e3842816 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_activity_log.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_activity_log.tsx @@ -31,6 +31,9 @@ import { getActivityLogRequestLoading, } from '../../store/selectors'; +const StyledEuiFlexGroup = styled(EuiFlexGroup)` + height: 85vh; +`; const LoadMoreTrigger = styled.div` height: 6px; width: 100%; @@ -79,7 +82,7 @@ export const EndpointActivityLog = memo( return ( <> - + {(activityLogLoaded && !activityLogSize) || activityLogError ? ( )} - + ); } From 398d3fdd5caa955e6229304c29fb52b9e733c56b Mon Sep 17 00:00:00 2001 From: Jean-Louis Leysens Date: Wed, 30 Jun 2021 15:24:41 +0200 Subject: [PATCH 9/9] [Reporting] Reintroduce "ILM policy for managing reporting indices" (#103850) * revert revert * fix import of old type from lib --- .../server/lib/store/report_ilm_policy.ts | 18 +++++ .../reporting/server/lib/store/store.test.ts | 39 +++++++++++ .../reporting/server/lib/store/store.ts | 67 +++++++++++++++---- x-pack/plugins/reporting/server/plugin.ts | 3 + 4 files changed, 115 insertions(+), 12 deletions(-) create mode 100644 x-pack/plugins/reporting/server/lib/store/report_ilm_policy.ts diff --git a/x-pack/plugins/reporting/server/lib/store/report_ilm_policy.ts b/x-pack/plugins/reporting/server/lib/store/report_ilm_policy.ts new file mode 100644 index 0000000000000..90636e3c523a3 --- /dev/null +++ b/x-pack/plugins/reporting/server/lib/store/report_ilm_policy.ts @@ -0,0 +1,18 @@ +/* + * 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 { IlmPutLifecycleRequest } from '@elastic/elasticsearch/api/types'; + +export const reportingIlmPolicy: IlmPutLifecycleRequest['body'] = { + policy: { + phases: { + hot: { + actions: {}, + }, + }, + }, +}; diff --git a/x-pack/plugins/reporting/server/lib/store/store.test.ts b/x-pack/plugins/reporting/server/lib/store/store.test.ts index 8bb5c7fb8bbf9..f46e55c9cc41b 100644 --- a/x-pack/plugins/reporting/server/lib/store/store.test.ts +++ b/x-pack/plugins/reporting/server/lib/store/store.test.ts @@ -7,6 +7,7 @@ import type { DeeplyMockedKeys } from '@kbn/utility-types/jest'; import { ElasticsearchClient } from 'src/core/server'; +import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { ReportingCore } from '../../'; import { createMockConfigSchema, @@ -16,6 +17,8 @@ import { import { Report, ReportDocument } from './report'; import { ReportingStore } from './store'; +const { createApiResponse } = elasticsearchServiceMock; + describe('ReportingStore', () => { const mockLogger = createMockLevelLogger(); let mockCore: ReportingCore; @@ -401,4 +404,40 @@ describe('ReportingStore', () => { expect(updateCall.if_seq_no).toBe(46); expect(updateCall.if_primary_term).toBe(10002); }); + + describe('start', () => { + it('creates an ILM policy for managing reporting indices if there is not already one', async () => { + mockEsClient.ilm.getLifecycle.mockRejectedValueOnce(createApiResponse({ statusCode: 404 })); + mockEsClient.ilm.putLifecycle.mockResolvedValueOnce(createApiResponse()); + + const store = new ReportingStore(mockCore, mockLogger); + await store.start(); + + expect(mockEsClient.ilm.getLifecycle).toHaveBeenCalledWith({ policy: 'kibana-reporting' }); + expect(mockEsClient.ilm.putLifecycle.mock.calls[0][0]).toMatchInlineSnapshot(` + Object { + "body": Object { + "policy": Object { + "phases": Object { + "hot": Object { + "actions": Object {}, + }, + }, + }, + }, + "policy": "kibana-reporting", + } + `); + }); + + it('does not create an ILM policy for managing reporting indices if one already exists', async () => { + mockEsClient.ilm.getLifecycle.mockResolvedValueOnce(createApiResponse()); + + const store = new ReportingStore(mockCore, mockLogger); + await store.start(); + + expect(mockEsClient.ilm.getLifecycle).toHaveBeenCalledWith({ policy: 'kibana-reporting' }); + expect(mockEsClient.ilm.putLifecycle).not.toHaveBeenCalled(); + }); + }); }); diff --git a/x-pack/plugins/reporting/server/lib/store/store.ts b/x-pack/plugins/reporting/server/lib/store/store.ts index 8f1e6c315a2d1..17c067a255b38 100644 --- a/x-pack/plugins/reporting/server/lib/store/store.ts +++ b/x-pack/plugins/reporting/server/lib/store/store.ts @@ -15,6 +15,8 @@ import { indexTimestamp } from './index_timestamp'; import { mapping } from './mapping'; import { MIGRATION_VERSION, Report, ReportDocument, ReportSource } from './report'; +import { reportingIlmPolicy } from './report_ilm_policy'; + /* * When an instance of Kibana claims a report job, this information tells us about that instance */ @@ -115,19 +117,22 @@ export class ReportingStore { return exists; } - const indexSettings = { - number_of_shards: 1, - auto_expand_replicas: '0-1', - }; - const body = { - settings: indexSettings, - mappings: { - properties: mapping, - }, - }; - try { - await client.indices.create({ index: indexName, body }); + await client.indices.create({ + index: indexName, + body: { + settings: { + number_of_shards: 1, + auto_expand_replicas: '0-1', + lifecycle: { + name: this.ilmPolicyName, + }, + }, + mappings: { + properties: mapping, + }, + }, + }); return true; } catch (error) { @@ -176,6 +181,44 @@ export class ReportingStore { return client.indices.refresh({ index }); } + private readonly ilmPolicyName = 'kibana-reporting'; + + private async doesIlmPolicyExist(): Promise { + const client = await this.getClient(); + try { + await client.ilm.getLifecycle({ policy: this.ilmPolicyName }); + return true; + } catch (e) { + if (e.statusCode === 404) { + return false; + } + throw e; + } + } + + /** + * Function to be called during plugin start phase. This ensures the environment is correctly + * configured for storage of reports. + */ + public async start() { + const client = await this.getClient(); + try { + if (await this.doesIlmPolicyExist()) { + this.logger.debug(`Found ILM policy ${this.ilmPolicyName}; skipping creation.`); + return; + } + this.logger.info(`Creating ILM policy for managing reporting indices: ${this.ilmPolicyName}`); + await client.ilm.putLifecycle({ + policy: this.ilmPolicyName, + body: reportingIlmPolicy, + }); + } catch (e) { + this.logger.error('Error in start phase'); + this.logger.error(e.body.error); + throw e; + } + } + public async addReport(report: Report): Promise { let index = report._index; if (!index) { diff --git a/x-pack/plugins/reporting/server/plugin.ts b/x-pack/plugins/reporting/server/plugin.ts index 4e7328cf18003..dc0ddf27a53b3 100644 --- a/x-pack/plugins/reporting/server/plugin.ts +++ b/x-pack/plugins/reporting/server/plugin.ts @@ -108,6 +108,9 @@ export class ReportingPlugin logger: this.logger, }); + // Note: this must be called after ReportingCore.pluginStart + await store.start(); + this.logger.debug('Start complete'); })().catch((e) => { this.logger.error(`Error in Reporting start, reporting may not function properly`);