diff --git a/src/plugins/data/common/field_formats/converters/string.ts b/src/plugins/data/common/field_formats/converters/string.ts index ec92d75910522..64367df5d90dd 100644 --- a/src/plugins/data/common/field_formats/converters/string.ts +++ b/src/plugins/data/common/field_formats/converters/string.ts @@ -13,6 +13,10 @@ import { FieldFormat } from '../field_format'; import { TextContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; import { shortenDottedString } from '../../utils'; +export const emptyLabel = i18n.translate('data.fieldFormats.string.emptyLabel', { + defaultMessage: '(empty)', +}); + const TRANSFORM_OPTIONS = [ { kind: false, @@ -103,6 +107,9 @@ export class StringFormat extends FieldFormat { } textConvert: TextContextTypeConvert = (val) => { + if (val === '') { + return emptyLabel; + } switch (this.param('transform')) { case 'lower': return String(val).toLowerCase(); diff --git a/src/plugins/vis_type_pie/public/utils/get_layers.ts b/src/plugins/vis_type_pie/public/utils/get_layers.ts index 27dcf2d379811..5a82871bf3688 100644 --- a/src/plugins/vis_type_pie/public/utils/get_layers.ts +++ b/src/plugins/vis_type_pie/public/utils/get_layers.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -import { i18n } from '@kbn/i18n'; import { Datum, PartitionFillLabel, @@ -125,11 +124,6 @@ export const getLayers = ( }, showAccessor: (d: Datum) => d !== EMPTY_SLICE, nodeLabel: (d: unknown) => { - if (d === '') { - return i18n.translate('visTypePie.emptyLabelValue', { - defaultMessage: '(empty)', - }); - } if (col.format) { const formattedLabel = formatter.deserialize(col.format).convert(d) ?? ''; if (visParams.labels.truncate && formattedLabel.length <= visParams.labels.truncate) { diff --git a/src/plugins/vis_type_xy/public/components/detailed_tooltip.tsx b/src/plugins/vis_type_xy/public/components/detailed_tooltip.tsx index c9ed82fcf58e5..fb6b4bb41d9ba 100644 --- a/src/plugins/vis_type_xy/public/components/detailed_tooltip.tsx +++ b/src/plugins/vis_type_xy/public/components/detailed_tooltip.tsx @@ -19,7 +19,6 @@ import { import { Aspects } from '../types'; import './_detailed_tooltip.scss'; -import { fillEmptyValue } from '../utils/get_series_name_fn'; import { COMPLEX_SPLIT_ACCESSOR, isRangeAggType } from '../utils/accessors'; interface TooltipData { @@ -100,8 +99,7 @@ export const getTooltipData = ( return data; }; -const renderData = ({ label, value: rawValue }: TooltipData, index: number) => { - const value = fillEmptyValue(rawValue); +const renderData = ({ label, value }: TooltipData, index: number) => { return label && value ? ( diff --git a/src/plugins/vis_type_xy/public/components/xy_settings.tsx b/src/plugins/vis_type_xy/public/components/xy_settings.tsx index 8922f512522a0..8d6a7eecdfe52 100644 --- a/src/plugins/vis_type_xy/public/components/xy_settings.tsx +++ b/src/plugins/vis_type_xy/public/components/xy_settings.tsx @@ -29,7 +29,6 @@ import { renderEndzoneTooltip } from '../../../charts/public'; import { getThemeService, getUISettings } from '../services'; import { VisConfig } from '../types'; -import { fillEmptyValue } from '../utils/get_series_name_fn'; declare global { interface Window { @@ -134,7 +133,7 @@ export const XYSettings: FC = ({ }; const headerValueFormatter: TickFormatter | undefined = xAxis.ticks?.formatter - ? (value) => fillEmptyValue(xAxis.ticks?.formatter?.(value)) ?? '' + ? (value) => xAxis.ticks?.formatter?.(value) ?? '' : undefined; const headerFormatter = isTimeChart && xDomain && adjustedXDomain diff --git a/src/plugins/vis_type_xy/public/config/get_axis.ts b/src/plugins/vis_type_xy/public/config/get_axis.ts index 08b17c882eea6..71d33cc20d057 100644 --- a/src/plugins/vis_type_xy/public/config/get_axis.ts +++ b/src/plugins/vis_type_xy/public/config/get_axis.ts @@ -27,7 +27,6 @@ import { YScaleType, SeriesParam, } from '../types'; -import { fillEmptyValue } from '../utils/get_series_name_fn'; export function getAxis( { type, title: axisTitle, labels, scale: axisScale, ...axis }: CategoryAxis, @@ -90,8 +89,7 @@ function getLabelFormatter( } return (value: any) => { - const formattedStringValue = `${formatter ? formatter(value) : value}`; - const finalValue = fillEmptyValue(formattedStringValue); + const finalValue = `${formatter ? formatter(value) : value}`; if (finalValue.length > truncate) { return `${finalValue.slice(0, truncate)}...`; diff --git a/src/plugins/vis_type_xy/public/utils/get_series_name_fn.ts b/src/plugins/vis_type_xy/public/utils/get_series_name_fn.ts index 0e54650e22f75..137f8a5558010 100644 --- a/src/plugins/vis_type_xy/public/utils/get_series_name_fn.ts +++ b/src/plugins/vis_type_xy/public/utils/get_series_name_fn.ts @@ -8,21 +8,10 @@ import { memoize } from 'lodash'; -import { i18n } from '@kbn/i18n'; import { XYChartSeriesIdentifier, SeriesName } from '@elastic/charts'; import { VisConfig } from '../types'; -const emptyTextLabel = i18n.translate('visTypeXy.emptyTextColumnValue', { - defaultMessage: '(empty)', -}); - -/** - * Returns empty values - */ -export const fillEmptyValue = (value: T) => - value === '' ? emptyTextLabel : value; - function getSplitValues( splitAccessors: XYChartSeriesIdentifier['splitAccessors'], seriesAspects?: VisConfig['aspects']['series'] @@ -36,7 +25,7 @@ function getSplitValues( const split = (seriesAspects ?? []).find(({ accessor }) => accessor === key); splitValues.push(split?.formatter ? split?.formatter(value) : value); }); - return splitValues.map(fillEmptyValue); + return splitValues; } export const getSeriesNameFn = (aspects: VisConfig['aspects'], multipleY = false) => diff --git a/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.ts b/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.ts index 0d44ae3aa6dec..8615ed6536316 100644 --- a/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.ts +++ b/x-pack/plugins/lens/public/datatable_visualization/components/table_actions.ts @@ -15,8 +15,6 @@ import type { LensToggleAction, } from './types'; import { ColumnConfig } from './table_basic'; - -import { desanitizeFilterContext } from '../../utils'; import { getOriginalId } from '../transpose_helpers'; export const createGridResizeHandler = ( @@ -92,7 +90,7 @@ export const createGridFilterHandler = ( timeFieldName, }; - onClickValue(desanitizeFilterContext(data)); + onClickValue(data); }; export const createTransposeColumnFilterHandler = ( @@ -125,7 +123,7 @@ export const createTransposeColumnFilterHandler = ( timeFieldName, }; - onClickValue(desanitizeFilterContext(data)); + onClickValue(data); }; export const createGridSortingConfig = ( diff --git a/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx b/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx index 3048f3b3db580..8214d5ba129d4 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx +++ b/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx @@ -21,7 +21,6 @@ import { VisualizationContainer } from '../visualization_container'; import { HeatmapRenderProps } from './types'; import './index.scss'; import { LensBrushEvent, LensFilterEvent } from '../types'; -import { desanitizeFilterContext } from '../utils'; import { EmptyPlaceholder } from '../shared_components'; import { LensIconChartHeatmap } from '../assets/chart_heatmap'; @@ -117,7 +116,7 @@ export const HeatmapComponent: FC = ({ })), timeFieldName, }; - onClickValue(desanitizeFilterContext(context)); + onClickValue(context); }) as ElementClickListener; const onBrushEnd = (e: HeatmapBrushEvent) => { @@ -164,7 +163,7 @@ export const HeatmapComponent: FC = ({ })), timeFieldName, }; - onClickValue(desanitizeFilterContext(context)); + onClickValue(context); } }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.test.ts b/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.test.ts index 0750b99db5f67..5654a599c5e27 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.test.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.test.ts @@ -83,29 +83,6 @@ describe('rename_columns', () => { `); }); - it('should replace "" with a visible value', () => { - const input: Datatable = { - type: 'datatable', - columns: [{ id: 'a', name: 'A', meta: { type: 'string' } }], - rows: [{ a: '' }], - }; - - const idMap = { - a: { - id: 'a', - label: 'Austrailia', - }, - }; - - const result = renameColumns.fn( - input, - { idMap: JSON.stringify(idMap) }, - createMockExecutionContext() - ); - - expect(result.rows[0].a).toEqual('(empty)'); - }); - it('should keep columns which are not mapped', () => { const input: Datatable = { type: 'datatable', diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.ts b/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.ts index 89c63880248d0..a16756126c030 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/rename_columns.ts @@ -49,9 +49,9 @@ export const renameColumns: ExpressionFunctionDefinition< Object.entries(row).forEach(([id, value]) => { if (id in idMap) { - mappedRow[idMap[id].id] = sanitizeValue(value); + mappedRow[idMap[id].id] = value; } else { - mappedRow[id] = sanitizeValue(value); + mappedRow[id] = value; } }); @@ -86,13 +86,3 @@ function getColumnName(originalColumn: OriginalColumn, newColumn: DatatableColum return originalColumn.label; } - -function sanitizeValue(value: unknown) { - if (value === '') { - return i18n.translate('xpack.lens.indexpattern.emptyTextColumnValue', { - defaultMessage: '(empty)', - }); - } - - return value; -} diff --git a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx index f329cfe1bb8b9..2e5a06b4f705f 100644 --- a/x-pack/plugins/lens/public/pie_visualization/render_function.tsx +++ b/x-pack/plugins/lens/public/pie_visualization/render_function.tsx @@ -31,7 +31,6 @@ import { PieExpressionProps } from './types'; import { getSliceValue, getFilterContext } from './render_helpers'; import { EmptyPlaceholder } from '../shared_components'; import './visualization.scss'; -import { desanitizeFilterContext } from '../utils'; import { ChartsPluginSetup, PaletteRegistry, @@ -254,7 +253,7 @@ export function PieComponent( const onElementClickHandler: ElementClickListener = (args) => { const context = getFilterContext(args[0][0] as LayerValue[], groups, firstTable); - onClickValue(desanitizeFilterContext(context)); + onClickValue(context); }; return ( diff --git a/x-pack/plugins/lens/public/shared_components/legend_action_popover.tsx b/x-pack/plugins/lens/public/shared_components/legend_action_popover.tsx index e344cb5289f51..5027629ef6ae5 100644 --- a/x-pack/plugins/lens/public/shared_components/legend_action_popover.tsx +++ b/x-pack/plugins/lens/public/shared_components/legend_action_popover.tsx @@ -9,7 +9,6 @@ import React, { useState } from 'react'; import { i18n } from '@kbn/i18n'; import { EuiContextMenuPanelDescriptor, EuiIcon, EuiPopover, EuiContextMenu } from '@elastic/eui'; import type { LensFilterEvent } from '../types'; -import { desanitizeFilterContext } from '../utils'; export interface LegendActionPopoverProps { /** @@ -45,7 +44,7 @@ export const LegendActionPopover: React.FunctionComponent, onClick: () => { setPopoverOpen(false); - onFilter(desanitizeFilterContext(context)); + onFilter(context); }, }, { @@ -56,7 +55,7 @@ export const LegendActionPopover: React.FunctionComponent, onClick: () => { setPopoverOpen(false); - onFilter(desanitizeFilterContext({ ...context, negate: true })); + onFilter({ ...context, negate: true }); }, }, ], diff --git a/x-pack/plugins/lens/public/utils.test.ts b/x-pack/plugins/lens/public/utils.test.ts deleted file mode 100644 index 76597870b3beb..0000000000000 --- a/x-pack/plugins/lens/public/utils.test.ts +++ /dev/null @@ -1,118 +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; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { LensFilterEvent } from './types'; -import { desanitizeFilterContext } from './utils'; -import { Datatable } from '../../../../src/plugins/expressions/common'; - -describe('desanitizeFilterContext', () => { - it(`When filtered value equals '(empty)' replaces it with '' in table and in value.`, () => { - const table: Datatable = { - type: 'datatable', - rows: [ - { - 'f903668f-1175-4705-a5bd-713259d10326': 1589414640000, - '5d5446b2-72e8-4f86-91e0-88380f0fa14c': '(empty)', - 'col-1-9f0b6f88-c399-43a0-a993-0ad943c9af25': 1, - }, - { - 'f903668f-1175-4705-a5bd-713259d10326': 1589414670000, - 'col-1-9f0b6f88-c399-43a0-a993-0ad943c9af25': 0, - }, - { - 'f903668f-1175-4705-a5bd-713259d10326': 1589414880000, - '5d5446b2-72e8-4f86-91e0-88380f0fa14c': '123123123', - 'col-1-9f0b6f88-c399-43a0-a993-0ad943c9af25': 1, - }, - { - 'f903668f-1175-4705-a5bd-713259d10326': 1589414910000, - '5d5446b2-72e8-4f86-91e0-88380f0fa14c': '(empty)', - 'col-1-9f0b6f88-c399-43a0-a993-0ad943c9af25': 1, - }, - ], - columns: [ - { - id: 'f903668f-1175-4705-a5bd-713259d10326', - name: 'order_date per 30 seconds', - meta: { type: 'date' }, - }, - { - id: '5d5446b2-72e8-4f86-91e0-88380f0fa14c', - name: 'Top values of customer_phone', - meta: { type: 'string' }, - }, - { - id: '9f0b6f88-c399-43a0-a993-0ad943c9af25', - name: 'Count of records', - meta: { type: 'number' }, - }, - ], - }; - - const contextWithEmptyValue: LensFilterEvent['data'] = { - data: [ - { - row: 3, - column: 0, - value: 1589414910000, - table, - }, - { - row: 0, - column: 1, - value: '(empty)', - table, - }, - ], - timeFieldName: 'order_date', - }; - - const desanitizedFilterContext = desanitizeFilterContext(contextWithEmptyValue); - - expect(desanitizedFilterContext).toEqual({ - data: [ - { - row: 3, - column: 0, - value: 1589414910000, - table, - }, - { - value: '', - row: 0, - column: 1, - table: { - rows: [ - { - 'f903668f-1175-4705-a5bd-713259d10326': 1589414640000, - '5d5446b2-72e8-4f86-91e0-88380f0fa14c': '', - 'col-1-9f0b6f88-c399-43a0-a993-0ad943c9af25': 1, - }, - { - 'f903668f-1175-4705-a5bd-713259d10326': 1589414670000, - 'col-1-9f0b6f88-c399-43a0-a993-0ad943c9af25': 0, - }, - { - 'f903668f-1175-4705-a5bd-713259d10326': 1589414880000, - '5d5446b2-72e8-4f86-91e0-88380f0fa14c': '123123123', - 'col-1-9f0b6f88-c399-43a0-a993-0ad943c9af25': 1, - }, - { - 'f903668f-1175-4705-a5bd-713259d10326': 1589414910000, - '5d5446b2-72e8-4f86-91e0-88380f0fa14c': '(empty)', - 'col-1-9f0b6f88-c399-43a0-a993-0ad943c9af25': 1, - }, - ], - columns: table.columns, - type: 'datatable', - }, - }, - ], - timeFieldName: 'order_date', - }); - }); -}); diff --git a/x-pack/plugins/lens/public/utils.ts b/x-pack/plugins/lens/public/utils.ts index 2706fe977c68e..1c4b2c67f96fc 100644 --- a/x-pack/plugins/lens/public/utils.ts +++ b/x-pack/plugins/lens/public/utils.ts @@ -9,42 +9,6 @@ import { i18n } from '@kbn/i18n'; import { IndexPattern, IndexPatternsContract, TimefilterContract } from 'src/plugins/data/public'; import { IUiSettingsClient } from 'kibana/public'; import moment from 'moment-timezone'; -import { LensFilterEvent } from './types'; - -/** replaces the value `(empty) to empty string for proper filtering` */ -export const desanitizeFilterContext = ( - context: LensFilterEvent['data'] -): LensFilterEvent['data'] => { - const emptyTextValue = i18n.translate('xpack.lens.indexpattern.emptyTextColumnValue', { - defaultMessage: '(empty)', - }); - const result: LensFilterEvent['data'] = { - ...context, - data: context.data.map((point) => - point.value === emptyTextValue - ? { - ...point, - value: '', - table: { - ...point.table, - rows: point.table.rows.map((row, index) => - index === point.row - ? { - ...row, - [point.table.columns[point.column].id]: '', - } - : row - ), - }, - } - : point - ), - }; - if (context.timeFieldName) { - result.timeFieldName = context.timeFieldName; - } - return result; -}; export function getVisualizeGeoFieldMessage(fieldType: string) { return i18n.translate('xpack.lens.visualizeGeoFieldMessage', { diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index 1de5cf6b30533..3fe98282a18b0 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -53,7 +53,6 @@ import { SeriesLayer, } from '../../../../../src/plugins/charts/public'; import { EmptyPlaceholder } from '../shared_components'; -import { desanitizeFilterContext } from '../utils'; import { fittingFunctionDefinitions, getFitOptions } from './fitting_functions'; import { getAxesConfiguration, GroupsConfiguration, validateExtent } from './axes_configuration'; import { getColorAssignments } from './color_assignment'; @@ -575,7 +574,7 @@ export function XYChart({ })), timeFieldName: xDomain && isDateField ? xAxisFieldName : undefined, }; - onClickValue(desanitizeFilterContext(context)); + onClickValue(context); }; const brushHandler: BrushEndListener = ({ x }) => { diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 87813b64f1f20..837716ec9dd5a 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -5055,7 +5055,6 @@ "visTypeXy.editors.pointSeries.thresholdLine.valueLabel": "しきい値", "visTypeXy.editors.pointSeries.thresholdLine.widthLabel": "線の幅", "visTypeXy.editors.pointSeries.thresholdLineSettingsTitle": "しきい線", - "visTypeXy.emptyTextColumnValue": " (空) ", "visTypeXy.fittingFunctionsTitle.carry": "最後 (ギャップを最後の値で埋める) ", "visTypeXy.fittingFunctionsTitle.linear": "線形 (ギャップを線で埋める) ", "visTypeXy.fittingFunctionsTitle.lookahead": "次 (ギャップを次の値で埋める) ", @@ -12574,7 +12573,6 @@ "xpack.lens.indexPattern.emptyDimensionButton": "空のディメンション", "xpack.lens.indexPattern.emptyFieldsLabel": "空のフィールド", "xpack.lens.indexPattern.emptyFieldsLabelHelp": "空のフィールドには、フィルターに基づく最初の 500 件のドキュメントの値が含まれていませんでした。", - "xpack.lens.indexpattern.emptyTextColumnValue": " (空) ", "xpack.lens.indexPattern.existenceErrorAriaLabel": "存在の取り込みに失敗しました", "xpack.lens.indexPattern.existenceErrorLabel": "フィールド情報を読み込めません", "xpack.lens.indexPattern.existenceTimeoutAriaLabel": "存在の取り込みがタイムアウトしました", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 4e98de541ce60..0192566db0731 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -5083,7 +5083,6 @@ "visTypeXy.editors.pointSeries.thresholdLine.valueLabel": "阈值", "visTypeXy.editors.pointSeries.thresholdLine.widthLabel": "线条宽度", "visTypeXy.editors.pointSeries.thresholdLineSettingsTitle": "阈值线条", - "visTypeXy.emptyTextColumnValue": " (空) ", "visTypeXy.fittingFunctionsTitle.carry": "最后一个 (使用最后一个值填充缺口) ", "visTypeXy.fittingFunctionsTitle.linear": "线 (使用线填充缺口) ", "visTypeXy.fittingFunctionsTitle.lookahead": "下一个 (使用下一个值填充缺口) ", @@ -12744,7 +12743,6 @@ "xpack.lens.indexPattern.emptyDimensionButton": "空维度", "xpack.lens.indexPattern.emptyFieldsLabel": "空字段", "xpack.lens.indexPattern.emptyFieldsLabelHelp": "空字段在基于您的筛选的前 500 个文档中不包含任何值。", - "xpack.lens.indexpattern.emptyTextColumnValue": " (空) ", "xpack.lens.indexPattern.existenceErrorAriaLabel": "现有内容提取失败", "xpack.lens.indexPattern.existenceErrorLabel": "无法加载字段信息", "xpack.lens.indexPattern.existenceTimeoutAriaLabel": "现有内容提取超时", diff --git a/x-pack/test/functional/apps/discover/__snapshots__/reporting.snap b/x-pack/test/functional/apps/discover/__snapshots__/reporting.snap index baa49cb6f9d81..c7666bf00dd53 100644 --- a/x-pack/test/functional/apps/discover/__snapshots__/reporting.snap +++ b/x-pack/test/functional/apps/discover/__snapshots__/reporting.snap @@ -65,7 +65,7 @@ exports[`discover Discover CSV Export Generate CSV: archived search generates a exports[`discover Discover CSV Export Generate CSV: new search generates a report from a new search with data: default 1`] = ` "\\"_id\\",\\"_index\\",\\"_score\\",\\"_type\\",category,\\"category.keyword\\",currency,\\"customer_first_name\\",\\"customer_first_name.keyword\\",\\"customer_full_name\\",\\"customer_full_name.keyword\\",\\"customer_gender\\",\\"customer_id\\",\\"customer_last_name\\",\\"customer_last_name.keyword\\",\\"customer_phone\\",\\"day_of_week\\",\\"day_of_week_i\\",email,\\"geoip.city_name\\",\\"geoip.continent_name\\",\\"geoip.country_iso_code\\",\\"geoip.location\\",\\"geoip.region_name\\",manufacturer,\\"manufacturer.keyword\\",\\"order_date\\",\\"order_id\\",\\"products._id\\",\\"products._id.keyword\\",\\"products.base_price\\",\\"products.base_unit_price\\",\\"products.category\\",\\"products.category.keyword\\",\\"products.created_on\\",\\"products.discount_amount\\",\\"products.discount_percentage\\",\\"products.manufacturer\\",\\"products.manufacturer.keyword\\",\\"products.min_price\\",\\"products.price\\",\\"products.product_id\\",\\"products.product_name\\",\\"products.product_name.keyword\\",\\"products.quantity\\",\\"products.sku\\",\\"products.tax_amount\\",\\"products.taxful_price\\",\\"products.taxless_price\\",\\"products.unit_discount_amount\\",sku,\\"taxful_total_price\\",\\"taxless_total_price\\",\\"total_quantity\\",\\"total_unique_products\\",type,user -3AMtOW0BH63Xcmy432DJ,ecommerce,\\"-\\",\\"-\\",\\"Men's Shoes, Men's Clothing, Women's Accessories, Men's Accessories\\",\\"Men's Shoes, Men's Clothing, Women's Accessories, Men's Accessories\\",EUR,\\"Sultan Al\\",\\"Sultan Al\\",\\"Sultan Al Boone\\",\\"Sultan Al Boone\\",MALE,19,Boone,Boone,,Saturday,5,\\"sultan al@boone-family.zzz\\",\\"Abu Dhabi\\",Asia,AE,\\"{ +3AMtOW0BH63Xcmy432DJ,ecommerce,\\"-\\",\\"-\\",\\"Men's Shoes, Men's Clothing, Women's Accessories, Men's Accessories\\",\\"Men's Shoes, Men's Clothing, Women's Accessories, Men's Accessories\\",EUR,\\"Sultan Al\\",\\"Sultan Al\\",\\"Sultan Al Boone\\",\\"Sultan Al Boone\\",MALE,19,Boone,Boone,\\"(empty)\\",Saturday,5,\\"sultan al@boone-family.zzz\\",\\"Abu Dhabi\\",Asia,AE,\\"{ \\"\\"coordinates\\"\\": [ 54.4, 24.5 @@ -77,7 +77,7 @@ exports[`discover Discover CSV Export Generate CSV: new search generates a repor exports[`discover Discover CSV Export Generate CSV: new search generates a report from a new search with data: discover:searchFieldsFromSource 1`] = ` "\\"_id\\",\\"_index\\",\\"_score\\",\\"_type\\",category,\\"category.keyword\\",currency,\\"customer_first_name\\",\\"customer_first_name.keyword\\",\\"customer_full_name\\",\\"customer_full_name.keyword\\",\\"customer_gender\\",\\"customer_id\\",\\"customer_last_name\\",\\"customer_last_name.keyword\\",\\"customer_phone\\",\\"day_of_week\\",\\"day_of_week_i\\",email,\\"geoip.city_name\\",\\"geoip.continent_name\\",\\"geoip.country_iso_code\\",\\"geoip.location\\",\\"geoip.region_name\\",manufacturer,\\"manufacturer.keyword\\",\\"order_date\\",\\"order_id\\",\\"products._id\\",\\"products._id.keyword\\",\\"products.base_price\\",\\"products.base_unit_price\\",\\"products.category\\",\\"products.category.keyword\\",\\"products.created_on\\",\\"products.discount_amount\\",\\"products.discount_percentage\\",\\"products.manufacturer\\",\\"products.manufacturer.keyword\\",\\"products.min_price\\",\\"products.price\\",\\"products.product_id\\",\\"products.product_name\\",\\"products.product_name.keyword\\",\\"products.quantity\\",\\"products.sku\\",\\"products.tax_amount\\",\\"products.taxful_price\\",\\"products.taxless_price\\",\\"products.unit_discount_amount\\",sku,\\"taxful_total_price\\",\\"taxless_total_price\\",\\"total_quantity\\",\\"total_unique_products\\",type,user -3AMtOW0BH63Xcmy432DJ,ecommerce,\\"-\\",\\"-\\",\\"Men's Shoes, Men's Clothing, Women's Accessories, Men's Accessories\\",\\"Men's Shoes, Men's Clothing, Women's Accessories, Men's Accessories\\",EUR,\\"Sultan Al\\",\\"Sultan Al\\",\\"Sultan Al Boone\\",\\"Sultan Al Boone\\",MALE,19,Boone,Boone,,Saturday,5,\\"sultan al@boone-family.zzz\\",\\"Abu Dhabi\\",Asia,AE,\\"{ +3AMtOW0BH63Xcmy432DJ,ecommerce,\\"-\\",\\"-\\",\\"Men's Shoes, Men's Clothing, Women's Accessories, Men's Accessories\\",\\"Men's Shoes, Men's Clothing, Women's Accessories, Men's Accessories\\",EUR,\\"Sultan Al\\",\\"Sultan Al\\",\\"Sultan Al Boone\\",\\"Sultan Al Boone\\",MALE,19,Boone,Boone,\\"(empty)\\",Saturday,5,\\"sultan al@boone-family.zzz\\",\\"Abu Dhabi\\",Asia,AE,\\"{ \\"\\"coordinates\\"\\": [ 54.4, 24.5