diff --git a/src/plugins/unified_histogram/public/__mocks__/suggestions.ts b/src/plugins/unified_histogram/public/__mocks__/suggestions.ts index 1de961c55c020..9e3a00d396047 100644 --- a/src/plugins/unified_histogram/public/__mocks__/suggestions.ts +++ b/src/plugins/unified_histogram/public/__mocks__/suggestions.ts @@ -57,22 +57,6 @@ export const currentSuggestionMock = { }, }, ], - allColumns: [ - { - columnId: '81e332d6-ee37-42a8-a646-cea4fc75d2d3', - fieldName: 'Dest', - meta: { - type: 'string', - }, - }, - { - columnId: '5b9b8b76-0836-4a12-b9c0-980c9900502f', - fieldName: 'AvgTicketPrice', - meta: { - type: 'number', - }, - }, - ], timeField: 'timestamp', }, }, @@ -195,22 +179,6 @@ export const allSuggestionsMock = [ }, }, ], - allColumns: [ - { - columnId: '923f0681-3fe1-4987-aa27-d9c91fb95fa6', - fieldName: 'Dest', - meta: { - type: 'string', - }, - }, - { - columnId: 'b5f41c04-4bca-4abe-ae5c-b1d4d6fb00e0', - fieldName: 'AvgTicketPrice', - meta: { - type: 'number', - }, - }, - ], timeField: 'timestamp', }, }, diff --git a/src/plugins/unified_histogram/public/chart/utils/get_lens_attributes.test.ts b/src/plugins/unified_histogram/public/chart/utils/get_lens_attributes.test.ts index 998cd17968049..3c049649d5c20 100644 --- a/src/plugins/unified_histogram/public/chart/utils/get_lens_attributes.test.ts +++ b/src/plugins/unified_histogram/public/chart/utils/get_lens_attributes.test.ts @@ -643,22 +643,6 @@ describe('getLensAttributes', () => { }, "layers": Object { "46aa21fa-b747-4543-bf90-0b40007c546d": Object { - "allColumns": Array [ - Object { - "columnId": "81e332d6-ee37-42a8-a646-cea4fc75d2d3", - "fieldName": "Dest", - "meta": Object { - "type": "string", - }, - }, - Object { - "columnId": "5b9b8b76-0836-4a12-b9c0-980c9900502f", - "fieldName": "AvgTicketPrice", - "meta": Object { - "type": "number", - }, - }, - ], "columns": Array [ Object { "columnId": "81e332d6-ee37-42a8-a646-cea4fc75d2d3", diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts index 0fe5f148a25d0..bc646ac140c95 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.test.ts @@ -14,18 +14,18 @@ import { mockAllSuggestions, } from '../../../mocks'; import { suggestionsApi } from '../../../lens_suggestions_api'; -import { fetchDataFromAggregateQuery } from '../../../datasources/text_based/fetch_data_from_aggregate_query'; +import { fetchFieldsFromESQL } from '../../../datasources/text_based/fetch_fields_from_esql'; import { getSuggestions } from './helpers'; const mockSuggestionApi = suggestionsApi as jest.Mock; -const mockFetchData = fetchDataFromAggregateQuery as jest.Mock; +const mockFetchData = fetchFieldsFromESQL as jest.Mock; jest.mock('../../../lens_suggestions_api', () => ({ suggestionsApi: jest.fn(() => mockAllSuggestions), })); -jest.mock('../../../datasources/text_based/fetch_data_from_aggregate_query', () => ({ - fetchDataFromAggregateQuery: jest.fn(() => { +jest.mock('../../../datasources/text_based/fetch_fields_from_esql', () => ({ + fetchFieldsFromESQL: jest.fn(() => { return { columns: [ { diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts index faecb37ba7fd7..1e1fd600b6879 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/helpers.ts @@ -12,14 +12,10 @@ import type { Suggestion } from '../../../types'; import type { TypedLensByValueInput } from '../../../embeddable/embeddable_component'; import type { LensPluginStartDependencies } from '../../../plugin'; import type { DatasourceMap, VisualizationMap } from '../../../types'; -import { fetchDataFromAggregateQuery } from '../../../datasources/text_based/fetch_data_from_aggregate_query'; +import { fetchFieldsFromESQL } from '../../../datasources/text_based/fetch_fields_from_esql'; import { suggestionsApi } from '../../../lens_suggestions_api'; -export const getQueryColumns = async ( - query: AggregateQuery, - dataView: DataView, - deps: LensPluginStartDependencies -) => { +export const getQueryColumns = async (query: AggregateQuery, deps: LensPluginStartDependencies) => { // Fetching only columns for ES|QL for performance reasons with limit 0 // Important note: ES doesnt return the warnings for 0 limit, // I am skipping them in favor of performance now @@ -28,12 +24,7 @@ export const getQueryColumns = async ( if ('esql' in performantQuery && performantQuery.esql) { performantQuery.esql = `${performantQuery.esql} | limit 0`; } - const table = await fetchDataFromAggregateQuery( - performantQuery, - dataView, - deps.data, - deps.expressions - ); + const table = await fetchFieldsFromESQL(performantQuery, deps.expressions); return table?.columns; }; @@ -65,7 +56,7 @@ export const getSuggestions = async ( if (dataView.fields.getByName('@timestamp')?.type === 'date' && !dataViewSpec) { dataView.timeFieldName = '@timestamp'; } - const columns = await getQueryColumns(query, dataView, deps); + const columns = await getQueryColumns(query, deps); const context = { dataViewSpec: dataView?.toSpec(), fieldName: '', diff --git a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx index 1aae97977d714..b17c1313a8df0 100644 --- a/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx +++ b/x-pack/plugins/lens/public/app_plugin/shared/edit_on_the_fly/lens_configuration_flyout.tsx @@ -28,6 +28,7 @@ import type { AggregateQuery, Query } from '@kbn/es-query'; import { TextBasedLangEditor } from '@kbn/text-based-languages/public'; import { DefaultInspectorAdapters } from '@kbn/expressions-plugin/common'; import { buildExpression } from '../../../editor_frame_service/editor_frame/expression_helpers'; +import { MAX_NUM_OF_COLUMNS } from '../../../datasources/text_based/utils'; import { useLensSelector, selectFramePublicAPI, @@ -76,6 +77,7 @@ export function LensEditConfigurationFlyout({ const [errors, setErrors] = useState(); const [isInlineFlyoutVisible, setIsInlineFlyoutVisible] = useState(true); const [isLayerAccordionOpen, setIsLayerAccordionOpen] = useState(true); + const [suggestsLimitedColumns, setSuggestsLimitedColumns] = useState(false); const [isSuggestionsAccordionOpen, setIsSuggestionsAccordionOpen] = useState(false); const datasourceState = attributes.state.datasourceStates[datasourceId]; const activeDatasource = datasourceMap[datasourceId]; @@ -87,7 +89,6 @@ export function LensEditConfigurationFlyout({ visualizationMap[visualization.activeId ?? attributes.visualizationType]; const framePublicAPI = useLensSelector((state) => selectFramePublicAPI(state, datasourceMap)); - const suggestsLimitedColumns = activeDatasource?.suggestsLimitedColumns?.(datasourceState); const layers = useMemo( () => activeDatasource.getLayers(datasourceState), @@ -101,6 +102,11 @@ export function LensEditConfigurationFlyout({ const adaptersTables = previousAdapters.current?.tables?.tables as Record; const [table] = Object.values(adaptersTables || {}); if (table) { + // there are cases where a query can return a big amount of columns + // at this case we don't suggest all columns in a table but the first + // MAX_NUM_OF_COLUMNS + const columns = Object.keys(table.rows?.[0]) ?? []; + setSuggestsLimitedColumns(columns.length >= MAX_NUM_OF_COLUMNS); layers.forEach((layer) => { activeData[layer] = table; }); diff --git a/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx b/x-pack/plugins/lens/public/datasources/text_based/components/datapanel.test.tsx similarity index 95% rename from x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx rename to x-pack/plugins/lens/public/datasources/text_based/components/datapanel.test.tsx index ca151b9ad21a6..7fb77386eff09 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/datapanel.test.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/components/datapanel.test.tsx @@ -23,14 +23,14 @@ import { EuiHighlight, EuiToken } from '@elastic/eui'; import { type TextBasedDataPanelProps, TextBasedDataPanel } from './datapanel'; import { coreMock } from '@kbn/core/public/mocks'; -import type { TextBasedPrivateState } from './types'; +import type { TextBasedPrivateState } from '../types'; import { mountWithIntl } from '@kbn/test-jest-helpers'; import { uiActionsPluginMock } from '@kbn/ui-actions-plugin/public/mocks'; -import { createIndexPatternServiceMock } from '../../mocks/data_views_service_mock'; -import { createMockFramePublicAPI } from '../../mocks'; -import { DataViewsState } from '../../state_management'; -import { addColumnsToCache } from './fieldlist_cache'; +import { createIndexPatternServiceMock } from '../../../mocks/data_views_service_mock'; +import { createMockFramePublicAPI } from '../../../mocks'; +import { DataViewsState } from '../../../state_management'; +import { addColumnsToCache } from '../fieldlist_cache'; const fieldsFromQuery = [ { @@ -106,7 +106,6 @@ const initialState: TextBasedPrivateState = { first: { index: '1', columns: [], - allColumns: [], query: { esql: 'SELECT * FROM foo' }, }, }, @@ -117,7 +116,7 @@ const initialState: TextBasedPrivateState = { ], }; -addColumnsToCache('SELECT * FROM my-fake-index-pattern', fieldsFromQuery); +addColumnsToCache({ esql: 'SELECT * FROM my-fake-index-pattern' }, fieldsFromQuery); function getFrameAPIMock({ indexPatterns, diff --git a/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx b/x-pack/plugins/lens/public/datasources/text_based/components/datapanel.tsx similarity index 89% rename from x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx rename to x-pack/plugins/lens/public/datasources/text_based/components/datapanel.tsx index cca962c1884b2..bda5df0e34882 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/datapanel.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/components/datapanel.tsx @@ -12,7 +12,7 @@ import { isEqual } from 'lodash'; import { DataPublicPluginStart } from '@kbn/data-plugin/public'; import type { DataViewsPublicPluginStart } from '@kbn/data-views-plugin/public'; -import { isOfAggregateQueryType, getAggregateQueryMode } from '@kbn/es-query'; +import { isOfAggregateQueryType } from '@kbn/es-query'; import { DatatableColumn, ExpressionsStart } from '@kbn/expressions-plugin/public'; import { KibanaContextProvider } from '@kbn/kibana-react-plugin/public'; import { @@ -24,11 +24,11 @@ import { GetCustomFieldType, useGroupedFields, } from '@kbn/unified-field-list'; -import type { DatasourceDataPanelProps } from '../../types'; -import type { TextBasedPrivateState } from './types'; -import { getStateFromAggregateQuery } from './utils'; -import { FieldItem } from '../common/field_item'; -import { getColumnsFromCache } from './fieldlist_cache'; +import type { DatasourceDataPanelProps } from '../../../types'; +import type { TextBasedPrivateState } from '../types'; +import { getStateFromAggregateQuery } from '../utils'; +import { FieldItem } from '../../common/field_item'; +import { getColumnsFromCache } from '../fieldlist_cache'; const getCustomFieldType: GetCustomFieldType = (field) => field?.meta.type; @@ -74,8 +74,7 @@ export function TextBasedDataPanel({ } fetchData(); }, [data, dataViews, expressions, prevQuery, query, setState, state, frame.dataViews]); - const language = isOfAggregateQueryType(query) ? getAggregateQueryMode(query) : null; - const fieldList = language ? getColumnsFromCache(query[language]) : []; + const fieldList = isOfAggregateQueryType(query) ? getColumnsFromCache(query) : []; const onSelectedFieldFilter = useCallback( (field: DatatableColumn): boolean => { diff --git a/x-pack/plugins/lens/public/datasources/text_based/components/dimension_editor.tsx b/x-pack/plugins/lens/public/datasources/text_based/components/dimension_editor.tsx new file mode 100644 index 0000000000000..8971696fc9028 --- /dev/null +++ b/x-pack/plugins/lens/public/datasources/text_based/components/dimension_editor.tsx @@ -0,0 +1,111 @@ +/* + * 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 React from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiFormRow } from '@elastic/eui'; +import { euiThemeVars } from '@kbn/ui-theme'; +import type { ExpressionsStart } from '@kbn/expressions-plugin/public'; +import type { DatasourceDimensionEditorProps, DataType } from '../../../types'; +import { FieldSelect } from './field_select'; +import type { TextBasedPrivateState } from '../types'; +import { retrieveLayerColumnsFromCache, getColumnsFromCache } from '../fieldlist_cache'; + +export type TextBasedDimensionEditorProps = + DatasourceDimensionEditorProps & { + expressions: ExpressionsStart; + }; + +export function TextBasedDimensionEditor(props: TextBasedDimensionEditorProps) { + const query = props.state.layers[props.layerId]?.query; + + const allColumns = retrieveLayerColumnsFromCache( + props.state.layers[props.layerId]?.columns ?? [], + query + ); + const allFields = query ? getColumnsFromCache(query) : []; + const hasNumberTypeColumns = allColumns?.some((c) => c?.meta?.type === 'number'); + const fields = allFields.map((col) => { + return { + id: col.id, + name: col.name, + meta: col?.meta ?? { type: 'number' }, + compatible: + props.isMetricDimension && hasNumberTypeColumns + ? props.filterOperations({ + dataType: col?.meta?.type as DataType, + isBucketed: Boolean(col?.meta?.type !== 'number'), + scale: 'ordinal', + }) + : true, + }; + }); + const selectedField = allColumns?.find((column) => column.columnId === props.columnId); + + return ( + <> + + { + const meta = fields?.find((f) => f.name === choice.field)?.meta; + const newColumn = { + columnId: props.columnId, + fieldName: choice.field, + meta, + }; + return props.setState( + !selectedField + ? { + ...props.state, + layers: { + ...props.state.layers, + [props.layerId]: { + ...props.state.layers[props.layerId], + columns: [...props.state.layers[props.layerId].columns, newColumn], + }, + }, + } + : { + ...props.state, + layers: { + ...props.state.layers, + [props.layerId]: { + ...props.state.layers[props.layerId], + columns: props.state.layers[props.layerId].columns.map((col) => + col.columnId !== props.columnId + ? col + : { ...col, fieldName: choice.field, meta } + ), + }, + }, + } + ); + }} + /> + + {props.dataSectionExtra && ( +
+ {props.dataSectionExtra} +
+ )} + + ); +} diff --git a/x-pack/plugins/lens/public/datasources/text_based/components/dimension_trigger.tsx b/x-pack/plugins/lens/public/datasources/text_based/components/dimension_trigger.tsx new file mode 100644 index 0000000000000..b1eec31ea3892 --- /dev/null +++ b/x-pack/plugins/lens/public/datasources/text_based/components/dimension_trigger.tsx @@ -0,0 +1,65 @@ +/* + * 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 React, { useEffect, useState } from 'react'; +import { i18n } from '@kbn/i18n'; +import { DimensionTrigger } from '@kbn/visualization-ui-components'; +import type { ExpressionsStart } from '@kbn/expressions-plugin/public'; +import type { DatasourceDimensionTriggerProps } from '../../../types'; +import type { TextBasedPrivateState } from '../types'; +import { + getColumnsFromCache, + addColumnsToCache, + retrieveLayerColumnsFromCache, +} from '../fieldlist_cache'; +import { fetchFieldsFromESQL } from '../fetch_fields_from_esql'; + +export type TextBasedDimensionTrigger = DatasourceDimensionTriggerProps & { + columnLabelMap: Record; + expressions: ExpressionsStart; +}; + +export function TextBasedDimensionTrigger(props: TextBasedDimensionTrigger) { + const [dataHasLoaded, setDataHasLoaded] = useState(false); + const query = props.state.layers[props.layerId]?.query; + useEffect(() => { + // in case the columns are not in the cache, I refetch them + async function fetchColumns() { + const fieldList = query ? getColumnsFromCache(query) : []; + + if (fieldList.length === 0 && query) { + const table = await fetchFieldsFromESQL(query, props.expressions); + if (table) { + addColumnsToCache(query, table.columns); + } + } + setDataHasLoaded(true); + } + fetchColumns(); + }, [props.expressions, query]); + const allColumns = dataHasLoaded + ? retrieveLayerColumnsFromCache(props.state.layers[props.layerId]?.columns ?? [], query) + : []; + const selectedField = allColumns?.find((column) => column.columnId === props.columnId); + let customLabel: string | undefined = props.columnLabelMap[props.columnId]; + if (!customLabel) { + customLabel = selectedField?.fieldName; + } + return ( + + ); +} diff --git a/x-pack/plugins/lens/public/datasources/text_based/field_select.test.tsx b/x-pack/plugins/lens/public/datasources/text_based/components/field_select.test.tsx similarity index 100% rename from x-pack/plugins/lens/public/datasources/text_based/field_select.test.tsx rename to x-pack/plugins/lens/public/datasources/text_based/components/field_select.test.tsx diff --git a/x-pack/plugins/lens/public/datasources/text_based/field_select.tsx b/x-pack/plugins/lens/public/datasources/text_based/components/field_select.tsx similarity index 96% rename from x-pack/plugins/lens/public/datasources/text_based/field_select.tsx rename to x-pack/plugins/lens/public/datasources/text_based/components/field_select.tsx index 3561697900bb4..3dd28dba55762 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/field_select.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/components/field_select.tsx @@ -10,8 +10,8 @@ import { EuiComboBoxOptionOption, EuiComboBoxProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import type { DatatableColumn } from '@kbn/expressions-plugin/public'; import { FieldPicker, FieldOptionValue, FieldOption } from '@kbn/visualization-ui-components'; -import type { TextBasedLayerColumn } from './types'; -import type { DataType } from '../../types'; +import type { TextBasedLayerColumn } from '../types'; +import type { DataType } from '../../../types'; export interface FieldOptionCompatible extends DatatableColumn { compatible: boolean; diff --git a/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.test.tsx b/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.test.tsx index 9b368050b0567..b7f90853b6610 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.test.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.test.tsx @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import type { DatatableColumn } from '@kbn/expressions-plugin/common'; import { DatasourceDimensionDropHandlerProps } from '../../../types'; import { getDropProps } from './get_drop_props'; import { @@ -13,18 +13,20 @@ import { column3, numericDraggedColumn, fieldList, - fieldListNonNumericOnly, notNumericDraggedField, numericDraggedField, } from './mocks'; import { TextBasedPrivateState } from '../types'; +import { addColumnsToCache } from '../fieldlist_cache'; const defaultProps = { state: { layers: { first: { columns: [column1, column2, column3], - allColumns: [...fieldList, column1, column2, column3], + query: { + esql: 'from foo', + }, }, }, }, @@ -42,7 +44,19 @@ const defaultProps = { }, }, } as unknown as DatasourceDimensionDropHandlerProps; - +const allColumns = [...fieldList, column1, column2, column3].map((f) => { + return { + id: f.columnId, + name: f.fieldName, + meta: f?.meta, + }; +}) as DatatableColumn[]; +addColumnsToCache( + { + esql: 'from foo', + }, + allColumns +); describe('Text-based: getDropProps', () => { it('should return undefined if source and target belong to different layers', () => { const props = { @@ -82,7 +96,6 @@ describe('Text-based: getDropProps', () => { layers: { first: { columns: [column1, column2, column3], - allColumns: [...fieldListNonNumericOnly, column1, column2, column3], }, }, }, diff --git a/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.tsx b/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.tsx index 78e1c98f3a301..bbbf7869849c4 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/dnd/get_drop_props.tsx @@ -11,6 +11,7 @@ import type { TextBasedPrivateState } from '../types'; import type { GetDropPropsArgs } from '../../../types'; import { isDraggedField, isOperationFromTheSameGroup } from '../../../utils'; import { canColumnBeDroppedInMetricDimension } from '../utils'; +import { retrieveLayerColumnsFromCache } from '../fieldlist_cache'; export const getDropProps = ( props: GetDropPropsArgs @@ -20,9 +21,10 @@ export const getDropProps = ( return; } const layer = state.layers[target.layerId]; + const allColumns = retrieveLayerColumnsFromCache(layer.columns, layer.query); const targetColumn = layer.columns.find((f) => f.columnId === target.columnId); - const targetField = layer.allColumns.find((f) => f.columnId === target.columnId); - const sourceField = layer.allColumns.find((f) => f.columnId === source.id); + const targetField = allColumns.find((f) => f.columnId === target.columnId); + const sourceField = allColumns.find((f) => f.columnId === source.id); if (isDraggedField(source)) { const nextLabel = source.humanData.label; @@ -46,12 +48,12 @@ export const getDropProps = ( } const sourceFieldCanMoveToMetricDimension = canColumnBeDroppedInMetricDimension( - layer.allColumns, + allColumns, sourceField?.meta?.type ); const targetFieldCanMoveToMetricDimension = canColumnBeDroppedInMetricDimension( - layer.allColumns, + allColumns, targetField?.meta?.type ); diff --git a/x-pack/plugins/lens/public/datasources/text_based/dnd/mocks.tsx b/x-pack/plugins/lens/public/datasources/text_based/dnd/mocks.tsx index c657290b00759..46a13f112ec69 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/dnd/mocks.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/dnd/mocks.tsx @@ -152,10 +152,9 @@ export const defaultProps = { first: { index: 'indexId', query: { - sql: 'SELECT * FROM "kibana_sample_data_ecommerce"', + esql: 'SELECT * FROM "kibana_sample_data_ecommerce"', }, columns: [column1, column2, column3], - allColumns: [...fieldList, column1, column2, column3], errors: [], }, }, diff --git a/x-pack/plugins/lens/public/datasources/text_based/dnd/on_drop.test.ts b/x-pack/plugins/lens/public/datasources/text_based/dnd/on_drop.test.ts index bbcca24f3a943..291b4cb9a29d2 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/dnd/on_drop.test.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/dnd/on_drop.test.ts @@ -6,12 +6,26 @@ */ import { DropType } from '@kbn/dom-drag-drop'; +import type { DatatableColumn } from '@kbn/expressions-plugin/common'; import { onDrop } from './on_drop'; import { column1, column2, column3, emptyDimensionTarget, defaultProps, fieldList } from './mocks'; import { DatasourceDimensionDropHandlerProps } from '../../../types'; import { TextBasedPrivateState } from '../types'; +import { addColumnsToCache } from '../fieldlist_cache'; describe('onDrop', () => { + addColumnsToCache( + { + esql: 'SELECT * FROM "kibana_sample_data_ecommerce"', + }, + fieldList.map((f) => { + return { + id: f.columnId, + name: f.fieldName, + meta: f?.meta, + } as DatatableColumn; + }) + ); it('should return false if dropType is not in the list', () => { const props = { ...defaultProps, @@ -34,7 +48,6 @@ describe('onDrop', () => { layers: { first: expect.objectContaining({ columns: expectedColumns, - allColumns: [...fieldList, ...expectedColumns], }), }, }) @@ -51,7 +64,6 @@ describe('onDrop', () => { layers: { first: expect.objectContaining({ columns: expectedColumns, - allColumns: [...fieldList, ...expectedColumns], }), }, }) @@ -69,13 +81,6 @@ describe('onDrop', () => { layers: { first: expect.objectContaining({ columns: expectedColumns, - allColumns: [ - ...fieldList, - column1, - column2, - column3, - { ...column1, columnId: 'newId' }, - ], }), }, }) @@ -120,7 +125,6 @@ describe('onDrop', () => { layers: { first: expect.objectContaining({ columns: expectedColumns, - allColumns: [...fieldList, ...expectedColumns], }), }, }) @@ -148,7 +152,6 @@ describe('onDrop', () => { layers: { first: expect.objectContaining({ columns: expectedColumns, - allColumns: [...fieldList, ...expectedColumns], }), }, }) @@ -165,7 +168,6 @@ describe('onDrop', () => { layers: { first: expect.objectContaining({ columns: expectedColumns, - allColumns: [...fieldList, ...expectedColumns], }), }, }) diff --git a/x-pack/plugins/lens/public/datasources/text_based/dnd/on_drop.ts b/x-pack/plugins/lens/public/datasources/text_based/dnd/on_drop.ts index 22c3d5b5f4436..5dc90cd4b4a21 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/dnd/on_drop.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/dnd/on_drop.ts @@ -9,6 +9,7 @@ import type { TextBasedLayerColumn, TextBasedPrivateState } from '../types'; import { reorderElements } from '../../../utils'; import { DatasourceDimensionDropHandlerProps, isOperation } from '../../../types'; import { removeColumn } from '../remove_column'; +import { retrieveLayerColumnsFromCache } from '../fieldlist_cache'; export const onDrop = (props: DatasourceDimensionDropHandlerProps) => { const { dropType, state, source, target } = props; @@ -28,31 +29,28 @@ export const onDrop = (props: DatasourceDimensionDropHandlerProps f.columnId === source.id); - const targetField = layer.allColumns.find((f) => f.columnId === target.columnId); + const allColumns = retrieveLayerColumnsFromCache(layer.columns, layer.query); + const sourceField = allColumns.find((f) => f.columnId === source.id); + const targetField = allColumns.find((f) => f.columnId === target.columnId); const newColumn = { columnId: target.columnId, fieldName: sourceField?.fieldName ?? '', meta: sourceField?.meta, }; let columns: TextBasedLayerColumn[] | undefined; - let allColumns: TextBasedLayerColumn[] | undefined; switch (dropType) { case 'field_add': case 'duplicate_compatible': case 'replace_duplicate_compatible': columns = [...layer.columns.filter((c) => c.columnId !== target.columnId), newColumn]; - allColumns = [...layer.allColumns.filter((c) => c.columnId !== target.columnId), newColumn]; break; case 'field_replace': case 'replace_compatible': columns = layer.columns.map((c) => (c.columnId === target.columnId ? newColumn : c)); - allColumns = layer.allColumns.map((c) => (c.columnId === target.columnId ? newColumn : c)); break; case 'move_compatible': columns = [...layer.columns, newColumn]; - allColumns = [...layer.allColumns, newColumn]; break; case 'swap_compatible': const swapTwoColumns = (c: TextBasedLayerColumn) => @@ -66,18 +64,16 @@ export const onDrop = (props: DatasourceDimensionDropHandlerProps f.columnId === target.columnId); const sourceColumn = layer.columns.find((f) => f.columnId === source.id); if (!targetColumn || !sourceColumn) return; columns = reorderElements(layer.columns, targetColumn, sourceColumn); - allColumns = reorderElements(layer.allColumns, targetColumn, sourceColumn); break; } - if (!columns || !allColumns) return; + if (!columns) return; const newState = { ...props.state, diff --git a/x-pack/plugins/lens/public/datasources/text_based/fetch_fields_from_esql.ts b/x-pack/plugins/lens/public/datasources/text_based/fetch_fields_from_esql.ts new file mode 100644 index 0000000000000..e19fde19187ff --- /dev/null +++ b/x-pack/plugins/lens/public/datasources/text_based/fetch_fields_from_esql.ts @@ -0,0 +1,52 @@ +/* + * 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 { pluck } from 'rxjs/operators'; +import { lastValueFrom } from 'rxjs'; +import type { Query, AggregateQuery } from '@kbn/es-query'; +import type { ExpressionsStart } from '@kbn/expressions-plugin/public'; +import type { Datatable } from '@kbn/expressions-plugin/public'; +import { textBasedQueryStateToAstWithValidation } from '@kbn/data-plugin/common'; + +interface TextBasedLanguagesErrorResponse { + error: { + message: string; + }; + type: 'error'; +} + +export function fetchFieldsFromESQL(query: Query | AggregateQuery, expressions: ExpressionsStart) { + return textBasedQueryStateToAstWithValidation({ + query, + }) + .then((ast) => { + if (ast) { + const execution = expressions.run(ast, null); + let finalData: Datatable; + let error: string | undefined; + execution.pipe(pluck('result')).subscribe((resp) => { + const response = resp as Datatable | TextBasedLanguagesErrorResponse; + if (response.type === 'error') { + error = response.error.message; + } else { + finalData = response; + } + }); + return lastValueFrom(execution).then(() => { + if (error) { + throw new Error(error); + } else { + return finalData; + } + }); + } + return undefined; + }) + .catch((err) => { + throw new Error(err.message); + }); +} diff --git a/x-pack/plugins/lens/public/datasources/text_based/fieldlist_cache.ts b/x-pack/plugins/lens/public/datasources/text_based/fieldlist_cache.ts index eaf2c201835ab..693a949ef8cd7 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/fieldlist_cache.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/fieldlist_cache.ts @@ -4,16 +4,33 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import { type AggregateQuery, getAggregateQueryMode } from '@kbn/es-query'; import type { DatatableColumn } from '@kbn/expressions-plugin/public'; +import { getAllColumns } from './utils'; +import type { TextBasedLayerColumn } from './types'; const cachedColumns = new Map(); -export const addColumnsToCache = (query: string, list: DatatableColumn[]) => { - const trimmedQuery = query.replaceAll('\n', '').trim(); +const getKey = (query: AggregateQuery) => { + const language = getAggregateQueryMode(query); + const queryString: string = query[language]; + return queryString.replaceAll('\n', '').trim(); +}; + +export const addColumnsToCache = (query: AggregateQuery, list: DatatableColumn[]) => { + const trimmedQuery = getKey(query); cachedColumns.set(trimmedQuery, list); }; -export const getColumnsFromCache = (query: string) => { - const trimmedQuery = query.replaceAll('\n', '').trim(); - return cachedColumns.get(trimmedQuery); +export const getColumnsFromCache = (query: AggregateQuery) => { + const trimmedQuery = getKey(query); + return cachedColumns.get(trimmedQuery) ?? []; +}; + +export const retrieveLayerColumnsFromCache = ( + existingColumns: TextBasedLayerColumn[], + query?: AggregateQuery +): TextBasedLayerColumn[] => { + const columnsFromCache = query ? getColumnsFromCache(query) : []; + return getAllColumns(existingColumns, columnsFromCache); }; diff --git a/x-pack/plugins/lens/public/datasources/text_based/remove_column.ts b/x-pack/plugins/lens/public/datasources/text_based/remove_column.ts index 2228492dc2b88..6d28b85b7becf 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/remove_column.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/remove_column.ts @@ -20,7 +20,6 @@ export const removeColumn: Datasource['removeColumn'] = ( [layerId]: { ...prevState.layers[layerId], columns: prevState.layers[layerId].columns.filter((col) => col.columnId !== columnId), - allColumns: prevState.layers[layerId].allColumns, }, }, }; diff --git a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts index 032c99a6b5780..cdd3bbdbb4cba 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.test.ts @@ -14,7 +14,6 @@ import { dataViewPluginMocks } from '@kbn/data-views-plugin/public/mocks'; import { getTextBasedDatasource } from './text_based_languages'; import { generateId } from '../../id_generator'; import { DatasourcePublicAPI, Datasource, FramePublicAPI } from '../../types'; - jest.mock('../../id_generator'); const fieldsOne = [ @@ -106,15 +105,6 @@ describe('Textbased Data Source', () => { }, }, ], - allColumns: [ - { - columnId: 'col1', - fieldName: 'Test 1', - meta: { - type: 'number', - }, - }, - ], index: 'foo', query: { esql: 'FROM foo' }, }, @@ -208,15 +198,6 @@ describe('Textbased Data Source', () => { layers: { a: { columns: [], - allColumns: [ - { - columnId: 'col1', - fieldName: 'Test 1', - meta: { - type: 'string', - }, - }, - ], query: { esql: 'FROM foo' }, index: 'foo', }, @@ -253,15 +234,6 @@ describe('Textbased Data Source', () => { newLayer: { index: 'foo', query: { esql: 'FROM foo' }, - allColumns: [ - { - columnId: 'col1', - fieldName: 'Test 1', - meta: { - type: 'number', - }, - }, - ], columns: [], }, }, @@ -278,15 +250,6 @@ describe('Textbased Data Source', () => { layers: { a: { columns: [], - allColumns: [ - { - columnId: 'col1', - fieldName: 'Test 1', - meta: { - type: 'number', - }, - }, - ], query: { esql: 'FROM foo' }, index: 'foo', }, @@ -327,22 +290,6 @@ describe('Textbased Data Source', () => { }, }, ], - allColumns: [ - { - columnId: 'a', - fieldName: 'Test 1', - meta: { - type: 'number', - }, - }, - { - columnId: 'b', - fieldName: 'Test 2', - meta: { - type: 'number', - }, - }, - ], query: { esql: 'FROM foo' }, index: 'foo', }, @@ -401,23 +348,6 @@ describe('Textbased Data Source', () => { ], layers: { newid: { - allColumns: [ - { - columnId: 'bytes', - fieldName: 'bytes', - inMetricDimension: true, - meta: { - type: 'number', - }, - }, - { - columnId: 'dest', - fieldName: 'dest', - meta: { - type: 'string', - }, - }, - ], columns: [ { columnId: 'bytes', @@ -552,24 +482,6 @@ describe('Textbased Data Source', () => { ], layers: { newid: { - allColumns: [ - { - columnId: '@timestamp', - fieldName: '@timestamp', - inMetricDimension: true, - meta: { - type: 'date', - }, - }, - { - columnId: 'dest', - fieldName: 'dest', - inMetricDimension: true, - meta: { - type: 'string', - }, - }, - ], columns: [ { columnId: '@timestamp', @@ -623,58 +535,6 @@ describe('Textbased Data Source', () => { }); }); - describe('#suggestsLimitedColumns', () => { - it('should return true if query returns big number of columns', () => { - const state = { - totalFields: 5, - layers: { - a: { - query: { esql: 'from foo' }, - index: 'foo', - allColumns: [ - { - id: 'a', - name: 'Test 1', - meta: { - type: 'number', - }, - }, - { - id: 'b', - name: 'Test 2', - meta: { - type: 'number', - }, - }, - { - id: 'c', - name: 'Test 3', - meta: { - type: 'date', - }, - }, - { - id: 'd', - name: 'Test 4', - meta: { - type: 'string', - }, - }, - { - id: 'e', - name: 'Test 5', - meta: { - type: 'string', - }, - }, - ], - }, - }, - } as unknown as TextBasedPrivateState; - expect(TextBasedDatasource?.suggestsLimitedColumns?.(state)).toBeTruthy(); - }); - }); - describe('#getUserMessages', () => { it('should use the results of getUserMessages directly when single layer', () => { const state = { @@ -696,22 +556,6 @@ describe('Textbased Data Source', () => { }, }, ], - allColumns: [ - { - columnId: 'a', - fieldName: 'Test 1', - meta: { - type: 'number', - }, - }, - { - columnId: 'b', - fieldName: 'Test 2', - meta: { - type: 'number', - }, - }, - ], errors: [new Error('error 1'), new Error('error 2')], query: { esql: 'FROM foo' }, index: 'foo', @@ -779,22 +623,6 @@ describe('Textbased Data Source', () => { }, }, ], - allColumns: [ - { - columnId: 'a', - fieldName: 'Test 1', - meta: { - type: 'number', - }, - }, - { - columnId: 'b', - fieldName: 'Test 2', - meta: { - type: 'number', - }, - }, - ], query: { esql: 'FROM foo' }, index: '1', }, @@ -826,22 +654,6 @@ describe('Textbased Data Source', () => { }, }, ], - allColumns: [ - { - columnId: 'a', - fieldName: 'Test 1', - meta: { - type: 'number', - }, - }, - { - columnId: 'b', - fieldName: 'Test 2', - meta: { - type: 'number', - }, - }, - ], query: { esql: 'FROM foo' }, index: '1', }, @@ -884,22 +696,6 @@ describe('Textbased Data Source', () => { }, }, ], - allColumns: [ - { - columnId: 'a', - fieldName: 'Test 1', - meta: { - type: 'number', - }, - }, - { - columnId: 'b', - fieldName: 'Test 2', - meta: { - type: 'number', - }, - }, - ], query: { esql: 'FROM foo' }, index: '1', }, diff --git a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx index d9be929567bae..0e78704ae95f2 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx +++ b/x-pack/plugins/lens/public/datasources/text_based/text_based_languages.tsx @@ -8,19 +8,17 @@ import React from 'react'; import { CoreStart } from '@kbn/core/public'; -import { i18n } from '@kbn/i18n'; import { IStorageWrapper } from '@kbn/kibana-utils-plugin/public'; import { AggregateQuery, isOfAggregateQueryType, getAggregateQueryMode } from '@kbn/es-query'; import type { SavedObjectReference } from '@kbn/core/public'; -import { EuiFormRow } from '@elastic/eui'; import type { ExpressionsStart } from '@kbn/expressions-plugin/public'; import type { DataViewsPublicPluginStart, DataView } from '@kbn/data-views-plugin/public'; import type { DataPublicPluginStart } from '@kbn/data-plugin/public'; -import { euiThemeVars } from '@kbn/ui-theme'; -import { DimensionTrigger } from '@kbn/visualization-ui-components'; import memoizeOne from 'memoize-one'; import { isEqual } from 'lodash'; -import { TextBasedDataPanel } from './datapanel'; +import { TextBasedDataPanel } from './components/datapanel'; +import { TextBasedDimensionEditor } from './components/dimension_editor'; +import { TextBasedDimensionTrigger } from './components/dimension_trigger'; import { toExpression } from './to_expression'; import { DatasourceDimensionEditorProps, @@ -40,13 +38,16 @@ import type { TextBasedLayerColumn, TextBasedField, } from './types'; -import { FieldSelect } from './field_select'; import type { Datasource } from '../../types'; import { getUniqueLabelGenerator, nonNullable } from '../../utils'; import { onDrop, getDropProps } from './dnd'; import { removeColumn } from './remove_column'; import { canColumnBeUsedBeInMetricDimension, MAX_NUM_OF_COLUMNS } from './utils'; -import { getColumnsFromCache, addColumnsToCache } from './fieldlist_cache'; +import { + getColumnsFromCache, + addColumnsToCache, + retrieveLayerColumnsFromCache, +} from './fieldlist_cache'; function getLayerReferenceName(layerId: string) { return `textBasedLanguages-datasource-layer-${layerId}`; @@ -79,6 +80,7 @@ export function getTextBasedDatasource({ }) { const getSuggestionsForState = (state: TextBasedPrivateState) => { return Object.entries(state.layers)?.map(([id, layer]) => { + const allColumns = retrieveLayerColumnsFromCache(layer.columns, layer.query); return { state: { ...state, @@ -90,7 +92,7 @@ export function getTextBasedDatasource({ columns: layer.columns?.map((f) => { const inMetricDimension = canColumnBeUsedBeInMetricDimension( - layer.allColumns, + allColumns, f?.meta?.type ); return { @@ -142,8 +144,7 @@ export function getTextBasedDatasource({ }; }); - const language = getAggregateQueryMode(context.query); - addColumnsToCache(context.query[language], textBasedQueryColumns); + addColumnsToCache(context.query, textBasedQueryColumns); const index = context.dataViewSpec.id ?? context.dataViewSpec.title; const query = context.query; @@ -167,7 +168,6 @@ export function getTextBasedDatasource({ index, query, columns: newColumns.slice(0, MAX_NUM_OF_COLUMNS) ?? [], - allColumns: newColumns ?? [], timeField: context.dataViewSpec.timeFieldName, }, }, @@ -278,7 +278,6 @@ export function getTextBasedDatasource({ insertLayer(state: TextBasedPrivateState, newLayerId: string) { const layer = Object.values(state?.layers)?.[0]; const query = layer?.query; - const columns = layer?.allColumns ?? []; const index = layer?.index ?? (JSON.parse(localStorage.getItem('lens-settings') || '{}').indexPatternId || @@ -287,7 +286,7 @@ export function getTextBasedDatasource({ ...state, layers: { ...state.layers, - [newLayerId]: blankLayer(index, query, columns), + [newLayerId]: blankLayer(index, query), }, }; }, @@ -338,14 +337,6 @@ export function getTextBasedDatasource({ getLayers(state: TextBasedPrivateState) { return state && state.layers ? Object.keys(state?.layers) : []; }, - // there are cases where a query can return a big amount of columns - // at this case we don't suggest all columns in a table but the first - // MAX_NUM_OF_COLUMNS - suggestsLimitedColumns(state: TextBasedPrivateState) { - const layers = Object.values(state.layers); - const allColumns = layers[0].allColumns; - return allColumns.length >= MAX_NUM_OF_COLUMNS; - }, isTimeBased: (state, indexPatterns) => { if (!state) return false; const { layers } = state; @@ -390,24 +381,11 @@ export function getTextBasedDatasource({ DimensionTriggerComponent: (props: DatasourceDimensionTriggerProps) => { const columnLabelMap = TextBasedDatasource.uniqueLabels(props.state, props.indexPatterns); - const layer = props.state.layers[props.layerId]; - const selectedField = layer?.allColumns?.find((column) => column.columnId === props.columnId); - let customLabel: string | undefined = columnLabelMap[props.columnId]; - if (!customLabel) { - customLabel = selectedField?.fieldName; - } - return ( - ); }, @@ -423,101 +401,7 @@ export function getTextBasedDatasource({ }, DimensionEditorComponent: (props: DatasourceDimensionEditorProps) => { - const allColumns = props.state.layers[props.layerId]?.allColumns; - const fields = allColumns.map((col) => { - return { - id: col.columnId, - name: col.fieldName, - meta: col?.meta ?? { type: 'number' }, - }; - }); - const selectedField = allColumns?.find((column) => column.columnId === props.columnId); - const hasNumberTypeColumns = allColumns?.some((c) => c?.meta?.type === 'number'); - - const updatedFields = fields?.map((f) => { - return { - ...f, - compatible: - props.isMetricDimension && hasNumberTypeColumns - ? props.filterOperations({ - dataType: f.meta.type as DataType, - isBucketed: Boolean(f?.meta?.type !== 'number'), - scale: 'ordinal', - }) - : true, - }; - }); - return ( - <> - - { - const meta = fields?.find((f) => f.name === choice.field)?.meta; - const newColumn = { - columnId: props.columnId, - fieldName: choice.field, - meta, - }; - return props.setState( - !selectedField - ? { - ...props.state, - layers: { - ...props.state.layers, - [props.layerId]: { - ...props.state.layers[props.layerId], - columns: [...props.state.layers[props.layerId].columns, newColumn], - allColumns: [ - ...props.state.layers[props.layerId].allColumns, - newColumn, - ], - }, - }, - } - : { - ...props.state, - layers: { - ...props.state.layers, - [props.layerId]: { - ...props.state.layers[props.layerId], - columns: props.state.layers[props.layerId].columns.map((col) => - col.columnId !== props.columnId - ? col - : { ...col, fieldName: choice.field, meta } - ), - allColumns: props.state.layers[props.layerId].allColumns.map((col) => - col.columnId !== props.columnId - ? col - : { ...col, fieldName: choice.field, meta } - ), - }, - }, - } - ); - }} - /> - - {props.dataSectionExtra && ( -
- {props.dataSectionExtra} -
- )} - - ); + return ; }, LayerPanelComponent: (props: DatasourceLayerPanelProps) => { @@ -556,7 +440,7 @@ export function getTextBasedDatasource({ }, getOperationForColumnId: (columnId: string) => { const layer = state.layers[layerId]; - const column = layer?.allColumns?.find((c) => c.columnId === columnId); + const column = layer?.columns?.find((c) => c.columnId === columnId); const columnLabelMap = TextBasedDatasource.uniqueLabels(state, indexPatterns); if (column) { @@ -598,7 +482,7 @@ export function getTextBasedDatasource({ getDatasourceSuggestionsForField(state, draggedField) { const layers = Object.values(state.layers); const query = layers?.[0]?.query; - const fieldList = query ? getColumnsFromCache(query[getAggregateQueryMode(query)]) : []; + const fieldList = query ? getColumnsFromCache(query) : []; const field = fieldList?.find((f) => f.id === (draggedField as TextBasedField).id); if (!field) return []; return Object.entries(state.layers)?.map(([id, layer]) => { @@ -616,7 +500,6 @@ export function getTextBasedDatasource({ [id]: { ...state.layers[id], columns: [...layer.columns, newColumn], - allColumns: [...layer.allColumns, newColumn], }, }, }, @@ -699,11 +582,10 @@ export function getTextBasedDatasource({ return TextBasedDatasource; } -function blankLayer(index: string, query?: AggregateQuery, columns?: TextBasedLayerColumn[]) { +function blankLayer(index: string, query?: AggregateQuery) { return { index, query, columns: [], - allColumns: columns ?? [], }; } diff --git a/x-pack/plugins/lens/public/datasources/text_based/types.ts b/x-pack/plugins/lens/public/datasources/text_based/types.ts index 8cbf2cdf0d1a1..452f9a8cc59da 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/types.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/types.ts @@ -26,7 +26,6 @@ export interface TextBasedLayer { query: AggregateQuery | undefined; table?: Datatable; columns: TextBasedLayerColumn[]; - allColumns: TextBasedLayerColumn[]; timeField?: string; errors?: Error[]; } diff --git a/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts b/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts index 2c82eb9450f7d..69cc7cfb3f7cd 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/utils.test.ts @@ -181,7 +181,6 @@ describe('Text based languages utils', () => { const state = { layers: { first: { - allColumns: [], columns: [], query: undefined, index: '', @@ -270,29 +269,6 @@ describe('Text based languages utils', () => { ], layers: { first: { - allColumns: [ - { - fieldName: 'timestamp', - columnId: 'timestamp', - meta: { - type: 'date', - }, - }, - { - fieldName: 'bytes', - columnId: 'bytes', - meta: { - type: 'number', - }, - }, - { - fieldName: 'memory', - columnId: 'memory', - meta: { - type: 'number', - }, - }, - ], columns: [], errors: [], index: '4', @@ -309,7 +285,6 @@ describe('Text based languages utils', () => { const state = { layers: { first: { - allColumns: [], columns: [], query: undefined, index: '', @@ -403,29 +378,6 @@ describe('Text based languages utils', () => { ], layers: { first: { - allColumns: [ - { - fieldName: 'timestamp', - columnId: 'timestamp', - meta: { - type: 'date', - }, - }, - { - fieldName: 'bytes', - columnId: 'bytes', - meta: { - type: 'number', - }, - }, - { - fieldName: 'memory', - columnId: 'memory', - meta: { - type: 'number', - }, - }, - ], columns: [], errors: [], index: 'adHoc-id', diff --git a/x-pack/plugins/lens/public/datasources/text_based/utils.ts b/x-pack/plugins/lens/public/datasources/text_based/utils.ts index 5486f210bf981..856e608d347e1 100644 --- a/x-pack/plugins/lens/public/datasources/text_based/utils.ts +++ b/x-pack/plugins/lens/public/datasources/text_based/utils.ts @@ -12,7 +12,6 @@ import { type AggregateQuery, getIndexPatternFromSQLQuery, getIndexPatternFromESQLQuery, - getAggregateQueryMode, } from '@kbn/es-query'; import type { DatatableColumn } from '@kbn/expressions-plugin/public'; import { generateId } from '../../id_generator'; @@ -88,7 +87,6 @@ export async function getStateFromAggregateQuery( // get the id of the dataview let dataViewId = indexPatternRefs.find((r) => r.title === indexPattern)?.id ?? ''; let columnsFromQuery: DatatableColumn[] = []; - let allColumns: TextBasedLayerColumn[] = []; let timeFieldName; try { const dataView = await dataViews.create({ @@ -111,9 +109,7 @@ export async function getStateFromAggregateQuery( timeFieldName = dataView.timeFieldName; const table = await fetchDataFromAggregateQuery(query, dataView, data, expressions); columnsFromQuery = table?.columns ?? []; - const language = getAggregateQueryMode(query); - addColumnsToCache(query[language], columnsFromQuery); - allColumns = getAllColumns(state.layers[newLayerId].allColumns, columnsFromQuery); + addColumnsToCache(query, columnsFromQuery); } catch (e) { errors.push(e); } @@ -124,7 +120,6 @@ export async function getStateFromAggregateQuery( index: dataViewId, query, columns: state.layers[newLayerId].columns ?? [], - allColumns, timeField: timeFieldName, errors, }, diff --git a/x-pack/plugins/lens/public/mocks/suggestions_mock.ts b/x-pack/plugins/lens/public/mocks/suggestions_mock.ts index 0ed32fbfd84da..c371f283ad964 100644 --- a/x-pack/plugins/lens/public/mocks/suggestions_mock.ts +++ b/x-pack/plugins/lens/public/mocks/suggestions_mock.ts @@ -56,22 +56,6 @@ export const currentSuggestionMock = { }, }, ], - allColumns: [ - { - columnId: '81e332d6-ee37-42a8-a646-cea4fc75d2d3', - fieldName: 'Dest', - meta: { - type: 'string', - }, - }, - { - columnId: '5b9b8b76-0836-4a12-b9c0-980c9900502f', - fieldName: 'AvgTicketPrice', - meta: { - type: 'number', - }, - }, - ], timeField: 'timestamp', }, }, @@ -195,22 +179,6 @@ export const mockAllSuggestions = [ }, }, ], - allColumns: [ - { - columnId: '923f0681-3fe1-4987-aa27-d9c91fb95fa6', - fieldName: 'Dest', - meta: { - type: 'string', - }, - }, - { - columnId: 'b5f41c04-4bca-4abe-ae5c-b1d4d6fb00e0', - fieldName: 'AvgTicketPrice', - meta: { - type: 'number', - }, - }, - ], timeField: 'timestamp', }, }, diff --git a/x-pack/plugins/lens/public/types.ts b/x-pack/plugins/lens/public/types.ts index e5c9fad96d6ca..53bb59c0a5459 100644 --- a/x-pack/plugins/lens/public/types.ts +++ b/x-pack/plugins/lens/public/types.ts @@ -511,8 +511,6 @@ export interface Datasource { ) => Promise; injectReferencesToLayers?: (state: T, references?: SavedObjectReference[]) => T; - - suggestsLimitedColumns?: (state: T) => boolean; } export interface DatasourceFixAction {