diff --git a/src/fixtures/stubbed_saved_object_index_pattern.ts b/src/fixtures/stubbed_saved_object_index_pattern.ts index 20a0474e1bd7..1100a987e287 100644 --- a/src/fixtures/stubbed_saved_object_index_pattern.ts +++ b/src/fixtures/stubbed_saved_object_index_pattern.ts @@ -33,8 +33,8 @@ import stubbedLogstashFields from './logstash_fields'; const mockLogstashFields = stubbedLogstashFields(); -export function stubbedSavedObjectIndexPattern(id: string | null = null) { - return { +export function stubbedSavedObjectIndexPattern(id: string | null = null, withDataSource?: false) { + const indexPattern: any = { id, type: 'index-pattern', attributes: { @@ -45,4 +45,16 @@ export function stubbedSavedObjectIndexPattern(id: string | null = null) { }, version: '2', }; + + if (withDataSource) { + indexPattern.reference = [ + { + id: 'id', + name: 'name', + type: 'data-source', + }, + ]; + } + + return indexPattern; } diff --git a/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap b/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap index ed84aceb60e5..32dd9fa3fa26 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap +++ b/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_pattern.test.ts.snap @@ -2,6 +2,649 @@ exports[`IndexPattern toSpec should match snapshot 1`] = ` Object { + "dataSourceRef": undefined, + "fields": Object { + "@tags": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "keyword", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "@tags", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "string", + }, + "@timestamp": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 30, + "esTypes": Array [ + "date", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "@timestamp", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "date", + }, + "_id": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "_id", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "_id", + "readFromDocValues": false, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "string", + }, + "_source": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "_source", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "_source", + "readFromDocValues": false, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "_source", + }, + "_type": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "_type", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "_type", + "readFromDocValues": false, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "string", + }, + "area": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "geo_shape", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "area", + "readFromDocValues": false, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "geo_shape", + }, + "bytes": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 10, + "esTypes": Array [ + "long", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "bytes", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "number", + }, + "custom_user_field": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "conflict", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "custom_user_field", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "conflict", + }, + "extension": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "text", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "extension", + "readFromDocValues": false, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "string", + }, + "extension.keyword": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "keyword", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "extension.keyword", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": Object { + "multi": Object { + "parent": "extension", + }, + }, + "type": "string", + }, + "geo.coordinates": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "geo_point", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "geo.coordinates", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "geo_point", + }, + "geo.src": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "keyword", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "geo.src", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "string", + }, + "hashed": Object { + "aggregatable": false, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "murmur3", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "hashed", + "readFromDocValues": false, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "murmur3", + }, + "ip": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "ip", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "ip", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "ip", + }, + "machine.os": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "text", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "machine.os", + "readFromDocValues": false, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "string", + }, + "machine.os.raw": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "keyword", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "machine.os.raw", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": Object { + "multi": Object { + "parent": "machine.os", + }, + }, + "type": "string", + }, + "non-filterable": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "text", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "non-filterable", + "readFromDocValues": false, + "script": undefined, + "scripted": false, + "searchable": false, + "subType": undefined, + "type": "string", + }, + "non-sortable": Object { + "aggregatable": false, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "text", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "non-sortable", + "readFromDocValues": false, + "script": undefined, + "scripted": false, + "searchable": false, + "subType": undefined, + "type": "string", + }, + "phpmemory": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "integer", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "phpmemory", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "number", + }, + "point": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "geo_point", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "point", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "geo_point", + }, + "request_body": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "attachment", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "request_body", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "attachment", + }, + "script date": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "date", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": "painless", + "name": "script date", + "readFromDocValues": false, + "script": "1234", + "scripted": true, + "searchable": true, + "subType": undefined, + "type": "date", + }, + "script murmur3": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "murmur3", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": "expression", + "name": "script murmur3", + "readFromDocValues": false, + "script": "1234", + "scripted": true, + "searchable": true, + "subType": undefined, + "type": "murmur3", + }, + "script number": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "long", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": "expression", + "name": "script number", + "readFromDocValues": false, + "script": "1234", + "scripted": true, + "searchable": true, + "subType": undefined, + "type": "number", + }, + "script string": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "text", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": "expression", + "name": "script string", + "readFromDocValues": false, + "script": "'i am a string'", + "scripted": true, + "searchable": true, + "subType": undefined, + "type": "string", + }, + "ssl": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 20, + "esTypes": Array [ + "boolean", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "ssl", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "boolean", + }, + "time": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 30, + "esTypes": Array [ + "date", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "time", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "date", + }, + "utc_time": Object { + "aggregatable": true, + "conflictDescriptions": undefined, + "count": 0, + "esTypes": Array [ + "date", + ], + "format": Object { + "id": "number", + "params": Object { + "pattern": "$0,0.[00]", + }, + }, + "lang": undefined, + "name": "utc_time", + "readFromDocValues": true, + "script": undefined, + "scripted": false, + "searchable": true, + "subType": undefined, + "type": "date", + }, + }, + "id": "test-pattern", + "sourceFilters": undefined, + "timeFieldName": "timestamp", + "title": "title", + "type": "index-pattern", + "typeMeta": undefined, + "version": "2", +} +`; + +exports[`IndexPatternWithDataSource toSpec should match snapshot 1`] = ` +Object { + "dataSourceRef": Object { + "id": "id", + "type": "data-source", + }, "fields": Object { "@tags": Object { "aggregatable": true, diff --git a/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_patterns.test.ts.snap b/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_patterns.test.ts.snap index 5f2338b77aa1..445ec63df131 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_patterns.test.ts.snap +++ b/src/plugins/data/common/index_patterns/index_patterns/__snapshots__/index_patterns.test.ts.snap @@ -21,3 +21,29 @@ Object { "version": "version", } `; + +exports[`IndexPatterns savedObjectToSpecWithDataSource 1`] = ` +Object { + "dataSourceRef": Object { + "id": "id", + "name": "dataSource", + "type": "data-source", + }, + "fields": Object {}, + "id": "id", + "intervalName": undefined, + "sourceFilters": Array [ + Object { + "value": "item1", + }, + Object { + "value": "item2", + }, + ], + "timeFieldName": "@timestamp", + "title": "opensearch-dashboards-*", + "type": "", + "typeMeta": Object {}, + "version": "version", +} +`; diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts index a5ccece49943..089927dbc1e8 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.test.ts @@ -90,6 +90,24 @@ function create(id: string) { }); } +function createWithDataSource(id: string) { + const { + type, + version, + attributes: { timeFieldName, fields, title }, + reference, + } = stubbedSavedObjectIndexPattern(id, true); + + const dataSourceRef = { id: reference[0].id, type: reference[0].type }; + return new IndexPattern({ + spec: { id, type, version, timeFieldName, fields, title, dataSourceRef }, + savedObjectsClient: {} as any, + fieldFormats: fieldFormatsMock, + shortDotsEnable: false, + metaFields: [], + }); +} + describe('IndexPattern', () => { let indexPattern: IndexPattern; @@ -252,3 +270,53 @@ describe('IndexPattern', () => { }); }); }); + +describe('IndexPatternWithDataSource', () => { + let indexPattern: IndexPattern; + + // create an indexPattern instance for each test + beforeEach(() => { + indexPattern = createWithDataSource('test-pattern'); + }); + + describe('toSpec', () => { + test('should match snapshot', () => { + const formatter = { + toJSON: () => ({ id: 'number', params: { pattern: '$0,0.[00]' } }), + } as FieldFormat; + indexPattern.getFormatterForField = () => formatter; + expect(indexPattern.toSpec()).toMatchSnapshot(); + }); + + test('can restore from spec', () => { + const formatter = { + toJSON: () => ({ id: 'number', params: { pattern: '$0,0.[00]' } }), + } as FieldFormat; + indexPattern.getFormatterForField = () => formatter; + const spec = indexPattern.toSpec(); + const restoredPattern = new IndexPattern({ + spec, + savedObjectsClient: {} as any, + fieldFormats: fieldFormatsMock, + shortDotsEnable: false, + metaFields: [], + }); + expect(restoredPattern.id).toEqual(indexPattern.id); + expect(restoredPattern.title).toEqual(indexPattern.title); + expect(restoredPattern.timeFieldName).toEqual(indexPattern.timeFieldName); + expect(restoredPattern.fields.length).toEqual(indexPattern.fields.length); + expect(restoredPattern.fieldFormatMap.bytes instanceof MockFieldFormatter).toEqual(true); + expect(restoredPattern.dataSourceRef).toEqual(indexPattern.dataSourceRef); + }); + }); + + describe('getSaveObjectReference', () => { + test('should get index pattern saved object reference', function () { + expect(indexPattern.getSaveObjectReference()[0]?.id).toEqual(indexPattern.dataSourceRef?.id); + expect(indexPattern.getSaveObjectReference()[0]?.type).toEqual( + indexPattern.dataSourceRef?.type + ); + expect(indexPattern.getSaveObjectReference()[0]?.name).toEqual('dataSource'); + }); + }); +}); diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts index 930d21f02992..7a966d2849c9 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts @@ -224,13 +224,13 @@ export class IndexPattern implements IIndexPattern { return { id: this.id, version: this.version, - title: this.title, timeFieldName: this.timeFieldName, sourceFilters: this.sourceFilters, fields: this.fields.toSpec({ getFormatterForField: this.getFormatterForField.bind(this) }), typeMeta: this.typeMeta, type: this.type, + dataSourceRef: this.dataSourceRef, }; } diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts index fe39a05b6b71..4361e12dec16 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_patterns.test.ts @@ -223,4 +223,30 @@ describe('IndexPatterns', () => { expect(indexPatterns.savedObjectToSpec(savedObject)).toMatchSnapshot(); }); + + test('savedObjectToSpecWithDataSource', () => { + const savedObject = { + id: 'id', + version: 'version', + attributes: { + title: 'opensearch-dashboards-*', + timeFieldName: '@timestamp', + fields: '[]', + sourceFilters: '[{"value":"item1"},{"value":"item2"}]', + fieldFormatMap: '{"field":{}}', + typeMeta: '{}', + type: '', + }, + type: 'index-pattern', + references: [ + { + id: 'id', + type: 'data-source', + name: 'dataSource', + }, + ], + }; + + expect(indexPatterns.savedObjectToSpec(savedObject)).toMatchSnapshot(); + }); }); diff --git a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/components/header/header.tsx b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/components/header/header.tsx index 7158cd71441a..169bfe261015 100644 --- a/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/components/header/header.tsx +++ b/src/plugins/index_pattern_management/public/components/create_index_pattern_wizard/components/step_data_source/components/header/header.tsx @@ -3,9 +3,19 @@ * SPDX-License-Identifier: Apache-2.0 */ -import React from 'react'; +import React, { useState } from 'react'; -import { EuiTitle, EuiSpacer, EuiText, EuiFlexItem, EuiFormRow, EuiButton } from '@elastic/eui'; +import { + EuiTitle, + EuiSpacer, + EuiText, + EuiFlexItem, + EuiFormRow, + EuiButton, + EuiFlexGroup, + EuiSwitch, + EuiSwitchEvent, +} from '@elastic/eui'; import { FormattedMessage } from '@osd/i18n/react'; import { i18n } from '@osd/i18n'; @@ -31,10 +41,16 @@ export const Header: React.FC = (props: HeaderProps) => { const { dataSourceRef, onSearchSelected, goToNextStep, isNextStepDisabled, stepInfo } = props; const { currentStepNumber, totalStepNumber } = stepInfo; + const [skipped, setSkipped] = useState(false); + const { savedObjects, uiSettings } = useOpenSearchDashboards< IndexPatternManagmentContext >().services; + const onSkipped = (e: EuiSwitchEvent) => { + setSkipped(e.target.checked); + }; + return (
@@ -46,6 +62,18 @@ export const Header: React.FC = (props: HeaderProps) => { /> + + + } + checked={skipped} + onChange={onSkipped} + /> + = (props: HeaderProps) => { defaultMessage="Please pick the data source -- within which to configure index patterns." /> - - 'apps', // todo: #2034 - name: i18n.translate( - 'indexPatternManagement.createIndexPattern.searchSelection.savedObjectType.dataSource', - { - defaultMessage: 'Data Source', - } - ), - }, - ]} - fixedPageSize={DATA_SOURCE_PAGE_SIZE} - uiSettings={uiSettings} - savedObjects={savedObjects} - /> - + {!skipped && ( + + 'apps', // todo: #2034 + name: i18n.translate( + 'indexPatternManagement.createIndexPattern.searchSelection.savedObjectType.dataSource', + { + defaultMessage: 'Data Source', + } + ), + }, + ]} + fixedPageSize={DATA_SOURCE_PAGE_SIZE} + uiSettings={uiSettings} + savedObjects={savedObjects} + /> + + )} + + + goToNextStep(dataSourceRef)} - isDisabled={isNextStepDisabled} + isDisabled={isNextStepDisabled && !skipped} > - - + +
); };