diff --git a/.buildkite/scripts/build_kibana.sh b/.buildkite/scripts/build_kibana.sh index 007dd19a2c0e1..d05fe178b72db 100755 --- a/.buildkite/scripts/build_kibana.sh +++ b/.buildkite/scripts/build_kibana.sh @@ -28,7 +28,7 @@ if [[ "${GITHUB_PR_LABELS:-}" == *"ci:deploy-cloud"* ]]; then --docker-tag-qualifier="$GIT_COMMIT" \ --docker-push \ --skip-docker-ubi \ - --skip-docker-centos \ + --skip-docker-ubuntu \ --skip-docker-contexts CLOUD_IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" docker.elastic.co/kibana-ci/kibana-cloud) diff --git a/.buildkite/scripts/steps/demo_env/kibana.sh b/.buildkite/scripts/steps/demo_env/kibana.sh index f10ed4013bc0c..f38d43b5479e6 100755 --- a/.buildkite/scripts/steps/demo_env/kibana.sh +++ b/.buildkite/scripts/steps/demo_env/kibana.sh @@ -9,7 +9,7 @@ source "$(dirname "${0}")/config.sh" export KIBANA_IMAGE="gcr.io/elastic-kibana-184716/demo/kibana:$DEPLOYMENT_NAME-$(git rev-parse HEAD)" echo '--- Build Kibana' -node scripts/build --debug --docker-images --example-plugins --skip-os-packages --skip-docker-ubi +node scripts/build --debug --docker-images --example-plugins --skip-docker-ubi echo '--- Build Docker image with example plugins' cd target/example_plugins diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ad992066f8503..cd3188ad971af 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -63,6 +63,8 @@ /packages/elastic-datemath/ @elastic/kibana-app-services /packages/kbn-interpreter/ @elastic/kibana-app-services /packages/kbn-react-field/ @elastic/kibana-app-services +/packages/kbn-es-query/ @elastic/kibana-app-services +/packages/kbn-field-types/ @elastic/kibana-app-services /src/plugins/bfetch/ @elastic/kibana-app-services /src/plugins/data/ @elastic/kibana-app-services /src/plugins/data_views/ @elastic/kibana-app-services diff --git a/examples/data_view_field_editor_example/public/app.tsx b/examples/data_view_field_editor_example/public/app.tsx index ac7e3b60482e0..cbad86d7e21d4 100644 --- a/examples/data_view_field_editor_example/public/app.tsx +++ b/examples/data_view_field_editor_example/public/app.tsx @@ -20,23 +20,20 @@ import { DefaultItemAction, } from '@elastic/eui'; import { AppMountParameters } from '../../../src/core/public'; -import { - DataPublicPluginStart, - IndexPattern, - IndexPatternField, -} from '../../../src/plugins/data/public'; +import { DataPublicPluginStart } from '../../../src/plugins/data/public'; +import type { DataView, DataViewField } from '../../../src/plugins/data_views/public'; import { IndexPatternFieldEditorStart } from '../../../src/plugins/data_view_field_editor/public'; interface Props { - indexPattern?: IndexPattern; + dataView?: DataView; dataViewFieldEditor: IndexPatternFieldEditorStart; } -const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: Props) => { - const [fields, setFields] = useState( - indexPattern?.getNonScriptedFields() || [] +const DataViewFieldEditorExample = ({ dataView, dataViewFieldEditor }: Props) => { + const [fields, setFields] = useState( + dataView?.fields.getAll().filter((f) => !f.scripted) || [] ); - const refreshFields = () => setFields(indexPattern?.getNonScriptedFields() || []); + const refreshFields = () => setFields(dataView?.fields.getAll().filter((f) => !f.scripted) || []); const columns = [ { field: 'name', @@ -51,9 +48,9 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P icon: 'pencil', type: 'icon', 'data-test-subj': 'editField', - onClick: (fld: IndexPatternField) => + onClick: (fld: DataViewField) => dataViewFieldEditor.openEditor({ - ctx: { dataView: indexPattern! }, + ctx: { dataView: dataView! }, fieldName: fld.name, onSave: refreshFields, }), @@ -65,27 +62,27 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P type: 'icon', 'data-test-subj': 'deleteField', available: (fld) => !!fld.runtimeField, - onClick: (fld: IndexPatternField) => + onClick: (fld: DataViewField) => dataViewFieldEditor.openDeleteModal({ fieldName: fld.name, ctx: { - dataView: indexPattern!, + dataView: dataView!, }, onDelete: refreshFields, }), }, - ] as Array>, + ] as Array>, }, ]; - const content = indexPattern ? ( + const content = dataView ? ( <> - Index pattern: {indexPattern?.title} + Data view: {dataView.title}
dataViewFieldEditor.openEditor({ - ctx: { dataView: indexPattern! }, + ctx: { dataView }, onSave: refreshFields, }) } @@ -94,7 +91,7 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P Add field
- + items={fields} columns={columns} pagination={true} @@ -108,13 +105,13 @@ const IndexPatternFieldEditorExample = ({ indexPattern, dataViewFieldEditor }: P /> ) : ( -

Please create an index pattern

+

Please create a data view

); return ( - Index pattern field editor demo + Data view field editor demo {content} @@ -132,12 +129,9 @@ export const renderApp = async ( { data, dataViewFieldEditor }: RenderAppDependencies, { element }: AppMountParameters ) => { - const indexPattern = (await data.indexPatterns.getDefault()) || undefined; + const dataView = (await data.dataViews.getDefault()) || undefined; ReactDOM.render( - , + , element ); diff --git a/examples/data_view_field_editor_example/public/index.ts b/examples/data_view_field_editor_example/public/index.ts index cc509da31d25f..77fcce64d3a9b 100644 --- a/examples/data_view_field_editor_example/public/index.ts +++ b/examples/data_view_field_editor_example/public/index.ts @@ -6,6 +6,6 @@ * Side Public License, v 1. */ -import { IndexPatternFieldEditorPlugin } from './plugin'; +import { DataViewFieldEditorPlugin } from './plugin'; -export const plugin = () => new IndexPatternFieldEditorPlugin(); +export const plugin = () => new DataViewFieldEditorPlugin(); diff --git a/examples/data_view_field_editor_example/public/plugin.tsx b/examples/data_view_field_editor_example/public/plugin.tsx index 92d18030e19b8..3cf0ce618ad3b 100644 --- a/examples/data_view_field_editor_example/public/plugin.tsx +++ b/examples/data_view_field_editor_example/public/plugin.tsx @@ -20,11 +20,11 @@ interface SetupDeps { developerExamples: DeveloperExamplesSetup; } -export class IndexPatternFieldEditorPlugin implements Plugin { +export class DataViewFieldEditorPlugin implements Plugin { public setup(core: CoreSetup, deps: SetupDeps) { core.application.register({ - id: 'indexPatternFieldEditorExample', - title: 'Index pattern field editor example', + id: 'dataViewFieldEditorExample', + title: 'Data view field editor example', navLinkStatus: AppNavLinkStatus.hidden, async mount(params: AppMountParameters) { const [, depsStart] = await core.getStartServices(); @@ -34,13 +34,13 @@ export class IndexPatternFieldEditorPlugin implements Plugin void; + openDateViewNumberFieldEditor: () => void; } const UsingAnExistingFieldFormatExample: React.FC<{ deps: Deps }> = (props) => { @@ -123,15 +123,15 @@ const CreatingCustomFieldFormat: React.FC<{ deps: Deps }> = (props) => {

- Currency formatter that we've just created is already integrated with index patterns. - It can be applied to any numeric field of any index pattern.{' '} - props.deps.openIndexPatternNumberFieldEditor()}> - Open index pattern field editor to give it a try. + Currency formatter that we've just created is already integrated with data views. It + can be applied to any numeric field of any data view.{' '} + props.deps.openDateViewNumberFieldEditor()}> + Open data view field editor to give it a try.

@@ -155,15 +155,15 @@ const CreatingCustomFieldFormatEditor: React.FC<{ deps: Deps }> = (props) => {

- Currency formatter and its custom editor are integrated with index patterns. It can be - applied to any numeric field of any index pattern.{' '} - props.deps.openIndexPatternNumberFieldEditor()}> - Open index pattern field editor to give it a try. + Currency formatter and its custom editor are integrated with data views. It can be applied + to any numeric field of any data view.{' '} + props.deps.openDateViewNumberFieldEditor()}> + Open date view field editor to give it a try.

diff --git a/examples/field_formats_example/public/plugin.tsx b/examples/field_formats_example/public/plugin.tsx index b12304c4ce080..8e8018a0f5e6e 100755 --- a/examples/field_formats_example/public/plugin.tsx +++ b/examples/field_formats_example/public/plugin.tsx @@ -45,29 +45,29 @@ export class FieldFormatsExamplePlugin implements Plugin { + // opens a field editor using default data view and first number field + const openDateViewNumberFieldEditor = async () => { const [, plugins] = await core.getStartServices(); - const indexPattern = await plugins.data.indexPatterns.getDefault(); - if (!indexPattern) { - alert('Creating at least one index pattern to continue with this example'); + const dataView = await plugins.data.dataViews.getDefault(); + if (!dataView) { + alert('Create at least one data view to continue with this example'); return; } - const numberField = indexPattern - .getNonScriptedFields() - .find((f) => !f.name.startsWith('_') && f.type === KBN_FIELD_TYPES.NUMBER); + const numberField = dataView.fields + .getAll() + .find((f) => !f.name.startsWith('_') && f.type === KBN_FIELD_TYPES.NUMBER && !f.scripted); if (!numberField) { alert( - 'Default index pattern needs at least a single field of type `number` to continue with this example' + 'Default data view needs at least a single field of type `number` to continue with this example' ); return; } plugins.dataViewFieldEditor.openEditor({ ctx: { - dataView: indexPattern, + dataView, }, fieldName: numberField.name, }); @@ -81,7 +81,7 @@ export class FieldFormatsExamplePlugin implements Plugin, + , element ); return () => ReactDOM.unmountComponentAtNode(element); diff --git a/examples/search_examples/public/search/app.tsx b/examples/search_examples/public/search/app.tsx index eeceab569d3b3..9220827863852 100644 --- a/examples/search_examples/public/search/app.tsx +++ b/examples/search_examples/public/search/app.tsx @@ -41,11 +41,10 @@ import { PLUGIN_ID, PLUGIN_NAME, SERVER_SEARCH_ROUTE_PATH } from '../../common'; import { DataPublicPluginStart, IKibanaSearchResponse, - IndexPattern, - IndexPatternField, isCompleteResponse, isErrorResponse, } from '../../../../src/plugins/data/public'; +import type { DataViewField, DataView } from '../../../../src/plugins/data_views/public'; import { IMyStrategyResponse } from '../../common/types'; import { AbortError } from '../../../../src/plugins/kibana_utils/common'; @@ -56,22 +55,22 @@ interface SearchExamplesAppDeps { data: DataPublicPluginStart; } -function getNumeric(fields?: IndexPatternField[]) { +function getNumeric(fields?: DataViewField[]) { if (!fields) return []; return fields?.filter((f) => f.type === 'number' && f.aggregatable); } -function getAggregatableStrings(fields?: IndexPatternField[]) { +function getAggregatableStrings(fields?: DataViewField[]) { if (!fields) return []; return fields?.filter((f) => f.type === 'string' && f.aggregatable); } -function formatFieldToComboBox(field?: IndexPatternField | null) { +function formatFieldToComboBox(field?: DataViewField | null) { if (!field) return []; return formatFieldsToComboBox([field]); } -function formatFieldsToComboBox(fields?: IndexPatternField[]) { +function formatFieldsToComboBox(fields?: DataViewField[]) { if (!fields) return []; return fields?.map((field) => { @@ -93,14 +92,14 @@ export const SearchExamplesApp = ({ const [timeTook, setTimeTook] = useState(); const [total, setTotal] = useState(100); const [loaded, setLoaded] = useState(0); - const [indexPattern, setIndexPattern] = useState(); - const [fields, setFields] = useState(); - const [selectedFields, setSelectedFields] = useState([]); + const [dataView, setDataView] = useState(); + const [fields, setFields] = useState(); + const [selectedFields, setSelectedFields] = useState([]); const [selectedNumericField, setSelectedNumericField] = useState< - IndexPatternField | null | undefined + DataViewField | null | undefined >(); const [selectedBucketField, setSelectedBucketField] = useState< - IndexPatternField | null | undefined + DataViewField | null | undefined >(); const [request, setRequest] = useState>({}); const [isLoading, setIsLoading] = useState(false); @@ -115,20 +114,20 @@ export const SearchExamplesApp = ({ setTimeTook(response.rawResponse.took); } - // Fetch the default index pattern using the `data.indexPatterns` service, as the component is mounted. + // Fetch the default data view using the `data.dataViews` service, as the component is mounted. useEffect(() => { - const setDefaultIndexPattern = async () => { - const defaultIndexPattern = await data.indexPatterns.getDefault(); - setIndexPattern(defaultIndexPattern); + const setDefaultDataView = async () => { + const defaultDataView = await data.dataViews.getDefault(); + setDataView(defaultDataView); }; - setDefaultIndexPattern(); + setDefaultDataView(); }, [data]); - // Update the fields list every time the index pattern is modified. + // Update the fields list every time the data view is modified. useEffect(() => { - setFields(indexPattern?.fields); - }, [indexPattern]); + setFields(dataView?.fields); + }, [dataView]); useEffect(() => { setSelectedBucketField(fields?.length ? getAggregatableStrings(fields)[0] : null); setSelectedNumericField(fields?.length ? getNumeric(fields)[0] : null); @@ -140,10 +139,10 @@ export const SearchExamplesApp = ({ addWarning: boolean = false, addError: boolean = false ) => { - if (!indexPattern || !selectedNumericField) return; + if (!dataView || !selectedNumericField) return; // Construct the query portion of the search request - const query = data.query.getEsQuery(indexPattern); + const query = data.query.getEsQuery(dataView); if (addWarning) { query.bool.must.push({ @@ -151,7 +150,7 @@ export const SearchExamplesApp = ({ error_query: { indices: [ { - name: indexPattern.title, + name: dataView.title, error_type: 'warning', message: 'Watch out!', }, @@ -165,7 +164,7 @@ export const SearchExamplesApp = ({ error_query: { indices: [ { - name: indexPattern.title, + name: dataView.title, error_type: 'exception', message: 'Watch out!', }, @@ -176,11 +175,11 @@ export const SearchExamplesApp = ({ // Construct the aggregations portion of the search request by using the `data.search.aggs` service. const aggs = [{ type: 'avg', params: { field: selectedNumericField!.name } }]; - const aggsDsl = data.search.aggs.createAggConfigs(indexPattern, aggs).toDsl(); + const aggsDsl = data.search.aggs.createAggConfigs(dataView, aggs).toDsl(); const req = { params: { - index: indexPattern.title, + index: dataView.title, body: { aggs: aggsDsl, query, @@ -264,11 +263,11 @@ export const SearchExamplesApp = ({ }; const doSearchSourceSearch = async (otherBucket: boolean) => { - if (!indexPattern) return; + if (!dataView) return; const query = data.query.queryString.getQuery(); const filters = data.query.filterManager.getFilters(); - const timefilter = data.query.timefilter.timefilter.createFilter(indexPattern); + const timefilter = data.query.timefilter.timefilter.createFilter(dataView); if (timefilter) { filters.push(timefilter); } @@ -277,7 +276,7 @@ export const SearchExamplesApp = ({ const searchSource = await data.search.searchSource.create(); searchSource - .setField('index', indexPattern) + .setField('index', dataView) .setField('filter', filters) .setField('query', query) .setField('fields', selectedFields.length ? selectedFields.map((f) => f.name) : ['']) @@ -296,7 +295,7 @@ export const SearchExamplesApp = ({ aggDef.push({ type: 'avg', params: { field: selectedNumericField.name } }); } if (aggDef.length > 0) { - const ac = data.search.aggs.createAggConfigs(indexPattern, aggDef); + const ac = data.search.aggs.createAggConfigs(dataView, aggDef); searchSource.setField('aggs', ac); } @@ -407,14 +406,14 @@ export const SearchExamplesApp = ({ }; const onServerClickHandler = async () => { - if (!indexPattern || !selectedNumericField) return; + if (!dataView || !selectedNumericField) return; const abortController = new AbortController(); setAbortController(abortController); setIsLoading(true); try { const res = await http.get(SERVER_SEARCH_ROUTE_PATH, { query: { - index: indexPattern.title, + index: dataView.title, field: selectedNumericField!.name, }, signal: abortController.signal, @@ -510,22 +509,26 @@ export const SearchExamplesApp = ({ appName={PLUGIN_ID} showSearchBar={true} useDefaultBehaviors={true} - indexPatterns={indexPattern ? [indexPattern] : undefined} + indexPatterns={dataView ? [dataView] : undefined} /> - Index Pattern + Data view { - const newIndexPattern = await data.indexPatterns.get(newIndexPatternId); - setIndexPattern(newIndexPattern); + indexPatternId={dataView?.id || ''} + onChange={async (dataViewId?: string) => { + if (dataViewId) { + const newDataView = await data.dataViews.get(dataViewId); + setDataView(newDataView); + } else { + setDataView(undefined); + } }} isClearable={false} - data-test-subj="indexPatternSelector" + data-test-subj="dataViewSelector" /> @@ -536,7 +539,7 @@ export const SearchExamplesApp = ({ singleSelection={true} onChange={(option) => { if (option.length) { - const fld = indexPattern?.getFieldByName(option[0].label); + const fld = dataView?.getFieldByName(option[0].label); setSelectedBucketField(fld || null); } else { setSelectedBucketField(null); @@ -554,7 +557,7 @@ export const SearchExamplesApp = ({ singleSelection={true} onChange={(option) => { if (option.length) { - const fld = indexPattern?.getFieldByName(option[0].label); + const fld = dataView?.getFieldByName(option[0].label); setSelectedNumericField(fld || null); } else { setSelectedNumericField(null); @@ -572,9 +575,9 @@ export const SearchExamplesApp = ({ singleSelection={false} onChange={(option) => { const flds = option - .map((opt) => indexPattern?.getFieldByName(opt?.label)) + .map((opt) => dataView?.getFieldByName(opt?.label)) .filter((f) => f); - setSelectedFields(flds.length ? (flds as IndexPatternField[]) : []); + setSelectedFields(flds.length ? (flds as DataViewField[]) : []); }} sortMatchesBy="startsWith" /> @@ -590,9 +593,8 @@ export const SearchExamplesApp = ({ If you want to fetch data from Elasticsearch, you can use the different services - provided by the data plugin. These help you get the index pattern - and search bar configuration, format them into a DSL query and send it to - Elasticsearch. + provided by the data plugin. These help you get the data view and + search bar configuration, format them into a DSL query and send it to Elasticsearch. { - if (!indexPattern) return; + if (!dataView) return; if (!numericFieldName) return; setIsSearching(true); const requestId = ++nextRequestIdRef.current; - doSearch({ indexPattern, numericFieldName, restoreSearchSessionId }, { data, notifications }) + doSearch({ dataView, numericFieldName, restoreSearchSessionId }, { data, notifications }) .then(({ response: res, request: req, tookMs: _tookMs }) => { if (requestId !== nextRequestIdRef.current) return; // no longer interested in this result if (restoreSearchSessionId) { @@ -220,7 +219,7 @@ export const SearchSessionsExampleApp = ({ setIsSearching(false); }); }, - [data, notifications, indexPattern, numericFieldName] + [data, notifications, dataView, numericFieldName] ); useEffect(() => { @@ -243,9 +242,9 @@ export const SearchSessionsExampleApp = ({ )} - {!indexPattern && ( + {!dataView && ( <> - + )} @@ -280,26 +279,23 @@ export const SearchSessionsExampleApp = ({ appName={PLUGIN_ID} showSearchBar={true} useDefaultBehaviors={true} - indexPatterns={indexPattern ? [indexPattern] : undefined} + indexPatterns={dataView ? [dataView] : undefined} onQuerySubmit={reset} /> - Index Pattern + Data view { if (!id) return; - setIndexPattern(id); + setDataView(id); }} isClearable={false} - data-test-subj="indexPatternSelector" + data-test-subj="dataViewSelector" /> @@ -309,7 +305,7 @@ export const SearchSessionsExampleApp = ({ selectedOptions={formatFieldToComboBox(selectedField)} singleSelection={true} onChange={(option) => { - const fld = indexPattern?.getFieldByName(option[0].label); + const fld = dataView?.getFieldByName(option[0].label); if (!fld) return; setNumericFieldName(fld?.name); }} @@ -336,7 +332,7 @@ export const SearchSessionsExampleApp = ({ size="xs" onClick={() => search()} iconType="play" - disabled={isSearching || !indexPattern || !numericFieldName} + disabled={isSearching || !dataView || !numericFieldName} data-test-subj={'startSearch'} > Start the search from low-level client (data.search.search) @@ -540,7 +536,7 @@ function SearchInspector({ function useAppState({ data }: { data: DataPublicPluginStart }) { const stateContainer = useMemo(() => { - const { filters, time, searchSessionId, numericFieldName, indexPatternId, query } = + const { filters, time, searchSessionId, numericFieldName, dataViewId, query } = getInitialStateFromUrl(); if (filters) { @@ -558,7 +554,7 @@ function useAppState({ data }: { data: DataPublicPluginStart }) { return createStateContainer({ restoreSessionId: searchSessionId, numericFieldName, - indexPatternId, + dataViewId, }); }, [data.query.filterManager, data.query.queryString, data.query.timefilter.timefilter]); const setState = useCallback( @@ -575,78 +571,78 @@ function useAppState({ data }: { data: DataPublicPluginStart }) { }); }, [stateContainer, data.query]); - const [fields, setFields] = useState(); - const [indexPattern, setIndexPattern] = useState(); + const [fields, setFields] = useState(); + const [dataView, setDataView] = useState(); - // Fetch the default index pattern using the `data.indexPatterns` service, as the component is mounted. + // Fetch the default data view using the `data.dataViews` service, as the component is mounted. useEffect(() => { let canceled = false; - const loadIndexPattern = async () => { + const loadDataView = async () => { // eslint-disable-next-line no-console - console.warn('Loading default index pattern'); - let loadedIndexPattern = state.indexPatternId - ? await data.indexPatterns.get(state.indexPatternId) - : await data.indexPatterns.getDefault(); - if (!loadedIndexPattern) { - // try to find any available index pattern - const [id] = await data.indexPatterns.getIds(true); + console.warn('Loading default data view'); + let loadedDataView = state.dataViewId + ? await data.dataViews.get(state.dataViewId) + : await data.dataViews.getDefault(); + if (!loadedDataView) { + // try to find any available data view + const [id] = await data.dataViews.getIds(true); if (id) { - loadedIndexPattern = await data.indexPatterns.get(id); + loadedDataView = await data.dataViews.get(id); } } if (canceled) return; - if (!loadedIndexPattern) { + if (!loadedDataView) { // eslint-disable-next-line no-console - console.warn('No index patterns to pick from'); + console.warn('No data view to pick from'); return; } - if (!state.indexPatternId) { + if (!state.dataViewId) { setState({ - indexPatternId: loadedIndexPattern.id, + dataViewId: loadedDataView.id, }); } - setIndexPattern(loadedIndexPattern); + setDataView(loadedDataView); }; - loadIndexPattern(); + loadDataView(); return () => { canceled = true; }; - }, [data, setState, state.indexPatternId]); + }, [data, setState, state.dataViewId]); - // Update the fields list every time the index pattern is modified. + // Update the fields list every time the data view is modified. useEffect(() => { - setFields(indexPattern?.fields); - }, [indexPattern]); + setFields(dataView?.fields); + }, [dataView]); useEffect(() => { if (state.numericFieldName) return; setState({ numericFieldName: fields?.length ? getNumeric(fields)[0]?.name : undefined }); }, [setState, fields, state.numericFieldName]); - const selectedField: IndexPatternField | undefined = useMemo( - () => indexPattern?.fields.find((field) => field.name === state.numericFieldName), - [indexPattern?.fields, state.numericFieldName] + const selectedField: DataViewField | undefined = useMemo( + () => dataView?.fields.find((field) => field.name === state.numericFieldName), + [dataView?.fields, state.numericFieldName] ); return { selectedField, - indexPattern, + dataView, numericFieldName: state.numericFieldName, fields, setNumericFieldName: (field: string) => setState({ numericFieldName: field }), - setIndexPattern: (indexPatternId: string) => setState({ indexPatternId }), + setDataView: (dataViewId: string) => setState({ dataViewId }), state, }; } function doSearch( { - indexPattern, + dataView, numericFieldName, restoreSearchSessionId, }: { - indexPattern: IndexPattern; + dataView: DataView; numericFieldName: string; restoreSearchSessionId?: string; }, @@ -655,7 +651,7 @@ function doSearch( notifications, }: { data: DataPublicPluginStart; notifications: CoreStart['notifications'] } ): Promise<{ request: IEsSearchRequest; response: IEsSearchResponse; tookMs?: number }> { - if (!indexPattern) return Promise.reject('Select an index patten'); + if (!dataView) return Promise.reject('Select a data view'); if (!numericFieldName) return Promise.reject('Select a field to aggregate on'); // start a new session or restore an existing one @@ -668,7 +664,7 @@ function doSearch( const sessionId = restoreSearchSessionId ? restoreSearchSessionId : data.search.session.start(); // Construct the query portion of the search request - const query = data.query.getEsQuery(indexPattern, restoreTimeRange); + const query = data.query.getEsQuery(dataView, restoreTimeRange); // Construct the aggregations portion of the search request by using the `data.search.aggs` service. @@ -679,11 +675,11 @@ function doSearch( ] : [{ type: 'avg', params: { field: numericFieldName } }]; - const aggsDsl = data.search.aggs.createAggConfigs(indexPattern, aggs).toDsl(); + const aggsDsl = data.search.aggs.createAggConfigs(dataView, aggs).toDsl(); const req = { params: { - index: indexPattern.title, + index: dataView.title, body: { aggs: aggsDsl, query, @@ -728,17 +724,17 @@ function doSearch( .toPromise(); } -function getNumeric(fields?: IndexPatternField[]) { +function getNumeric(fields?: DataViewField[]) { if (!fields) return []; return fields?.filter((f) => f.type === 'number' && f.aggregatable); } -function formatFieldToComboBox(field?: IndexPatternField | null) { +function formatFieldToComboBox(field?: DataViewField | null) { if (!field) return []; return formatFieldsToComboBox([field]); } -function formatFieldsToComboBox(fields?: IndexPatternField[]) { +function formatFieldsToComboBox(fields?: DataViewField[]) { if (!fields) return []; return fields?.map((field) => { @@ -781,10 +777,10 @@ function NoShardDelayCallout() { ); } -function NoIndexPatternsCallout() { +function NoDataViewsCallout() { return ( - Missing index patterns!} color="warning" iconType="help"> -

This demo requires at least one index pattern.

+ Missing data views!} color="warning" iconType="help"> +

This demo requires at least one data view.

); } diff --git a/examples/search_examples/public/search_sessions/app_locator.ts b/examples/search_examples/public/search_sessions/app_locator.ts index 1cbd27887c1c3..f7e59ece3be5d 100644 --- a/examples/search_examples/public/search_sessions/app_locator.ts +++ b/examples/search_examples/public/search_sessions/app_locator.ts @@ -7,7 +7,8 @@ */ import { SerializableRecord } from '@kbn/utility-types'; -import { esFilters, Filter, Query, TimeRange } from '../../../../src/plugins/data/public'; +import { Filter, Query, isFilterPinned } from '@kbn/es-query'; +import type { TimeRange } from '../../../../src/plugins/data/public'; import { getStatesFromKbnUrl, setStateToKbnUrl } from '../../../../src/plugins/kibana_utils/public'; import { LocatorDefinition } from '../../../../src/plugins/share/common'; @@ -19,7 +20,7 @@ export const SEARCH_SESSIONS_EXAMPLES_APP_LOCATOR = 'SEARCH_SESSIONS_EXAMPLES_AP export interface AppUrlState extends SerializableRecord { filters?: Filter[]; query?: Query; - indexPatternId?: string; + dataViewId?: string; numericFieldName?: string; searchSessionId?: string; } @@ -46,8 +47,8 @@ export class SearchSessionsExamplesAppLocatorDefinition STATE_STORAGE_KEY, { query: params.query, - filters: params.filters?.filter((f) => !esFilters.isFilterPinned(f)), - indexPatternId: params.indexPatternId, + filters: params.filters?.filter((f) => !isFilterPinned(f)), + dataViewId: params.dataViewId, numericFieldName: params.numericFieldName, searchSessionId: params.searchSessionId, } as AppUrlState, @@ -59,7 +60,7 @@ export class SearchSessionsExamplesAppLocatorDefinition GLOBAL_STATE_STORAGE_KEY, { time: params.time, - filters: params.filters?.filter((f) => esFilters.isFilterPinned(f)), + filters: params.filters?.filter((f) => isFilterPinned(f)), } as GlobalUrlState, { useHash: false, storeInHashQuery: false }, url @@ -75,7 +76,7 @@ export class SearchSessionsExamplesAppLocatorDefinition export function getInitialStateFromUrl(): SearchSessionsExamplesAppLocatorParams { const { - _a: { numericFieldName, indexPatternId, searchSessionId, filters: aFilters, query } = {}, + _a: { numericFieldName, dataViewId, searchSessionId, filters: aFilters, query } = {}, _g: { filters: gFilters, time } = {}, } = getStatesFromKbnUrl<{ _a: AppUrlState; _g: GlobalUrlState }>( window.location.href, @@ -90,7 +91,7 @@ export function getInitialStateFromUrl(): SearchSessionsExamplesAppLocatorParams searchSessionId, time, filters: [...(gFilters ?? []), ...(aFilters ?? [])], - indexPatternId, + dataViewId, query, }; } diff --git a/examples/search_examples/tsconfig.json b/examples/search_examples/tsconfig.json index 547952b8dd3d8..9c0fad34ef9c0 100644 --- a/examples/search_examples/tsconfig.json +++ b/examples/search_examples/tsconfig.json @@ -15,6 +15,7 @@ "references": [ { "path": "../../src/core/tsconfig.json" }, { "path": "../../src/plugins/data/tsconfig.json" }, + { "path": "../../src/plugins/data_views/tsconfig.json" }, { "path": "../../src/plugins/kibana_utils/tsconfig.json" }, { "path": "../../src/plugins/kibana_react/tsconfig.json" }, { "path": "../../src/plugins/navigation/tsconfig.json" }, diff --git a/examples/state_containers_examples/public/with_data_services/app.tsx b/examples/state_containers_examples/public/with_data_services/app.tsx index a26b28f3cf9f3..881bc07017966 100644 --- a/examples/state_containers_examples/public/with_data_services/app.tsx +++ b/examples/state_containers_examples/public/with_data_services/app.tsx @@ -18,19 +18,18 @@ import { EuiText, EuiTitle, } from '@elastic/eui'; +import { Filter, FilterStateStore } from '@kbn/es-query'; import { CoreStart } from 'kibana/public'; import { NavigationPublicPluginStart } from '../../../../src/plugins/navigation/public'; import { connectToQueryState, DataPublicPluginStart, - esFilters, - Filter, - IndexPattern, Query, QueryState, syncQueryStateWithUrl, } from '../../../../src/plugins/data/public'; +import type { DataView } from '../../../../src/plugins/data_views/public'; import { BaseStateContainer, createStateContainer, @@ -73,13 +72,9 @@ export const App = ({ useGlobalStateSyncing(data.query, kbnUrlStateStorage); useAppStateSyncing(appStateContainer, data.query, kbnUrlStateStorage); - const indexPattern = useIndexPattern(data); - if (!indexPattern) - return ( -
- No index pattern found. Please create an index pattern before trying this example... -
- ); + const dataView = useDataView(data); + if (!dataView) + return
No data view found. Please create a data view before trying this example...
; // Note that `navigation.ui.TopNavMenu` is a stateful component exported on the `navigation` plugin's start contract. return ( @@ -102,7 +97,7 @@ export const App = ({ @@ -126,19 +121,19 @@ export const App = ({ ); }; -function useIndexPattern(data: DataPublicPluginStart) { - const [indexPattern, setIndexPattern] = useState(); +function useDataView(data: DataPublicPluginStart) { + const [dataView, setDataView] = useState(); useEffect(() => { - const fetchIndexPattern = async () => { - const defaultIndexPattern = await data.indexPatterns.getDefault(); - if (defaultIndexPattern) { - setIndexPattern(defaultIndexPattern); + const fetchDataView = async () => { + const defaultDataView = await data.dataViews.getDefault(); + if (defaultDataView) { + setDataView(defaultDataView); } }; - fetchIndexPattern(); - }, [data.indexPatterns]); + fetchDataView(); + }, [data.dataViews]); - return indexPattern; + return dataView; } function useGlobalStateSyncing( @@ -167,7 +162,7 @@ function useAppStateSyncing( const stopSyncingQueryAppStateWithStateContainer = connectToQueryState( query, appStateContainer, - { filters: esFilters.FilterStateStore.APP_STATE, query: true } + { filters: FilterStateStore.APP_STATE, query: true } ); // sets up syncing app state container with url diff --git a/examples/state_containers_examples/tsconfig.json b/examples/state_containers_examples/tsconfig.json index fc266cbe2c83f..40b66f9fc9c7b 100644 --- a/examples/state_containers_examples/tsconfig.json +++ b/examples/state_containers_examples/tsconfig.json @@ -18,6 +18,7 @@ { "path": "../../src/plugins/kibana_react/tsconfig.json" }, { "path": "../../src/plugins/navigation/tsconfig.json" }, { "path": "../../src/plugins/data/tsconfig.json" }, + { "path": "../../src/plugins/data_views/tsconfig.json" }, { "path": "../developer_examples/tsconfig.json" }, ] } diff --git a/package.json b/package.json index 8c59805785891..16ca8d4b8d72e 100644 --- a/package.json +++ b/package.json @@ -103,7 +103,7 @@ "@elastic/apm-rum": "^5.10.0", "@elastic/apm-rum-react": "^1.3.2", "@elastic/apm-synthtrace": "link:bazel-bin/packages/elastic-apm-synthtrace", - "@elastic/charts": "40.1.0", + "@elastic/charts": "40.2.0", "@elastic/datemath": "link:bazel-bin/packages/elastic-datemath", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^8.0.0-canary.35", "@elastic/ems-client": "8.0.0", @@ -189,6 +189,7 @@ "@turf/helpers": "6.0.1", "@turf/length": "^6.0.2", "@types/jsonwebtoken": "^8.5.6", + "@types/moment-duration-format": "^2.2.3", "JSONStream": "1.3.5", "abort-controller": "^3.0.0", "antlr4ts": "^0.5.0-alpha.3", @@ -211,7 +212,7 @@ "constate": "^1.3.2", "content-disposition": "0.5.3", "copy-to-clipboard": "^3.0.8", - "core-js": "^3.19.1", + "core-js": "^3.19.3", "cronstrue": "^1.51.0", "cytoscape": "^3.10.0", "cytoscape-dagre": "^2.2.2", @@ -577,6 +578,8 @@ "@types/kbn__mapbox-gl": "link:bazel-bin/packages/kbn-mapbox-gl/npm_module_types", "@types/kbn__monaco": "link:bazel-bin/packages/kbn-monaco/npm_module_types", "@types/kbn__optimizer": "link:bazel-bin/packages/kbn-optimizer/npm_module_types", + "@types/kbn__plugin-generator": "link:bazel-bin/packages/kbn-plugin-generator/npm_module_types", + "@types/kbn__plugin-helpers": "link:bazel-bin/packages/kbn-plugin-helpers/npm_module_types", "@types/license-checker": "15.0.0", "@types/listr": "^0.14.0", "@types/loader-utils": "^1.1.3", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index 5045d919f21cb..64936ba71fcf2 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -96,6 +96,8 @@ filegroup( "//packages/kbn-mapbox-gl:build_types", "//packages/kbn-monaco:build_types", "//packages/kbn-optimizer:build_types", + "//packages/kbn-plugin-generator:build_types", + "//packages/kbn-plugin-helpers:build_types", ], ) diff --git a/packages/kbn-plugin-generator/BUILD.bazel b/packages/kbn-plugin-generator/BUILD.bazel index 488f09bdd5d52..3fef9531b57a1 100644 --- a/packages/kbn-plugin-generator/BUILD.bazel +++ b/packages/kbn-plugin-generator/BUILD.bazel @@ -1,9 +1,10 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") PKG_BASE_NAME = "kbn-plugin-generator" PKG_REQUIRE_NAME = "@kbn/plugin-generator" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__plugin-generator" SOURCE_FILES = glob( [ @@ -96,7 +97,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -115,3 +116,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-plugin-generator/package.json b/packages/kbn-plugin-generator/package.json index d30f25e478dcf..28b7e849ab3c1 100644 --- a/packages/kbn-plugin-generator/package.json +++ b/packages/kbn-plugin-generator/package.json @@ -3,6 +3,5 @@ "version": "1.0.0", "private": true, "license": "SSPL-1.0 OR Elastic License 2.0", - "main": "target_node/index.js", - "types": "target_types/index.d.ts" + "main": "target_node/index.js" } \ No newline at end of file diff --git a/packages/kbn-plugin-helpers/BUILD.bazel b/packages/kbn-plugin-helpers/BUILD.bazel index 84afabb354aa5..eeb5d06a3866a 100644 --- a/packages/kbn-plugin-helpers/BUILD.bazel +++ b/packages/kbn-plugin-helpers/BUILD.bazel @@ -1,10 +1,11 @@ -load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") -load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") -load("//src/dev/bazel:index.bzl", "jsts_transpiler") +load("@npm//@bazel/typescript:index.bzl", "ts_config") +load("@build_bazel_rules_nodejs//:index.bzl", "js_library") +load("//src/dev/bazel:index.bzl", "jsts_transpiler", "pkg_npm", "pkg_npm_types", "ts_project") PKG_BASE_NAME = "kbn-plugin-helpers" PKG_REQUIRE_NAME = "@kbn/plugin-helpers" +TYPES_PKG_REQUIRE_NAME = "@types/kbn__plugin-helpers" SOURCE_FILES = glob( [ @@ -89,7 +90,7 @@ ts_project( js_library( name = PKG_BASE_NAME, srcs = NPM_MODULE_EXTRA_FILES, - deps = RUNTIME_DEPS + [":target_node", ":tsc_types"], + deps = RUNTIME_DEPS + [":target_node"], package_name = PKG_REQUIRE_NAME, visibility = ["//visibility:public"], ) @@ -108,3 +109,20 @@ filegroup( ], visibility = ["//visibility:public"], ) + +pkg_npm_types( + name = "npm_module_types", + srcs = SRCS, + deps = [":tsc_types"], + package_name = TYPES_PKG_REQUIRE_NAME, + tsconfig = ":tsconfig", + visibility = ["//visibility:public"], +) + +filegroup( + name = "build_types", + srcs = [ + ":npm_module_types", + ], + visibility = ["//visibility:public"], +) diff --git a/packages/kbn-plugin-helpers/package.json b/packages/kbn-plugin-helpers/package.json index 21ed8f46f52fa..cac041762f739 100644 --- a/packages/kbn-plugin-helpers/package.json +++ b/packages/kbn-plugin-helpers/package.json @@ -8,7 +8,6 @@ "devOnly": true }, "main": "target_node/index.js", - "types": "target_types/index.d.ts", "bin": { "plugin-helpers": "bin/plugin-helpers.js" } diff --git a/packages/kbn-rule-data-utils/src/technical_field_names.ts b/packages/kbn-rule-data-utils/src/technical_field_names.ts index 16b9ba91b96f2..c6edd30549a76 100644 --- a/packages/kbn-rule-data-utils/src/technical_field_names.ts +++ b/packages/kbn-rule-data-utils/src/technical_field_names.ts @@ -55,12 +55,8 @@ const ALERT_RULE_NAME = `${ALERT_RULE_NAMESPACE}.name` as const; const ALERT_RULE_NOTE = `${ALERT_RULE_NAMESPACE}.note` as const; const ALERT_RULE_PARAMETERS = `${ALERT_RULE_NAMESPACE}.parameters` as const; const ALERT_RULE_REFERENCES = `${ALERT_RULE_NAMESPACE}.references` as const; -const ALERT_RULE_RISK_SCORE = `${ALERT_RULE_NAMESPACE}.risk_score` as const; -const ALERT_RULE_RISK_SCORE_MAPPING = `${ALERT_RULE_NAMESPACE}.risk_score_mapping` as const; const ALERT_RULE_RULE_ID = `${ALERT_RULE_NAMESPACE}.rule_id` as const; const ALERT_RULE_RULE_NAME_OVERRIDE = `${ALERT_RULE_NAMESPACE}.rule_name_override` as const; -const ALERT_RULE_SEVERITY = `${ALERT_RULE_NAMESPACE}.severity` as const; -const ALERT_RULE_SEVERITY_MAPPING = `${ALERT_RULE_NAMESPACE}.severity_mapping` as const; const ALERT_RULE_TAGS = `${ALERT_RULE_NAMESPACE}.tags` as const; const ALERT_RULE_TO = `${ALERT_RULE_NAMESPACE}.to` as const; const ALERT_RULE_TYPE = `${ALERT_RULE_NAMESPACE}.type` as const; @@ -114,12 +110,8 @@ const fields = { ALERT_RULE_NOTE, ALERT_RULE_PARAMETERS, ALERT_RULE_REFERENCES, - ALERT_RULE_RISK_SCORE, - ALERT_RULE_RISK_SCORE_MAPPING, ALERT_RULE_RULE_ID, ALERT_RULE_RULE_NAME_OVERRIDE, - ALERT_RULE_SEVERITY, - ALERT_RULE_SEVERITY_MAPPING, ALERT_RULE_TAGS, ALERT_RULE_TO, ALERT_RULE_TYPE, @@ -171,11 +163,8 @@ export { ALERT_RULE_NOTE, ALERT_RULE_PARAMETERS, ALERT_RULE_REFERENCES, - ALERT_RULE_RISK_SCORE, - ALERT_RULE_RISK_SCORE_MAPPING, ALERT_RULE_RULE_ID, ALERT_RULE_RULE_NAME_OVERRIDE, - ALERT_RULE_SEVERITY_MAPPING, ALERT_RULE_TAGS, ALERT_RULE_TO, ALERT_RULE_TYPE, @@ -183,7 +172,6 @@ export { ALERT_RULE_UPDATED_AT, ALERT_RULE_UPDATED_BY, ALERT_RULE_VERSION, - ALERT_RULE_SEVERITY, ALERT_SEVERITY, ALERT_START, ALERT_SYSTEM_STATUS, diff --git a/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts b/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts index 904ccc385bd7d..f70123029e6c4 100644 --- a/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts +++ b/packages/kbn-test/src/kbn_client/kbn_client_saved_objects.ts @@ -36,6 +36,7 @@ interface SavedObjectResponse> { interface GetOptions { type: string; id: string; + space?: string; } interface IndexOptions { @@ -110,11 +111,13 @@ export class KbnClientSavedObjects { * Get an object */ public async get>(options: GetOptions) { - this.log.debug('Gettings saved object: %j', options); + this.log.debug('Getting saved object: %j', options); const { data } = await this.requester.request>({ description: 'get saved object', - path: uriencode`/api/saved_objects/${options.type}/${options.id}`, + path: options.space + ? uriencode`/s/${options.space}/api/saved_objects/${options.type}/${options.id}` + : uriencode`/api/saved_objects/${options.type}/${options.id}`, method: 'GET', }); return data; @@ -174,7 +177,9 @@ export class KbnClientSavedObjects { const { data } = await this.requester.request({ description: 'delete saved object', - path: uriencode`/api/saved_objects/${options.type}/${options.id}`, + path: options.space + ? uriencode`/s/${options.space}/api/saved_objects/${options.type}/${options.id}` + : uriencode`/api/saved_objects/${options.type}/${options.id}`, method: 'DELETE', }); diff --git a/renovate.json b/renovate.json index a6b54a3dae349..95358af48a2cc 100644 --- a/renovate.json +++ b/renovate.json @@ -26,7 +26,7 @@ "matchPackageNames": ["@elastic/charts"], "reviewers": ["team:datavis"], "matchBaseBranches": ["main"], - "labels": ["release_note:skip", "v8.0.0", "v7.16.0", "auto-backport"], + "labels": ["release_note:skip", "auto-backport", "Team:DataVis", "v8.1.0", "v7.17.0"], "draftPR": true, "enabled": true }, @@ -35,7 +35,7 @@ "matchPackageNames": ["@elastic/elasticsearch"], "reviewers": ["team:kibana-operations", "team:kibana-core"], "matchBaseBranches": ["main"], - "labels": ["release_note:skip", "v8.0.0", "Team:Operations", "Team:Core", "backport:skip"], + "labels": ["release_note:skip", "backport:skip", "Team:Operations", "Team:Core", "v8.1.0"], "enabled": true }, { @@ -126,6 +126,21 @@ "matchBaseBranches": ["main"], "labels": ["Team:Security", "release_note:skip", "auto-backport"], "enabled": true + }, + { + "groupName": "ftr", + "packageNames": [ + "@types/chromedriver", + "@types/selenium-webdriver", + "chromedriver", + "geckodriver", + "ms-chromium-edge-driver", + "selenium-webdriver" + ], + "reviewers": ["team:kibana-operations"], + "matchBaseBranches": ["main"], + "labels": ["Team:Operations", "release_note:skip"], + "enabled": true } ] } diff --git a/src/dev/build/args.test.ts b/src/dev/build/args.test.ts index 354de9fee60d7..5601e063414b3 100644 --- a/src/dev/build/args.test.ts +++ b/src/dev/build/args.test.ts @@ -28,10 +28,10 @@ it('build default and oss dist for current platform, without packages, by defaul "buildOptions": Object { "createArchives": true, "createDebPackage": false, - "createDockerCentOS": false, "createDockerCloud": false, "createDockerContexts": true, "createDockerUBI": false, + "createDockerUbuntu": false, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -58,10 +58,10 @@ it('builds packages if --all-platforms is passed', () => { "buildOptions": Object { "createArchives": true, "createDebPackage": true, - "createDockerCentOS": true, "createDockerCloud": true, "createDockerContexts": true, "createDockerUBI": true, + "createDockerUbuntu": true, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -88,10 +88,10 @@ it('limits packages if --rpm passed with --all-platforms', () => { "buildOptions": Object { "createArchives": true, "createDebPackage": false, - "createDockerCentOS": false, "createDockerCloud": false, "createDockerContexts": true, "createDockerUBI": false, + "createDockerUbuntu": false, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -118,10 +118,10 @@ it('limits packages if --deb passed with --all-platforms', () => { "buildOptions": Object { "createArchives": true, "createDebPackage": true, - "createDockerCentOS": false, "createDockerCloud": false, "createDockerContexts": true, "createDockerUBI": false, + "createDockerUbuntu": false, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -149,10 +149,10 @@ it('limits packages if --docker passed with --all-platforms', () => { "buildOptions": Object { "createArchives": true, "createDebPackage": false, - "createDockerCentOS": true, "createDockerCloud": true, "createDockerContexts": true, "createDockerUBI": true, + "createDockerUbuntu": true, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -187,10 +187,10 @@ it('limits packages if --docker passed with --skip-docker-ubi and --all-platform "buildOptions": Object { "createArchives": true, "createDebPackage": false, - "createDockerCentOS": true, "createDockerCloud": true, "createDockerContexts": true, "createDockerUBI": false, + "createDockerUbuntu": true, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, @@ -211,17 +211,17 @@ it('limits packages if --docker passed with --skip-docker-ubi and --all-platform `); }); -it('limits packages if --all-platforms passed with --skip-docker-centos', () => { - expect(readCliArgs(['node', 'scripts/build', '--all-platforms', '--skip-docker-centos'])) +it('limits packages if --all-platforms passed with --skip-docker-ubuntu', () => { + expect(readCliArgs(['node', 'scripts/build', '--all-platforms', '--skip-docker-ubuntu'])) .toMatchInlineSnapshot(` Object { "buildOptions": Object { "createArchives": true, "createDebPackage": true, - "createDockerCentOS": false, "createDockerCloud": true, "createDockerContexts": true, "createDockerUBI": true, + "createDockerUbuntu": false, "createExamplePlugins": false, "createGenericFolders": true, "createPlatformFolders": true, diff --git a/src/dev/build/args.ts b/src/dev/build/args.ts index 78f097b595c40..d890dbef4e74f 100644 --- a/src/dev/build/args.ts +++ b/src/dev/build/args.ts @@ -26,7 +26,7 @@ export function readCliArgs(argv: string[]) { 'docker-push', 'skip-docker-contexts', 'skip-docker-ubi', - 'skip-docker-centos', + 'skip-docker-ubuntu', 'skip-docker-cloud', 'release', 'skip-node-download', @@ -109,8 +109,8 @@ export function readCliArgs(argv: string[]) { createExamplePlugins: Boolean(flags['example-plugins']), createRpmPackage: isOsPackageDesired('rpm'), createDebPackage: isOsPackageDesired('deb'), - createDockerCentOS: - isOsPackageDesired('docker-images') && !Boolean(flags['skip-docker-centos']), + createDockerUbuntu: + isOsPackageDesired('docker-images') && !Boolean(flags['skip-docker-ubuntu']), createDockerCloud: isOsPackageDesired('docker-images') && !Boolean(flags['skip-docker-cloud']), createDockerUBI: isOsPackageDesired('docker-images') && !Boolean(flags['skip-docker-ubi']), createDockerContexts: !Boolean(flags['skip-docker-contexts']), diff --git a/src/dev/build/build_distributables.ts b/src/dev/build/build_distributables.ts index 9e3a419d63964..992486796dfad 100644 --- a/src/dev/build/build_distributables.ts +++ b/src/dev/build/build_distributables.ts @@ -24,7 +24,7 @@ export interface BuildOptions { createRpmPackage: boolean; createDebPackage: boolean; createDockerUBI: boolean; - createDockerCentOS: boolean; + createDockerUbuntu: boolean; createDockerCloud: boolean; createDockerContexts: boolean; versionQualifier: string | undefined; @@ -126,9 +126,9 @@ export async function buildDistributables(log: ToolingLog, options: BuildOptions await run(Tasks.CreateDockerUBI); } - if (options.createDockerCentOS) { - // control w/ --docker-images or --skip-docker-centos or --skip-os-packages - await run(Tasks.CreateDockerCentOS); + if (options.createDockerUbuntu) { + // control w/ --docker-images or --skip-docker-ubuntu or --skip-os-packages + await run(Tasks.CreateDockerUbuntu); } if (options.createDockerCloud) { diff --git a/src/dev/build/cli.ts b/src/dev/build/cli.ts index c727c26d7dcd3..323a40d02de66 100644 --- a/src/dev/build/cli.ts +++ b/src/dev/build/cli.ts @@ -41,7 +41,7 @@ if (showHelp) { --docker-images {dim Only build the Docker images} --docker-contexts {dim Only build the Docker build contexts} --skip-docker-ubi {dim Don't build the docker ubi image} - --skip-docker-centos {dim Don't build the docker centos image} + --skip-docker-ubuntu {dim Don't build the docker ubuntu image} --release {dim Produce a release-ready distributable} --version-qualifier {dim Suffix version with a qualifier} --skip-node-download {dim Reuse existing downloads of node.js} diff --git a/src/dev/build/tasks/os_packages/create_os_package_tasks.ts b/src/dev/build/tasks/os_packages/create_os_package_tasks.ts index ab9a7ce65cbc6..b4724085c5184 100644 --- a/src/dev/build/tasks/os_packages/create_os_package_tasks.ts +++ b/src/dev/build/tasks/os_packages/create_os_package_tasks.ts @@ -59,20 +59,22 @@ export const CreateRpmPackage: Task = { }; const dockerBuildDate = new Date().toISOString(); -export const CreateDockerCentOS: Task = { - description: 'Creating Docker CentOS image', +export const CreateDockerUbuntu: Task = { + description: 'Creating Docker Ubuntu image', async run(config, log, build) { await runDockerGenerator(config, log, build, { architecture: 'x64', context: false, image: true, + ubuntu: true, dockerBuildDate, }); await runDockerGenerator(config, log, build, { architecture: 'aarch64', context: false, image: true, + ubuntu: true, dockerBuildDate, }); }, @@ -99,12 +101,14 @@ export const CreateDockerCloud: Task = { architecture: 'x64', context: false, cloud: true, + ubuntu: true, image: true, }); await runDockerGenerator(config, log, build, { architecture: 'aarch64', context: false, cloud: true, + ubuntu: true, image: true, }); }, diff --git a/src/dev/build/tasks/os_packages/docker_generator/run.ts b/src/dev/build/tasks/os_packages/docker_generator/run.ts index 085b4393caa66..657efc8d7bd99 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/run.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/run.ts @@ -32,13 +32,15 @@ export async function runDockerGenerator( context: boolean; image: boolean; ubi?: boolean; + ubuntu?: boolean; ironbank?: boolean; cloud?: boolean; dockerBuildDate?: string; } ) { - // UBI var config - const baseOSImage = flags.ubi ? 'docker.elastic.co/ubi8/ubi-minimal:latest' : 'centos:8'; + let baseOSImage = ''; + if (flags.ubuntu) baseOSImage = 'ubuntu:20.04'; + if (flags.ubi) baseOSImage = 'docker.elastic.co/ubi8/ubi-minimal:latest'; const ubiVersionTag = 'ubi8'; let imageFlavor = ''; @@ -91,6 +93,7 @@ export async function runDockerGenerator( baseOSImage, dockerBuildDate, ubi: flags.ubi, + ubuntu: flags.ubuntu, cloud: flags.cloud, metricbeatTarball, filebeatTarball, diff --git a/src/dev/build/tasks/os_packages/docker_generator/template_context.ts b/src/dev/build/tasks/os_packages/docker_generator/template_context.ts index 143fcf16ace56..a715bfaa5d50d 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/template_context.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/template_context.ts @@ -23,6 +23,7 @@ export interface TemplateContext { dockerBuildDate: string; usePublicArtifact?: boolean; ubi?: boolean; + ubuntu?: boolean; cloud?: boolean; metricbeatTarball?: string; filebeatTarball?: string; diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile index 90a622e64efe4..54af1c41b2da9 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/base/Dockerfile @@ -14,6 +14,9 @@ FROM {{{baseOSImage}}} AS builder {{#ubi}} RUN {{packageManager}} install -y findutils tar gzip {{/ubi}} +{{#ubuntu}} +RUN {{packageManager}} update && DEBIAN_FRONTEND=noninteractive {{packageManager}} install -y curl +{{/ubuntu}} {{#usePublicArtifact}} RUN cd /tmp && \ @@ -55,18 +58,28 @@ FROM {{{baseOSImage}}} EXPOSE 5601 {{#ubi}} - # https://github.com/rpm-software-management/microdnf/issues/50 - RUN mkdir -p /run/user/$(id -u) -{{/ubi}} - RUN for iter in {1..10}; do \ {{packageManager}} update --setopt=tsflags=nodocs -y && \ {{packageManager}} install --setopt=tsflags=nodocs -y \ - fontconfig freetype shadow-utils nss {{#ubi}}findutils{{/ubi}} && \ + fontconfig freetype shadow-utils nss findutils && \ {{packageManager}} clean all && exit_code=0 && break || exit_code=$? && echo "{{packageManager}} error: retry $iter in 10s" && \ sleep 10; \ done; \ (exit $exit_code) +{{/ubi}} +{{#ubuntu}} +RUN for iter in {1..10}; do \ + export DEBIAN_FRONTEND=noninteractive && \ + {{packageManager}} update && \ + {{packageManager}} upgrade -y && \ + {{packageManager}} install -y --no-install-recommends \ + fontconfig fonts-liberation libnss3 libfontconfig1 ca-certificates curl && \ + {{packageManager}} clean && \ + rm -rf /var/lib/apt/lists/* && exit_code=0 && break || exit_code=$? && echo "{{packageManager}} error: retry $iter in 10s" && \ + sleep 10; \ + done; \ + (exit $exit_code) +{{/ubuntu}} # Add an init process, check the checksum to make sure it's a match RUN set -e ; \ @@ -164,7 +177,7 @@ ENTRYPOINT ["/bin/tini", "--"] CMD ["/app/kibana.sh"] # Generate a stub command that will be overwritten at runtime RUN mkdir /app && \ - echo -e '#!/bin/sh\nexec /usr/local/bin/kibana-docker' > /app/kibana.sh && \ + echo -e '#!/bin/bash\nexec /usr/local/bin/kibana-docker' > /app/kibana.sh && \ chmod 0555 /app/kibana.sh {{/cloud}} diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts b/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts index e668299a3acc3..94068f2b64b12 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/dockerfile.template.ts @@ -16,7 +16,7 @@ function generator(options: TemplateContext) { const dir = options.ironbank ? 'ironbank' : 'base'; const template = readFileSync(resolve(__dirname, dir, './Dockerfile')); return Mustache.render(template.toString(), { - packageManager: options.ubi ? 'microdnf' : 'yum', + packageManager: options.ubi ? 'microdnf' : 'apt-get', ...options, }); } diff --git a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx index a5f59b976d3ba..76d4b9dd8e801 100644 --- a/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx +++ b/src/plugins/data/public/ui/query_string_input/query_bar_top_row.tsx @@ -32,33 +32,34 @@ const QueryStringInput = withKibana(QueryStringInputUI); // @internal export interface QueryBarTopRowProps { - query?: Query; - onSubmit: (payload: { dateRange: TimeRange; query?: Query }) => void; - onChange: (payload: { dateRange: TimeRange; query?: Query }) => void; - onRefresh?: (payload: { dateRange: TimeRange }) => void; + customSubmitButton?: any; dataTestSubj?: string; + dateRangeFrom?: string; + dateRangeTo?: string; disableAutoFocus?: boolean; - screenTitle?: string; + fillSubmitButton: boolean; + iconType?: EuiIconProps['type']; indexPatterns?: Array; + indicateNoData?: boolean; + isClearable?: boolean; + isDirty: boolean; isLoading?: boolean; + isRefreshPaused?: boolean; + nonKqlMode?: 'lucene' | 'text'; + nonKqlModeHelpText?: string; + onChange: (payload: { dateRange: TimeRange; query?: Query }) => void; + onRefresh?: (payload: { dateRange: TimeRange }) => void; + onRefreshChange?: (options: { isPaused: boolean; refreshInterval: number }) => void; + onSubmit: (payload: { dateRange: TimeRange; query?: Query }) => void; + placeholder?: string; prepend?: React.ComponentProps['prepend']; + query?: Query; + refreshInterval?: number; + screenTitle?: string; showQueryInput?: boolean; showDatePicker?: boolean; - dateRangeFrom?: string; - dateRangeTo?: string; - isRefreshPaused?: boolean; - refreshInterval?: number; showAutoRefreshOnly?: boolean; - onRefreshChange?: (options: { isPaused: boolean; refreshInterval: number }) => void; - customSubmitButton?: any; - isDirty: boolean; timeHistory?: TimeHistoryContract; - indicateNoData?: boolean; - iconType?: EuiIconProps['type']; - placeholder?: string; - isClearable?: boolean; - nonKqlMode?: 'lucene' | 'text'; - nonKqlModeHelpText?: string; timeRangeForSuggestionsOverride?: boolean; } @@ -229,7 +230,7 @@ export default function QueryBarTopRow(props: QueryBarTopRowProps) { isDisabled={isDateRangeInvalid} isLoading={props.isLoading} onClick={onClickSubmitButton} - fill={false} + fill={props.fillSubmitButton} data-test-subj="querySubmitButton" /> ); diff --git a/src/plugins/data/public/ui/search_bar/search_bar.tsx b/src/plugins/data/public/ui/search_bar/search_bar.tsx index 3fef455be41c3..87b6480096551 100644 --- a/src/plugins/data/public/ui/search_bar/search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/search_bar.tsx @@ -77,6 +77,8 @@ export interface SearchBarOwnProps { nonKqlModeHelpText?: string; // defines padding; use 'inPage' to avoid extra padding; use 'detached' if the searchBar appears at the very top of the view, without any wrapper displayStyle?: 'inPage' | 'detached'; + // super update button background fill control + fillSubmitButton?: boolean; } export type SearchBarProps = SearchBarOwnProps & SearchBarInjectedDeps; @@ -365,6 +367,7 @@ class SearchBarUI extends Component { onSubmit={this.onQueryBarSubmit} indexPatterns={this.props.indexPatterns} isLoading={this.props.isLoading} + fillSubmitButton={this.props.fillSubmitButton || false} prepend={this.props.showFilterBar ? savedQueryManagement : undefined} showDatePicker={this.props.showDatePicker} dateRangeFrom={this.state.dateRangeFrom} diff --git a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx index 6316369ff4c6f..27f2845503978 100644 --- a/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx +++ b/src/plugins/discover/public/application/main/components/sidebar/discover_sidebar_responsive.tsx @@ -123,16 +123,11 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) const [fieldFilter, setFieldFilter] = useState(getDefaultFieldFilter()); const [isFlyoutVisible, setIsFlyoutVisible] = useState(false); /** - * needed for merging new with old field counts, high likely legacy, but kept this behavior - * because not 100% sure in this case + * fieldCounts are used to determine which fields are actually used in the given set of documents */ const fieldCounts = useRef | null>(null); if (fieldCounts.current === null) { - fieldCounts.current = calcFieldCounts( - {}, - props.documents$.getValue().result, - selectedIndexPattern - ); + fieldCounts.current = calcFieldCounts(props.documents$.getValue().result, selectedIndexPattern); } const [documentState, setDocumentState] = useState(props.documents$.getValue()); @@ -140,11 +135,7 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) const subscription = props.documents$.subscribe((next) => { if (next.fetchStatus !== documentState.fetchStatus) { if (next.result) { - fieldCounts.current = calcFieldCounts( - next.result.length && fieldCounts.current ? fieldCounts.current : {}, - next.result, - selectedIndexPattern! - ); + fieldCounts.current = calcFieldCounts(next.result, selectedIndexPattern!); } setDocumentState({ ...documentState, ...next }); } diff --git a/src/plugins/discover/public/application/main/utils/calc_field_counts.test.ts b/src/plugins/discover/public/application/main/utils/calc_field_counts.test.ts index 28d814b871104..2ed564194bd25 100644 --- a/src/plugins/discover/public/application/main/utils/calc_field_counts.test.ts +++ b/src/plugins/discover/public/application/main/utils/calc_field_counts.test.ts @@ -16,7 +16,7 @@ describe('calcFieldCounts', () => { { _id: 1, _source: { message: 'test1', bytes: 20 } }, { _id: 2, _source: { name: 'test2', extension: 'jpg' } }, ] as unknown as ElasticSearchHit[]; - const result = calcFieldCounts({}, rows, indexPatternMock); + const result = calcFieldCounts(rows, indexPatternMock); expect(result).toMatchInlineSnapshot(` Object { "_index": 2, @@ -33,14 +33,14 @@ describe('calcFieldCounts', () => { { _id: 1, _source: { message: 'test1', bytes: 20 } }, { _id: 2, _source: { name: 'test2', extension: 'jpg' } }, ] as unknown as ElasticSearchHit[]; - const result = calcFieldCounts({ message: 2 }, rows, indexPatternMock); + const result = calcFieldCounts(rows, indexPatternMock); expect(result).toMatchInlineSnapshot(` Object { "_index": 2, "_score": 2, "bytes": 1, "extension": 1, - "message": 3, + "message": 1, "name": 1, } `); diff --git a/src/plugins/discover/public/application/main/utils/calc_field_counts.ts b/src/plugins/discover/public/application/main/utils/calc_field_counts.ts index 9a7f68550d840..e315ec15d9284 100644 --- a/src/plugins/discover/public/application/main/utils/calc_field_counts.ts +++ b/src/plugins/discover/public/application/main/utils/calc_field_counts.ts @@ -10,14 +10,11 @@ import { flattenHit, IndexPattern } from '../../../../../data/common'; import { ElasticSearchHit } from '../../../types'; /** - * This function is recording stats of the available fields, for usage in sidebar and sharing + * This function is calculating stats of the available fields, for usage in sidebar and sharing * Note that this values aren't displayed, but used for internal calculations */ -export function calcFieldCounts( - counts = {} as Record, - rows?: ElasticSearchHit[], - indexPattern?: IndexPattern -) { +export function calcFieldCounts(rows?: ElasticSearchHit[], indexPattern?: IndexPattern) { + const counts: Record = {}; if (!rows || !indexPattern) { return {}; } diff --git a/src/plugins/embeddable/common/index.ts b/src/plugins/embeddable/common/index.ts index b6a6fe101668e..4eed6531cf7d5 100644 --- a/src/plugins/embeddable/common/index.ts +++ b/src/plugins/embeddable/common/index.ts @@ -6,8 +6,13 @@ * Side Public License, v 1. */ -// TODO: https://github.com/elastic/kibana/issues/109903 -/* eslint-disable @kbn/eslint/no_export_all */ - -export * from './types'; -export * from './lib'; +export type { + EmbeddableInput, + CommonEmbeddableStartContract, + EmbeddableStateWithType, + PanelState, + EmbeddablePersistableStateService, +} from './types'; +export { ViewMode } from './types'; +export type { SavedObjectEmbeddableInput } from './lib'; +export { isSavedObjectEmbeddableInput } from './lib'; diff --git a/src/plugins/embeddable/common/lib/index.ts b/src/plugins/embeddable/common/lib/index.ts index c7e8473937cc7..4cc8715334cf8 100644 --- a/src/plugins/embeddable/common/lib/index.ts +++ b/src/plugins/embeddable/common/lib/index.ts @@ -6,9 +6,10 @@ * Side Public License, v 1. */ -export * from './extract'; -export * from './inject'; -export * from './migrate'; -export * from './migrate_base_input'; -export * from './telemetry'; -export * from './saved_object_embeddable'; +export { getExtractFunction } from './extract'; +export { getInjectFunction } from './inject'; +export type { MigrateFunction } from './migrate'; +export { getMigrateFunction } from './migrate'; +export { getTelemetryFunction } from './telemetry'; +export type { SavedObjectEmbeddableInput } from './saved_object_embeddable'; +export { isSavedObjectEmbeddableInput } from './saved_object_embeddable'; diff --git a/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap b/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap index 1cf6a3409539e..b05abbcece0b9 100644 --- a/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap +++ b/src/plugins/kibana_react/public/code_editor/__snapshots__/code_editor.test.tsx.snap @@ -215,6 +215,7 @@ exports[` is rendered 1`] = ` " >
+