(queryLanguage ? getQueryLog(uiSettings!, storage, appName, queryLanguage) : undefined),
- [queryLanguage]
+ () =>
+ queryLanguage && uiSettings && storage && appName
+ ? getQueryLog(uiSettings!, storage, appName, queryLanguage)
+ : undefined,
+ [appName, queryLanguage, uiSettings, storage]
);
function onClickSubmitButton(event: React.MouseEvent) {
@@ -298,7 +305,7 @@ function QueryBarTopRowUI(props: Props) {
id: 'data.query.queryBar.luceneSyntaxWarningTitle',
defaultMessage: 'Lucene syntax warning',
}),
- text: (
+ text: toMountPoint(
;
-
-const createSetupContractMock = () => {
- const setupContract: jest.Mocked = {
- helpers: {
- fromUser: jest.fn(),
- toUser: jest.fn(),
- getQueryLog: jest.fn(),
- },
- };
-
- return setupContract;
-};
-
-const createMock = () => {
- const mocked: jest.Mocked = {
- setup: jest.fn(),
- start: jest.fn(),
- stop: jest.fn(),
- };
-
- mocked.setup.mockReturnValue(createSetupContractMock());
- return mocked;
-};
-
-export const queryServiceMock = {
- create: createMock,
- createSetupContract: createSetupContractMock,
- createStartContract: createSetupContractMock,
-};
diff --git a/src/legacy/core_plugins/data/public/search/search_bar/components/search_bar.tsx b/src/legacy/core_plugins/data/public/search/search_bar/components/search_bar.tsx
index a57b7b17a0da6..d713139366eef 100644
--- a/src/legacy/core_plugins/data/public/search/search_bar/components/search_bar.tsx
+++ b/src/legacy/core_plugins/data/public/search/search_bar/components/search_bar.tsx
@@ -24,9 +24,8 @@ import React, { Component } from 'react';
import ResizeObserver from 'resize-observer-polyfill';
import { get, isEqual } from 'lodash';
-import { TimeRange } from 'src/plugins/data/common/types';
-import { TimeHistoryContract } from 'src/plugins/data/public';
-import { IndexPattern, Query, FilterBar } from '../../../../../data/public';
+import { TimeRange, Query, TimeHistoryContract } from 'src/plugins/data/public';
+import { IndexPattern, FilterBar } from '../../../../../data/public';
import { QueryBarTopRow } from '../../../query';
import { SavedQuery, SavedQueryAttributes } from '../index';
import { SavedQueryMeta, SaveQueryForm } from './saved_query_management/save_query_form';
@@ -73,6 +72,7 @@ export interface SearchBarOwnProps {
// Show when user has privileges to save
showSaveQuery?: boolean;
savedQuery?: SavedQuery;
+ onQueryChange?: (payload: { dateRange: TimeRange; query?: Query }) => void;
onQuerySubmit?: (payload: { dateRange: TimeRange; query?: Query }) => void;
// User has saved the current state as a saved query
onSaved?: (savedQuery: SavedQuery) => void;
@@ -207,6 +207,18 @@ class SearchBarUI extends Component {
);
}
+ /*
+ * This Function is here to show the toggle in saved query form
+ * in case you the date range (from/to)
+ */
+ private shouldRenderTimeFilterInSavedQueryForm() {
+ const { dateRangeFrom, dateRangeTo, showDatePicker } = this.props;
+ return (
+ showDatePicker ||
+ (!showDatePicker && dateRangeFrom !== undefined && dateRangeTo !== undefined)
+ );
+ }
+
public setFilterBarHeight = () => {
requestAnimationFrame(() => {
const height =
@@ -300,6 +312,9 @@ class SearchBarUI extends Component {
dateRangeFrom: queryAndDateRange.dateRange.from,
dateRangeTo: queryAndDateRange.dateRange.to,
});
+ if (this.props.onQueryChange) {
+ this.props.onQueryChange(queryAndDateRange);
+ }
};
public onQueryBarSubmit = (queryAndDateRange: { dateRange?: TimeRange; query?: Query }) => {
@@ -441,7 +456,7 @@ class SearchBarUI extends Component {
onSave={this.onSave}
onClose={() => this.setState({ showSaveQueryModal: false })}
showFilterOption={this.props.showFilterBar}
- showTimeFilterOption={this.props.showDatePicker}
+ showTimeFilterOption={this.shouldRenderTimeFilterInSavedQueryForm()}
/>
) : null}
{this.state.showSaveNewQueryModal ? (
@@ -450,7 +465,7 @@ class SearchBarUI extends Component {
onSave={savedQueryMeta => this.onSave(savedQueryMeta, true)}
onClose={() => this.setState({ showSaveNewQueryModal: false })}
showFilterOption={this.props.showFilterBar}
- showTimeFilterOption={this.props.showDatePicker}
+ showTimeFilterOption={this.shouldRenderTimeFilterInSavedQueryForm()}
/>
) : null}
diff --git a/src/legacy/core_plugins/data/public/search/search_bar/index.tsx b/src/legacy/core_plugins/data/public/search/search_bar/index.tsx
index ebde9d60b0b51..f369bf997c1a9 100644
--- a/src/legacy/core_plugins/data/public/search/search_bar/index.tsx
+++ b/src/legacy/core_plugins/data/public/search/search_bar/index.tsx
@@ -17,9 +17,7 @@
* under the License.
*/
-import { RefreshInterval, TimeRange } from 'src/plugins/data/public';
-import { Query } from '../../query/query_bar';
-import { esFilters } from '../../../../../../plugins/data/public';
+import { RefreshInterval, TimeRange, Query, esFilters } from 'src/plugins/data/public';
export * from './components';
diff --git a/src/legacy/core_plugins/input_control_vis/public/components/editor/list_control_editor.test.js b/src/legacy/core_plugins/input_control_vis/public/components/editor/list_control_editor.test.js
index 96c0802d3772a..ea029af9e4890 100644
--- a/src/legacy/core_plugins/input_control_vis/public/components/editor/list_control_editor.test.js
+++ b/src/legacy/core_plugins/input_control_vis/public/components/editor/list_control_editor.test.js
@@ -236,7 +236,7 @@ test('handleCheckboxOptionChange - multiselect', async () => {
component.update();
const checkbox = findTestSubject(component, 'listControlMultiselectInput');
- checkbox.simulate('change', { target: { checked: true } });
+ checkbox.simulate('click');
sinon.assert.notCalled(handleFieldNameChange);
sinon.assert.notCalled(handleIndexPatternChange);
sinon.assert.notCalled(handleNumberOptionChange);
@@ -247,7 +247,9 @@ test('handleCheckboxOptionChange - multiselect', async () => {
expectedControlIndex,
expectedOptionName,
sinon.match((evt) => {
- if (evt.target.checked === true) {
+ // Synthetic `evt.target.checked` does not get altered by EuiSwitch,
+ // but its aria attribute is correctly updated
+ if (evt.target.getAttribute('aria-checked') === 'true') {
return true;
}
return false;
diff --git a/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js b/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js
index 39f5f6a50a5a6..8784f0e79ca8d 100644
--- a/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js
+++ b/src/legacy/core_plugins/input_control_vis/public/components/editor/options_tab.test.js
@@ -47,8 +47,8 @@ describe('OptionsTab', () => {
it('should update updateFiltersOnChange', () => {
const component = mountWithIntl();
- const checkbox = component.find('[data-test-subj="inputControlEditorUpdateFiltersOnChangeCheckbox"] input[type="checkbox"]');
- checkbox.simulate('change', { target: { checked: true } });
+ const checkbox = component.find('[data-test-subj="inputControlEditorUpdateFiltersOnChangeCheckbox"] button');
+ checkbox.simulate('click');
expect(props.setValue).toHaveBeenCalledTimes(1);
expect(props.setValue).toHaveBeenCalledWith('updateFiltersOnChange', true);
@@ -56,8 +56,8 @@ describe('OptionsTab', () => {
it('should update useTimeFilter', () => {
const component = mountWithIntl();
- const checkbox = component.find('[data-test-subj="inputControlEditorUseTimeFilterCheckbox"] input[type="checkbox"]');
- checkbox.simulate('change', { target: { checked: true } });
+ const checkbox = component.find('[data-test-subj="inputControlEditorUseTimeFilterCheckbox"] button');
+ checkbox.simulate('click');
expect(props.setValue).toHaveBeenCalledTimes(1);
expect(props.setValue).toHaveBeenCalledWith('useTimeFilter', true);
@@ -65,8 +65,8 @@ describe('OptionsTab', () => {
it('should update pinFilters', () => {
const component = mountWithIntl();
- const checkbox = component.find('[data-test-subj="inputControlEditorPinFiltersCheckbox"] input[type="checkbox"]');
- checkbox.simulate('change', { target: { checked: true } });
+ const checkbox = component.find('[data-test-subj="inputControlEditorPinFiltersCheckbox"] button');
+ checkbox.simulate('click');
expect(props.setValue).toHaveBeenCalledTimes(1);
expect(props.setValue).toHaveBeenCalledWith('pinFilters', true);
diff --git a/src/legacy/core_plugins/interpreter/public/renderers/visualization.tsx b/src/legacy/core_plugins/interpreter/public/renderers/visualization.tsx
index 9de6cdeaf5ec3..f15cdf23fe15b 100644
--- a/src/legacy/core_plugins/interpreter/public/renderers/visualization.tsx
+++ b/src/legacy/core_plugins/interpreter/public/renderers/visualization.tsx
@@ -21,7 +21,7 @@ import chrome from 'ui/chrome';
import React from 'react';
import { render, unmountComponentAtNode } from 'react-dom';
// @ts-ignore
-import { VisProvider } from '../../../../ui/public/visualize/loader/vis';
+import { Vis } from '../../../../ui/public/visualize/loader/vis';
import { Visualization } from '../../../../ui/public/visualize/components';
export const visualization = () => ({
@@ -33,8 +33,6 @@ export const visualization = () => ({
const visType = config.visType || visConfig.type;
const $injector = await chrome.dangerouslyGetActiveInjector();
const $rootScope = $injector.get('$rootScope') as any;
- const Private = $injector.get('Private') as any;
- const Vis = Private(VisProvider);
if (handlers.vis) {
// special case in visualize, we need to render first (without executing the expression), for maps to work
diff --git a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.tsx b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.tsx
index c7ada18f9e1f2..2ca4ed1e2343d 100644
--- a/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.tsx
+++ b/src/legacy/core_plugins/kbn_vislib_vis_types/public/components/options/metrics_axes/index.tsx
@@ -83,9 +83,11 @@ function MetricsAxisOptions(props: ValidationVisOptionsProps)
// stores previous aggs' custom labels
const [lastCustomLabels, setLastCustomLabels] = useState({} as { [key: string]: string });
// stores previous aggs' field and type
- const [lastSeriesAgg, setLastSeriesAgg] = useState({} as {
- [key: string]: { type: string; field: string };
- });
+ const [lastSeriesAgg, setLastSeriesAgg] = useState(
+ {} as {
+ [key: string]: { type: string; field: string };
+ }
+ );
const updateAxisTitle = () => {
const axes = cloneDeep(stateParams.valueAxes);
diff --git a/src/legacy/core_plugins/kibana/index.js b/src/legacy/core_plugins/kibana/index.js
index 24cd436912395..c7cda8aec0165 100644
--- a/src/legacy/core_plugins/kibana/index.js
+++ b/src/legacy/core_plugins/kibana/index.js
@@ -62,7 +62,7 @@ export default function (kibana) {
uiExports: {
hacks: [
- 'plugins/kibana/dev_tools/hacks/hide_empty_tools',
+ 'plugins/kibana/dev_tools',
],
fieldFormats: ['plugins/kibana/field_formats/register'],
savedObjectTypes: [
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.tsx
index 5fa3a938ed9df..656b54040ad99 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.tsx
+++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app.tsx
@@ -26,19 +26,16 @@ import { IInjector } from 'ui/chrome';
// @ts-ignore
import * as filterActions from 'plugins/kibana/discover/doc_table/actions/filter';
-// @ts-ignore
-import { getFilterGenerator } from 'ui/filter_manager';
-
import {
AppStateClass as TAppStateClass,
AppState as TAppState,
} from 'ui/state_management/app_state';
import { KbnUrl } from 'ui/url/kbn_url';
-import { TimeRange } from 'src/plugins/data/public';
+import { TimeRange, Query } from 'src/plugins/data/public';
import { IndexPattern } from 'ui/index_patterns';
import { IPrivate } from 'ui/private';
-import { StaticIndexPattern, Query, SavedQuery } from 'plugins/data';
+import { StaticIndexPattern, SavedQuery } from 'plugins/data';
import moment from 'moment';
import { Subscription } from 'rxjs';
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx
index 548a66297a3f9..d82b89339b0d0 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx
+++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_app_controller.tsx
@@ -50,12 +50,13 @@ import {
import { KbnUrl } from 'ui/url/kbn_url';
import { IndexPattern } from 'ui/index_patterns';
import { IPrivate } from 'ui/private';
-import { Query, SavedQuery } from 'src/legacy/core_plugins/data/public';
+import { SavedQuery } from 'src/legacy/core_plugins/data/public';
import { SaveOptions } from 'ui/saved_objects/saved_object';
import { capabilities } from 'ui/capabilities';
import { Subscription } from 'rxjs';
import { npStart } from 'ui/new_platform';
import { SavedObjectFinder } from 'ui/saved_objects/components/saved_object_finder';
+import { Query } from '../../../../../plugins/data/public';
import { start as data } from '../../../data/public/legacy';
import {
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.ts b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.ts
index 8ffabe5add1c3..1a42ed837a9de 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.ts
+++ b/src/legacy/core_plugins/kibana/public/dashboard/dashboard_state_manager.ts
@@ -27,9 +27,9 @@ import { migrateLegacyQuery } from 'ui/utils/migrate_legacy_query';
import { Moment } from 'moment';
import { DashboardContainer } from 'src/legacy/core_plugins/dashboard_embeddable_container/public/np_ready/public';
+import { Query } from 'src/plugins/data/public';
import { ViewMode } from '../../../../../../src/plugins/embeddable/public';
import { esFilters } from '../../../../../../src/plugins/data/public';
-import { Query } from '../../../data/public';
import { getAppStateDefaults, migrateAppState } from './lib';
import { convertPanelStateToSavedDashboardPanel } from './lib/embeddable_saved_object_converters';
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/migrations/move_filters_to_query.ts b/src/legacy/core_plugins/kibana/public/dashboard/migrations/move_filters_to_query.ts
index 8522495b9dedb..e82fc58670e39 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/migrations/move_filters_to_query.ts
+++ b/src/legacy/core_plugins/kibana/public/dashboard/migrations/move_filters_to_query.ts
@@ -17,8 +17,7 @@
* under the License.
*/
-import { Query } from 'src/legacy/core_plugins/data/public';
-import { esFilters } from '../../../../../../plugins/data/public';
+import { esFilters, Query } from '../../../../../../plugins/data/public';
export interface Pre600FilterQuery {
// pre 6.0.0 global query:queryString:options were stored per dashboard and would
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.d.ts b/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.d.ts
index 5b860b0a2cc7c..5b24aa13f4f77 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.d.ts
+++ b/src/legacy/core_plugins/kibana/public/dashboard/saved_dashboard/saved_dashboard.d.ts
@@ -19,9 +19,7 @@
import { SearchSource } from 'ui/courier';
import { SavedObject } from 'ui/saved_objects/saved_object';
-import { RefreshInterval } from 'src/plugins/data/public';
-import { Query } from 'src/legacy/core_plugins/data/public';
-import { esFilters } from '../../../../../../plugins/data/public';
+import { esFilters, Query, RefreshInterval } from '../../../../../../plugins/data/public';
export interface SavedObjectDashboard extends SavedObject {
id?: string;
diff --git a/src/legacy/core_plugins/kibana/public/dashboard/types.ts b/src/legacy/core_plugins/kibana/public/dashboard/types.ts
index 5aaca7b62094f..3c2c87a502da4 100644
--- a/src/legacy/core_plugins/kibana/public/dashboard/types.ts
+++ b/src/legacy/core_plugins/kibana/public/dashboard/types.ts
@@ -18,7 +18,6 @@
*/
import { AppState } from 'ui/state_management/app_state';
-import { Query } from 'src/legacy/core_plugins/data/public';
import { AppState as TAppState } from 'ui/state_management/app_state';
import { ViewMode } from 'src/plugins/embeddable/public';
import {
@@ -29,7 +28,7 @@ import {
RawSavedDashboardPanel640To720,
RawSavedDashboardPanel730ToLatest,
} from './migrations/types';
-import { esFilters } from '../../../../../plugins/data/public';
+import { Query, esFilters } from '../../../../../plugins/data/public';
export type NavAction = (anchorElement?: any) => void;
diff --git a/src/legacy/core_plugins/kibana/public/dev_tools/_index.scss b/src/legacy/core_plugins/kibana/public/dev_tools/_index.scss
index 563b140fd2ead..2e88d2e1285e3 100644
--- a/src/legacy/core_plugins/kibana/public/dev_tools/_index.scss
+++ b/src/legacy/core_plugins/kibana/public/dev_tools/_index.scss
@@ -16,3 +16,6 @@
}
}
+.devApp {
+ height: 100%;
+}
diff --git a/src/legacy/core_plugins/kibana/public/dev_tools/application.tsx b/src/legacy/core_plugins/kibana/public/dev_tools/application.tsx
new file mode 100644
index 0000000000000..3945d8d8dc856
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/dev_tools/application.tsx
@@ -0,0 +1,184 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { I18nProvider } from '@kbn/i18n/react';
+import { i18n } from '@kbn/i18n';
+import { EuiTab, EuiTabs, EuiToolTip } from '@elastic/eui';
+import { HashRouter as Router, Switch, Route, Redirect } from 'react-router-dom';
+import * as React from 'react';
+import ReactDOM from 'react-dom';
+import { useEffect, useRef } from 'react';
+
+import { AppMountContext } from 'kibana/public';
+import { DevTool } from '../../../../../plugins/dev_tools/public';
+
+interface DevToolsWrapperProps {
+ devTools: readonly DevTool[];
+ activeDevTool: DevTool;
+ appMountContext: AppMountContext;
+ updateRoute: (newRoute: string) => void;
+}
+
+interface MountedDevToolDescriptor {
+ devTool: DevTool;
+ mountpoint: HTMLElement;
+ unmountHandler: () => void;
+}
+
+function DevToolsWrapper({
+ devTools,
+ activeDevTool,
+ appMountContext,
+ updateRoute,
+}: DevToolsWrapperProps) {
+ const mountedTool = useRef(null);
+
+ useEffect(
+ () => () => {
+ if (mountedTool.current) {
+ mountedTool.current.unmountHandler();
+ }
+ },
+ []
+ );
+
+ return (
+
+
+ {devTools.map(currentDevTool => (
+
+ {
+ if (!currentDevTool.disabled) {
+ updateRoute(`/dev_tools/${currentDevTool.id}`);
+ }
+ }}
+ >
+ {currentDevTool.title}
+
+
+ ))}
+
+ {
+ if (
+ element &&
+ (mountedTool.current === null ||
+ mountedTool.current.devTool !== activeDevTool ||
+ mountedTool.current.mountpoint !== element)
+ ) {
+ if (mountedTool.current) {
+ mountedTool.current.unmountHandler();
+ }
+ const unmountHandler = await activeDevTool.mount(appMountContext, {
+ element,
+ appBasePath: '',
+ });
+ mountedTool.current = {
+ devTool: activeDevTool,
+ mountpoint: element,
+ unmountHandler,
+ };
+ }
+ }}
+ />
+
+ );
+}
+
+function redirectOnMissingCapabilities(appMountContext: AppMountContext) {
+ if (!appMountContext.core.application.capabilities.dev_tools.show) {
+ window.location.hash = '/home';
+ return true;
+ }
+ return false;
+}
+
+function setBadge(appMountContext: AppMountContext) {
+ if (appMountContext.core.application.capabilities.dev_tools.save) {
+ return;
+ }
+ appMountContext.core.chrome.setBadge({
+ text: i18n.translate('kbn.devTools.badge.readOnly.text', {
+ defaultMessage: 'Read only',
+ }),
+ tooltip: i18n.translate('kbn.devTools.badge.readOnly.tooltip', {
+ defaultMessage: 'Unable to save',
+ }),
+ iconType: 'glasses',
+ });
+}
+
+function setBreadcrumbs(appMountContext: AppMountContext) {
+ appMountContext.core.chrome.setBreadcrumbs([
+ {
+ text: i18n.translate('kbn.devTools.k7BreadcrumbsDevToolsLabel', {
+ defaultMessage: 'Dev Tools',
+ }),
+ href: '#/dev_tools',
+ },
+ ]);
+}
+
+export function renderApp(
+ element: HTMLElement,
+ appMountContext: AppMountContext,
+ basePath: string,
+ devTools: readonly DevTool[]
+) {
+ if (redirectOnMissingCapabilities(appMountContext)) {
+ return () => {};
+ }
+ setBadge(appMountContext);
+ setBreadcrumbs(appMountContext);
+ ReactDOM.render(
+
+
+
+ {devTools.map(devTool => (
+ (
+
+ )}
+ />
+ ))}
+
+
+
+
+
+ ,
+ element
+ );
+
+ return () => ReactDOM.unmountComponentAtNode(element);
+}
diff --git a/src/legacy/core_plugins/kibana/public/dev_tools/hacks/__tests__/hide_empty_tools.js b/src/legacy/core_plugins/kibana/public/dev_tools/hacks/__tests__/hide_empty_tools.js
deleted file mode 100644
index 25c7b945b9dfb..0000000000000
--- a/src/legacy/core_plugins/kibana/public/dev_tools/hacks/__tests__/hide_empty_tools.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import expect from '@kbn/expect';
-import sinon from 'sinon';
-
-import { hideEmptyDevTools } from '../hide_empty_tools';
-import { npStart } from 'ui/new_platform';
-
-describe('hide dev tools', function () {
- let updateNavLink;
-
- function PrivateWithoutTools() {
- return [];
- }
-
- function PrivateWithTools() {
- return ['tool1', 'tool2'];
- }
-
- function isHidden() {
- return updateNavLink.calledWith('kibana:dev_tools', { hidden: true });
- }
-
- beforeEach(function () {
- const coreNavLinks = npStart.core.chrome.navLinks;
- updateNavLink = sinon.spy(coreNavLinks, 'update');
- });
-
- it('should hide the app if there are no dev tools', function () {
- hideEmptyDevTools(PrivateWithTools);
- expect(isHidden()).to.be(false);
- });
-
- it('should not hide the app if there are tools', function () {
- hideEmptyDevTools(PrivateWithoutTools);
- expect(isHidden()).to.be(true);
- });
-
- afterEach(function () {
- updateNavLink.restore();
- });
-});
diff --git a/src/legacy/core_plugins/kibana/public/dev_tools/index.js b/src/legacy/core_plugins/kibana/public/dev_tools/index.js
deleted file mode 100644
index e36e75f6837ab..0000000000000
--- a/src/legacy/core_plugins/kibana/public/dev_tools/index.js
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import uiRoutes from 'ui/routes';
-import { i18n } from '@kbn/i18n';
-import { DevToolsRegistryProvider } from 'ui/registry/dev_tools';
-import { FeatureCatalogueRegistryProvider, FeatureCatalogueCategory } from 'ui/registry/feature_catalogue';
-import 'ui/directives/kbn_href';
-import './directives/dev_tools_app';
-
-uiRoutes
- .when('/dev_tools', {
- resolve: {
- redirect(Private, kbnUrl) {
- const items = Private(DevToolsRegistryProvider).inOrder;
- kbnUrl.redirect(items[0].url.substring(1));
- }
- }
- });
-
-uiRoutes.defaults(/^\/dev_tools(\/|$)/, {
- badge: uiCapabilities => {
- if (uiCapabilities.dev_tools.save) {
- return undefined;
- }
-
- return {
- text: i18n.translate('kbn.devTools.badge.readOnly.text', {
- defaultMessage: 'Read only',
- }),
- tooltip: i18n.translate('kbn.devTools.badge.readOnly.tooltip', {
- defaultMessage: 'Unable to save',
- }),
- iconType: 'glasses'
- };
- },
- k7Breadcrumbs: () => [
- {
- text: i18n.translate('kbn.devTools.k7BreadcrumbsDevToolsLabel', {
- defaultMessage: 'Dev Tools'
- }),
- href: '#/dev_tools'
- }
- ]
-});
-
-FeatureCatalogueRegistryProvider.register(() => {
- return {
- id: 'console',
- title: i18n.translate('kbn.devTools.consoleTitle', {
- defaultMessage: 'Console'
- }),
- description: i18n.translate('kbn.devTools.consoleDescription', {
- defaultMessage: 'Skip cURL and use this JSON interface to work with your data directly.'
- }),
- icon: 'consoleApp',
- path: '/app/kibana#/dev_tools/console',
- showOnHomePage: true,
- category: FeatureCatalogueCategory.ADMIN
- };
-});
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_stats.ts b/src/legacy/core_plugins/kibana/public/dev_tools/index.ts
similarity index 68%
rename from src/legacy/core_plugins/telemetry/server/telemetry_collection/get_stats.ts
rename to src/legacy/core_plugins/kibana/public/dev_tools/index.ts
index b739b20545678..74708e36a98aa 100644
--- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_stats.ts
+++ b/src/legacy/core_plugins/kibana/public/dev_tools/index.ts
@@ -17,12 +17,18 @@
* under the License.
*/
-// @ts-ignore
-import { getLocalStats } from './get_local_stats';
-import { StatsGetter, getStatsCollectionConfig } from '../collection_manager';
+import { npSetup, npStart } from 'ui/new_platform';
-export const getStats: StatsGetter = async function(config) {
- const { callCluster, server } = getStatsCollectionConfig(config, 'data');
+import { DevToolsPlugin } from './plugin';
+import { localApplicationService } from '../local_application_service';
- return [await getLocalStats({ callCluster, server })];
-};
+const instance = new DevToolsPlugin();
+
+instance.setup(npSetup.core, {
+ __LEGACY: {
+ localApplicationService,
+ },
+});
+instance.start(npStart.core, {
+ newPlatformDevTools: npStart.plugins.devTools,
+});
diff --git a/src/legacy/core_plugins/kibana/public/dev_tools/partials/dev_tools_app.html b/src/legacy/core_plugins/kibana/public/dev_tools/partials/dev_tools_app.html
deleted file mode 100644
index 6c076092c76d5..0000000000000
--- a/src/legacy/core_plugins/kibana/public/dev_tools/partials/dev_tools_app.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
-
-
diff --git a/src/legacy/core_plugins/kibana/public/dev_tools/plugin.ts b/src/legacy/core_plugins/kibana/public/dev_tools/plugin.ts
new file mode 100644
index 0000000000000..ec9af1a6acd92
--- /dev/null
+++ b/src/legacy/core_plugins/kibana/public/dev_tools/plugin.ts
@@ -0,0 +1,71 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// This import makes sure dev tools are registered before the app is.
+import 'uiExports/devTools';
+
+import { CoreSetup, CoreStart, Plugin } from 'kibana/public';
+
+import { LocalApplicationService } from '../local_application_service';
+import { DevTool, DevToolsStart } from '../../../../../plugins/dev_tools/public';
+
+export interface DevToolsPluginSetupDependencies {
+ __LEGACY: {
+ localApplicationService: LocalApplicationService;
+ };
+}
+
+export interface DevToolsPluginStartDependencies {
+ newPlatformDevTools: DevToolsStart;
+}
+
+export class DevToolsPlugin implements Plugin {
+ private getSortedDevTools: (() => readonly DevTool[]) | null = null;
+
+ public setup(
+ core: CoreSetup,
+ { __LEGACY: { localApplicationService } }: DevToolsPluginSetupDependencies
+ ) {
+ localApplicationService.register({
+ id: 'dev_tools',
+ title: 'Dev Tools',
+ mount: async (appMountContext, params) => {
+ if (!this.getSortedDevTools) {
+ throw new Error('not started yet');
+ }
+ const { renderApp } = await import('./application');
+ return renderApp(
+ params.element,
+ appMountContext,
+ params.appBasePath,
+ this.getSortedDevTools()
+ );
+ },
+ });
+ }
+
+ public start(core: CoreStart, { newPlatformDevTools }: DevToolsPluginStartDependencies) {
+ this.getSortedDevTools = newPlatformDevTools.getSortedDevTools;
+ if (this.getSortedDevTools().length === 0) {
+ core.chrome.navLinks.update('kibana:dev_tools', {
+ hidden: true,
+ });
+ }
+ }
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/_stubs.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/_stubs.js
index f472ff9250eb5..b3d37083b37f7 100644
--- a/src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/_stubs.js
+++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/api/__tests__/_stubs.js
@@ -26,7 +26,8 @@ export function createIndexPatternsStub() {
get: sinon.spy(indexPatternId =>
Promise.resolve({
id: indexPatternId,
- isTimeNanosBased: () => false
+ isTimeNanosBased: () => false,
+ popularizeField: () => {},
})
),
};
diff --git a/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_add_filter.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_add_filter.js
index b136b03bd500b..5a445a65939ed 100644
--- a/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_add_filter.js
+++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/__tests__/action_add_filter.js
@@ -19,32 +19,33 @@
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
-import sinon from 'sinon';
import { getServices } from '../../../../kibana_services';
import { createStateStub } from './_utils';
import { QueryParameterActionsProvider } from '../actions';
-
+import { createIndexPatternsStub } from '../../api/__tests__/_stubs';
+import { npStart } from 'ui/new_platform';
describe('context app', function () {
beforeEach(ngMock.module('kibana'));
+ beforeEach(ngMock.module(function createServiceStubs($provide) {
+ $provide.value('indexPatterns', createIndexPatternsStub());
+ }));
+
describe('action addFilter', function () {
- let filterManagerStub;
let addFilter;
beforeEach(ngMock.inject(function createPrivateStubs(Private) {
- filterManagerStub = createQueryFilterStub();
- Private.stub(getServices().FilterBarQueryFilterProvider, filterManagerStub);
-
+ Private.stub(getServices().FilterBarQueryFilterProvider);
addFilter = Private(QueryParameterActionsProvider).addFilter;
}));
it('should pass the given arguments to the filterManager', function () {
const state = createStateStub();
+ const filterManagerAddStub = npStart.plugins.data.query.filterManager.addFilters;
addFilter(state)('FIELD_NAME', 'FIELD_VALUE', 'FILTER_OPERATION');
- const filterManagerAddStub = filterManagerStub.addFilters;
//get the generated filter
const generatedFilter = filterManagerAddStub.firstCall.args[0][0];
const queryKeys = Object.keys(generatedFilter.query.match_phrase);
@@ -55,20 +56,12 @@ describe('context app', function () {
it('should pass the index pattern id to the filterManager', function () {
const state = createStateStub();
+ const filterManagerAddStub = npStart.plugins.data.query.filterManager.addFilters;
addFilter(state)('FIELD_NAME', 'FIELD_VALUE', 'FILTER_OPERATION');
- const filterManagerAddStub = filterManagerStub.addFilters;
const generatedFilter = filterManagerAddStub.firstCall.args[0][0];
- expect(filterManagerAddStub.calledOnce).to.be(true);
expect(generatedFilter.meta.index).to.eql('INDEX_PATTERN_ID');
});
});
});
-
-function createQueryFilterStub() {
- return {
- addFilters: sinon.stub(),
- getAppFilters: sinon.stub(),
- };
-}
diff --git a/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/actions.js b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/actions.js
index 9f7b180e8fe7d..10fe6c0e2eda1 100644
--- a/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/actions.js
+++ b/src/legacy/core_plugins/kibana/public/discover/angular/context/query_parameters/actions.js
@@ -18,7 +18,8 @@
*/
import _ from 'lodash';
-import { getServices, getFilterGenerator } from '../../../kibana_services';
+import { generateFilters } from '../../../../../../../../plugins/data/public';
+import { npStart } from 'ui/new_platform';
import {
MAX_CONTEXT_SIZE,
@@ -27,9 +28,8 @@ import {
} from './constants';
-export function QueryParameterActionsProvider(indexPatterns, Private) {
- const queryFilter = Private(getServices().FilterBarQueryFilterProvider);
- const filterGen = getFilterGenerator(queryFilter);
+export function QueryParameterActionsProvider(indexPatterns) {
+ const { filterManager } = npStart.plugins.data.query;
const setPredecessorCount = (state) => (predecessorCount) => (
state.queryParameters.predecessorCount = clamp(
@@ -55,13 +55,13 @@ export function QueryParameterActionsProvider(indexPatterns, Private) {
);
const updateFilters = () => filters => {
- queryFilter.setFilters(filters);
+ filterManager.setFilters(filters);
};
const addFilter = (state) => async (field, values, operation) => {
const indexPatternId = state.queryParameters.indexPatternId;
- const newFilters = filterGen.generate(field, values, operation, indexPatternId);
- queryFilter.addFilters(newFilters);
+ const newFilters = generateFilters(filterManager, field, values, operation, indexPatternId);
+ filterManager.addFilters(newFilters);
const indexPattern = await indexPatterns.get(indexPatternId);
indexPattern.popularizeField(field.name, 1);
};
diff --git a/src/legacy/core_plugins/kibana/public/discover/angular/discover.js b/src/legacy/core_plugins/kibana/public/discover/angular/discover.js
index ed5049aa912e0..8ee23bfb005a2 100644
--- a/src/legacy/core_plugins/kibana/public/discover/angular/discover.js
+++ b/src/legacy/core_plugins/kibana/public/discover/angular/discover.js
@@ -31,7 +31,6 @@ import './doc_table';
import { getSort } from './doc_table/lib/get_sort';
import { getSortForSearchSource } from './doc_table/lib/get_sort_for_search_source';
import * as columnActions from './doc_table/actions/columns';
-import * as filterActions from './doc_table/actions/filter';
import indexTemplate from './discover.html';
import { showOpenSearchPanel } from '../top_nav/show_open_search_panel';
@@ -41,7 +40,6 @@ import { getPainlessError } from './get_painless_error';
import {
angular,
buildVislibDimensions,
- getFilterGenerator,
getRequestInspectorStats,
getResponseInspectorStats,
getServices,
@@ -57,7 +55,7 @@ import {
subscribeWithScope,
tabifyAggResponse,
vislibSeriesResponseHandlerProvider,
- VisProvider,
+ Vis,
SavedObjectSaveModal,
} from '../kibana_services';
@@ -76,7 +74,7 @@ const {
import { getRootBreadcrumbs, getSavedSearchBreadcrumbs } from '../breadcrumbs';
import { extractTimeFilter, changeTimeFilter } from '../../../../data/public';
import { start as data } from '../../../../data/public/legacy';
-
+import { generateFilters } from '../../../../../../plugins/data/public';
const { savedQueryService } = data.search.services;
@@ -190,13 +188,11 @@ function discoverController(
localStorage,
uiCapabilities
) {
- const Vis = Private(VisProvider);
const responseHandler = vislibSeriesResponseHandlerProvider().handler;
const getUnhashableStates = Private(getUnhashableStatesProvider);
const shareContextMenuExtensions = Private(ShareContextMenuExtensionsRegistryProvider);
const queryFilter = Private(FilterBarQueryFilterProvider);
- const filterGen = getFilterGenerator(queryFilter);
const inspectorAdapters = {
requests: new RequestAdapter()
@@ -901,7 +897,8 @@ function discoverController(
// TODO: On array fields, negating does not negate the combination, rather all terms
$scope.filterQuery = function (field, values, operation) {
$scope.indexPattern.popularizeField(field, 1);
- filterActions.addFilter(field, values, operation, $scope.indexPattern.id, $scope.state, filterGen);
+ const newFilters = generateFilters(queryFilter, field, values, operation, $scope.indexPattern.id);
+ return queryFilter.addFilters(newFilters);
};
$scope.addColumn = function addColumn(columnName) {
diff --git a/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/__tests__/actions/filter.js b/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/__tests__/actions/filter.js
deleted file mode 100644
index 1f5db791469b9..0000000000000
--- a/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/__tests__/actions/filter.js
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import { addFilter } from '../../actions/filter';
-import StubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
-import NoDigestPromises from 'test_utils/no_digest_promises';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import sinon from 'sinon';
-
-function getFilterGeneratorStub() {
- return {
- add: sinon.stub()
- };
-}
-
-describe('doc table filter actions', function () {
- NoDigestPromises.activateForSuite();
-
- let filterGen;
- let indexPattern;
-
- beforeEach(ngMock.module(
- 'kibana',
- function ($provide) {
- $provide.service('indexPatterns', require('fixtures/mock_index_patterns'));
- }
- ));
-
- beforeEach(ngMock.inject(function (Private) {
- indexPattern = Private(StubbedLogstashIndexPatternProvider);
- filterGen = getFilterGeneratorStub();
- }));
-
- describe('add', function () {
-
- it('should defer to the FilterManager when dealing with a lucene query', function () {
- const state = {
- query: { query: 'foo', language: 'lucene' }
- };
- const args = ['foo', ['bar'], '+', indexPattern, ];
- addFilter('foo', ['bar'], '+', indexPattern, state, filterGen);
- expect(filterGen.add.calledOnce).to.be(true);
- expect(filterGen.add.calledWith(...args)).to.be(true);
- });
-
- });
-
-
-});
diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.test.tsx b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.test.tsx
index badfbb4b14a4c..5054f7b4bdad1 100644
--- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.test.tsx
+++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.test.tsx
@@ -121,7 +121,7 @@ describe('DiscoverFieldSearch', () => {
// @ts-ignore
(aggregtableButtonGroup.props() as EuiButtonGroupProps).onChange('aggregatable-true', null);
});
- missingSwitch.simulate('change', { target: { value: false } });
+ missingSwitch.simulate('click');
expect(onChange).toBeCalledTimes(2);
});
diff --git a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.tsx b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.tsx
index 3d93487d9e6cc..d5f6b63d12199 100644
--- a/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.tsx
+++ b/src/legacy/core_plugins/kibana/public/discover/components/field_chooser/discover_field_search.tsx
@@ -29,6 +29,7 @@ import {
EuiPopoverTitle,
EuiSelect,
EuiSwitch,
+ EuiSwitchEvent,
EuiForm,
EuiFormRow,
EuiButtonGroup,
@@ -154,7 +155,7 @@ export function DiscoverFieldSearch({ onChange, value, types }: Props) {
setActiveFiltersCount(activeFiltersCount + diff);
};
- const handleMissingChange = (e: React.ChangeEvent
) => {
+ const handleMissingChange = (e: EuiSwitchEvent) => {
const missingValue = e.target.checked;
handleValueChange('missing', missingValue);
};
diff --git a/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable.ts b/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable.ts
index 732fb6d2e4e70..c575465a377e2 100644
--- a/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/embeddable/search_embeddable.ts
@@ -25,10 +25,12 @@ import { npStart } from 'ui/new_platform';
import {
esFilters,
TimeRange,
+ FilterManager,
onlyDisabledFiltersChanged,
+ generateFilters,
getTime,
+ Query,
} from '../../../../../../plugins/data/public';
-import { Query } from '../../../../data/public';
import {
APPLY_FILTER_TRIGGER,
Container,
@@ -43,7 +45,6 @@ import { getSortForSearchSource } from '../angular/doc_table/lib/get_sort_for_se
import {
Adapters,
angular,
- getFilterGenerator,
getRequestInspectorStats,
getResponseInspectorStats,
getServices,
@@ -72,18 +73,6 @@ interface SearchScope extends ng.IScope {
isLoading?: boolean;
}
-export interface FilterManager {
- generate: (
- field: {
- name: string;
- scripted: boolean;
- },
- values: string | string[],
- operation: string,
- index: number
- ) => esFilters.Filter[];
-}
-
interface SearchEmbeddableConfig {
$rootScope: ng.IRootScopeService;
$compile: ng.ICompileService;
@@ -107,7 +96,7 @@ export class SearchEmbeddable extends Embeddable
private autoRefreshFetchSubscription?: Subscription;
private subscription?: Subscription;
public readonly type = SEARCH_EMBEDDABLE_TYPE;
- private filterGen: FilterManager;
+ private filterManager: FilterManager;
private abortController?: AbortController;
private prevTimeRange?: TimeRange;
@@ -134,7 +123,7 @@ export class SearchEmbeddable extends Embeddable
parent
);
- this.filterGen = getFilterGenerator(queryFilter);
+ this.filterManager = queryFilter as FilterManager;
this.savedSearch = savedSearch;
this.$rootScope = $rootScope;
this.$compile = $compile;
@@ -251,7 +240,7 @@ export class SearchEmbeddable extends Embeddable
};
searchScope.filter = async (field, value, operator) => {
- let filters = this.filterGen.generate(field, value, operator, indexPattern.id);
+ let filters = generateFilters(this.filterManager, field, value, operator, indexPattern.id);
filters = filters.map(filter => ({
...filter,
$state: { store: esFilters.FilterStateStore.APP_STATE },
diff --git a/src/legacy/core_plugins/kibana/public/discover/embeddable/types.ts b/src/legacy/core_plugins/kibana/public/discover/embeddable/types.ts
index 5473ec0e7b8b4..2d940ad8cba98 100644
--- a/src/legacy/core_plugins/kibana/public/discover/embeddable/types.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/embeddable/types.ts
@@ -17,13 +17,11 @@
* under the License.
*/
-import { TimeRange } from 'src/plugins/data/public';
-import { Query } from 'src/legacy/core_plugins/data/public';
import { EmbeddableInput, EmbeddableOutput, IEmbeddable } from 'src/plugins/embeddable/public';
import { StaticIndexPattern } from '../kibana_services';
import { SavedSearch } from '../types';
import { SortOrder } from '../angular/doc_table/components/table_header/helpers';
-import { esFilters } from '../../../../../../plugins/data/public';
+import { esFilters, TimeRange, Query } from '../../../../../../plugins/data/public';
export interface SearchInput extends EmbeddableInput {
timeRange: TimeRange;
diff --git a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts
index b78d05e68acad..d0eb115e32676 100644
--- a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts
+++ b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts
@@ -84,8 +84,6 @@ export { angular };
export { buildVislibDimensions } from 'ui/visualize/loader/pipeline_helpers/build_pipeline';
// @ts-ignore
export { callAfterBindingsWorkaround } from 'ui/compat';
-// @ts-ignore
-export { getFilterGenerator } from 'ui/filter_manager';
export {
getRequestInspectorStats,
getResponseInspectorStats,
@@ -114,7 +112,7 @@ export { tabifyAggResponse } from 'ui/agg_response/tabify';
export { vislibSeriesResponseHandlerProvider } from 'ui/vis/response_handlers/vislib';
// EXPORT types
-export { VisProvider } from 'ui/vis';
+export { Vis } from 'ui/vis';
export { StaticIndexPattern, IndexPatterns, IndexPattern, FieldType } from 'ui/index_patterns';
export { SearchSource } from 'ui/courier';
export { ElasticSearchHit } from 'ui/registry/doc_views_types';
diff --git a/src/legacy/core_plugins/kibana/public/kibana.js b/src/legacy/core_plugins/kibana/public/kibana.js
index fe741a357cbfe..c5b9d86b57aae 100644
--- a/src/legacy/core_plugins/kibana/public/kibana.js
+++ b/src/legacy/core_plugins/kibana/public/kibana.js
@@ -37,7 +37,6 @@ import 'uiExports/navbarExtensions';
import 'uiExports/contextMenuActions';
import 'uiExports/managementSections';
import 'uiExports/indexManagement';
-import 'uiExports/devTools';
import 'uiExports/docViews';
import 'uiExports/embeddableFactories';
import 'uiExports/embeddableActions';
diff --git a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/extract_export_details.test.ts b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/extract_export_details.test.ts
index a6ed2e36839f4..4ecc3583e76ce 100644
--- a/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/extract_export_details.test.ts
+++ b/src/legacy/core_plugins/kibana/public/management/sections/objects/lib/__jest__/extract_export_details.test.ts
@@ -62,7 +62,10 @@ describe('extractExportDetails', () => {
[
[
objLine('1', 'index-pattern'),
- detailsLine(1, [{ id: '2', type: 'index-pattern' }, { id: '3', type: 'index-pattern' }]),
+ detailsLine(1, [
+ { id: '2', type: 'index-pattern' },
+ { id: '3', type: 'index-pattern' },
+ ]),
].join(''),
],
{
@@ -75,7 +78,10 @@ describe('extractExportDetails', () => {
expect(result).toEqual({
exportedCount: 1,
missingRefCount: 2,
- missingReferences: [{ id: '2', type: 'index-pattern' }, { id: '3', type: 'index-pattern' }],
+ missingReferences: [
+ { id: '2', type: 'index-pattern' },
+ { id: '3', type: 'index-pattern' },
+ ],
});
});
diff --git a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts
index 60cf7c7ec1928..0b75c6ffa1ffb 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts
+++ b/src/legacy/core_plugins/kibana/public/visualize/embeddable/visualize_embeddable.ts
@@ -33,11 +33,12 @@ import { npStart } from 'ui/new_platform';
import { IExpressionLoaderParams } from '../../../../expressions/public/np_ready/public/types';
import { start as expressions } from '../../../../expressions/public/legacy';
import { VISUALIZE_EMBEDDABLE_TYPE } from './constants';
-import { Query } from '../../../../data/public';
import {
TimeRange,
+ Query,
onlyDisabledFiltersChanged,
esFilters,
+ mapAndFlattenFilters,
} from '../../../../../../plugins/data/public';
import {
EmbeddableInput,
@@ -47,7 +48,6 @@ import {
APPLY_FILTER_TRIGGER,
} from '../../../../../../plugins/embeddable/public';
import { dispatchRenderComplete } from '../../../../../../plugins/kibana_utils/public';
-import { mapAndFlattenFilters } from '../../../../../../plugins/data/public';
const getKeys = (o: T): Array => Object.keys(o) as Array;
diff --git a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.js b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.js
index f8adaed0bf584..aec80b8d13551 100644
--- a/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.js
+++ b/src/legacy/core_plugins/kibana/public/visualize/saved_visualizations/_saved_vis.js
@@ -25,7 +25,7 @@
* NOTE: It's a type of SavedObject, but specific to visualizations.
*/
-import { VisProvider } from 'ui/vis';
+import { Vis } from 'ui/vis';
import { uiModules } from 'ui/modules';
import { updateOldState } from 'ui/vis/vis_update_state';
import { VisualizeConstants } from '../visualize_constants';
@@ -39,7 +39,6 @@ import {
uiModules
.get('app/visualize')
.factory('SavedVis', function (Promise, savedSearches, Private) {
- const Vis = Private(VisProvider);
const SavedObject = Private(SavedObjectProvider);
createLegacyClass(SavedVis).inherits(SavedObject);
function SavedVis(opts) {
diff --git a/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx b/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx
index d4d1c159906aa..4d3b72bae6411 100644
--- a/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx
+++ b/src/legacy/core_plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx
@@ -45,6 +45,7 @@ export function TopNavMenuItem(props: TopNavMenuData) {
isDisabled={isDisabled()}
onClick={handleClick}
data-test-subj={props.testId}
+ className={props.className}
>
{capitalize(props.label || props.id!)}
diff --git a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js
index 9bfa413257967..b57fbd637f0b7 100644
--- a/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js
+++ b/src/legacy/core_plugins/region_map/public/__tests__/region_map_visualization.js
@@ -22,7 +22,7 @@ import ngMock from 'ng_mock';
import _ from 'lodash';
import ChoroplethLayer from '../choropleth_layer';
import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern';
-import * as visModule from 'ui/vis';
+import { Vis } from 'ui/vis';
import { ImageComparator } from 'test_utils/image_comparator';
import worldJson from './world.json';
import EMS_CATALOGUE from '../../../../ui/public/vis/__tests__/map/ems_mocks/sample_manifest.json';
@@ -50,7 +50,6 @@ const PIXEL_DIFF = 96;
describe('RegionMapsVisualizationTests', function () {
let domNode;
let RegionMapsVisualization;
- let Vis;
let indexPattern;
let vis;
let dependencies;
@@ -113,7 +112,6 @@ describe('RegionMapsVisualizationTests', function () {
visualizationsSetup.types.registerVisualization(() => createRegionMapTypeDefinition(dependencies));
}
- Vis = Private(visModule.VisProvider);
RegionMapsVisualization = createRegionMapVisualization(dependencies);
indexPattern = Private(LogstashIndexPatternStubProvider);
diff --git a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx
index 9749c7fa8e2f9..8306b3274a914 100644
--- a/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx
+++ b/src/legacy/core_plugins/region_map/public/components/region_map_options.tsx
@@ -82,7 +82,10 @@ function RegionMapOptions(props: RegionMapOptionsProps) {
const setField = useCallback(
(paramName: 'selectedJoinField', value: FileLayerField['name']) => {
if (stateParams.selectedLayer) {
- setValue(paramName, stateParams.selectedLayer.fields.find(f => f.name === value));
+ setValue(
+ paramName,
+ stateParams.selectedLayer.fields.find(f => f.name === value)
+ );
}
},
[setValue, stateParams.selectedLayer]
diff --git a/src/legacy/core_plugins/telemetry/index.ts b/src/legacy/core_plugins/telemetry/index.ts
index 149fa99938563..9993f2dbf0b86 100644
--- a/src/legacy/core_plugins/telemetry/index.ts
+++ b/src/legacy/core_plugins/telemetry/index.ts
@@ -50,12 +50,9 @@ const telemetry = (kibana: any) => {
allowChangingOptInStatus: Joi.boolean().default(true),
optIn: Joi.when('allowChangingOptInStatus', {
is: false,
- then: Joi.valid(true).required(),
- otherwise: Joi.boolean()
- .allow(null)
- .default(null),
+ then: Joi.valid(true).default(true),
+ otherwise: Joi.boolean().default(true),
}),
-
// `config` is used internally and not intended to be set
config: Joi.string().default(Joi.ref('$defaultConfigPath')),
banner: Joi.boolean().default(true),
@@ -68,6 +65,15 @@ const telemetry = (kibana: any) => {
`https://telemetry.elastic.co/xpack/${ENDPOINT_VERSION}/send`
),
}),
+ optInStatusUrl: Joi.when('$dev', {
+ is: true,
+ then: Joi.string().default(
+ `https://telemetry-staging.elastic.co/opt_in_status/${ENDPOINT_VERSION}/send`
+ ),
+ otherwise: Joi.string().default(
+ `https://telemetry.elastic.co/opt_in_status/${ENDPOINT_VERSION}/send`
+ ),
+ }),
sendUsageFrom: Joi.string()
.allow(['server', 'browser'])
.default('browser'),
@@ -103,6 +109,7 @@ const telemetry = (kibana: any) => {
config.get('telemetry.allowChangingOptInStatus') !== false &&
getXpackConfigWithDeprecated(config, 'telemetry.banner'),
telemetryOptedIn: config.get('telemetry.optIn'),
+ telemetryOptInStatusUrl: config.get('telemetry.optInStatusUrl'),
allowChangingOptInStatus: config.get('telemetry.allowChangingOptInStatus'),
telemetrySendUsageFrom: config.get('telemetry.sendUsageFrom'),
};
@@ -142,7 +149,6 @@ const telemetry = (kibana: any) => {
} as any) as CoreSetup;
telemetryPlugin(initializerContext).setup(coreSetup);
-
// register collectors
server.usage.collectorSet.register(createTelemetryPluginUsageCollector(server));
server.usage.collectorSet.register(createLocalizationUsageCollector(server));
diff --git a/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap b/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap
index b96313fd700ac..a7f8d72e016f8 100644
--- a/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap
+++ b/src/legacy/core_plugins/telemetry/public/components/__snapshots__/telemetry_form.test.js.snap
@@ -34,7 +34,8 @@ exports[`TelemetryForm renders as expected when allows to change optIn status 1`
save={[Function]}
setting={
Object {
- "defVal": false,
+ "ariaName": "Provide usage statistics",
+ "defVal": true,
"description":
Help us improve the Elastic Stack by providing usage statistics for basic features. We will not share this data outside of Elastic.
diff --git a/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js b/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js
index 80eb2da59c47e..6c6ace71af4d0 100644
--- a/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js
+++ b/src/legacy/core_plugins/telemetry/public/components/telemetry_form.js
@@ -33,6 +33,7 @@ import { getConfigTelemetryDesc, PRIVACY_STATEMENT_URL } from '../../common/cons
import { OptInExampleFlyout } from './opt_in_details_component';
import { Field } from 'ui/management';
import { FormattedMessage } from '@kbn/i18n/react';
+import { i18n } from '@kbn/i18n';
const SEARCH_TERMS = ['telemetry', 'usage', 'data', 'usage data'];
@@ -116,7 +117,8 @@ export class TelemetryForm extends Component {
type: 'boolean',
value: telemetryOptInProvider.getOptIn() || false,
description: this.renderDescription(),
- defVal: false,
+ defVal: true,
+ ariaName: i18n.translate('telemetry.provideUsageStatisticsLabel', { defaultMessage: 'Provide usage statistics' })
}}
save={this.toggleOptIn}
clear={this.toggleOptIn}
diff --git a/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/click_banner.test.js b/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/click_banner.test.js
index 6e9a9fc8443ba..54557f100f4aa 100644
--- a/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/click_banner.test.js
+++ b/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/click_banner.test.js
@@ -54,7 +54,7 @@ const getTelemetryOptInProvider = ({ simulateFailure = false, simulateError = fa
addBasePath: (url) => url
};
- const provider = new TelemetryOptInProvider(injector, chrome);
+ const provider = new TelemetryOptInProvider(injector, chrome, false);
if (simulateError) {
provider.setOptIn = () => Promise.reject('unhandled error');
diff --git a/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.test.js b/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.test.js
index f26ca0ca0e3c5..d78a4a3e92362 100644
--- a/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.test.js
+++ b/src/legacy/core_plugins/telemetry/public/hacks/welcome_banner/handle_old_settings.test.js
@@ -49,7 +49,7 @@ const getTelemetryOptInProvider = (enabled, { simulateFailure = false } = {}) =>
}
};
- return new TelemetryOptInProvider($injector, chrome);
+ return new TelemetryOptInProvider($injector, chrome, false);
};
describe('handle_old_settings', () => {
diff --git a/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.test.js b/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.test.js
index 26f14fc87d937..b0ebb9e7382f6 100644
--- a/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.test.js
+++ b/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.test.js
@@ -48,7 +48,7 @@ describe('TelemetryOptInProvider', () => {
}
};
- const provider = new TelemetryOptInProvider(mockInjector, mockChrome);
+ const provider = new TelemetryOptInProvider(mockInjector, mockChrome, false);
return {
provider,
mockHttp,
diff --git a/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts b/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts
index f7b09b1befafa..9b32f88df1218 100644
--- a/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts
+++ b/src/legacy/core_plugins/telemetry/public/services/telemetry_opt_in.ts
@@ -26,7 +26,36 @@ import { i18n } from '@kbn/i18n';
let bannerId: string | null = null;
let currentOptInStatus = false;
-export function TelemetryOptInProvider($injector: any, chrome: any) {
+async function sendOptInStatus($injector: any, chrome: any, enabled: boolean) {
+ const telemetryOptInStatusUrl = npStart.core.injectedMetadata.getInjectedVar(
+ 'telemetryOptInStatusUrl'
+ ) as string;
+ const $http = $injector.get('$http');
+
+ try {
+ const optInStatus = await $http.post(
+ chrome.addBasePath('/api/telemetry/v2/clusters/_opt_in_stats'),
+ {
+ enabled,
+ unencrypted: false,
+ }
+ );
+
+ if (optInStatus.data && optInStatus.data.length) {
+ return await fetch(telemetryOptInStatusUrl, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ },
+ body: JSON.stringify(optInStatus.data),
+ });
+ }
+ } catch (err) {
+ // Sending the ping is best-effort. Telemetry tries to send the ping once and discards it immediately if sending fails.
+ // swallow any errors
+ }
+}
+export function TelemetryOptInProvider($injector: any, chrome: any, sendOptInStatusChange = true) {
currentOptInStatus = npStart.core.injectedMetadata.getInjectedVar('telemetryOptedIn') as boolean;
const allowChangingOptInStatus = npStart.core.injectedMetadata.getInjectedVar(
'allowChangingOptInStatus'
@@ -49,6 +78,9 @@ export function TelemetryOptInProvider($injector: any, chrome: any) {
try {
await $http.post(chrome.addBasePath('/api/telemetry/v2/optIn'), { enabled });
+ if (sendOptInStatusChange) {
+ await sendOptInStatus($injector, chrome, enabled);
+ }
currentOptInStatus = enabled;
} catch (error) {
toastNotifications.addError(error, {
diff --git a/src/legacy/core_plugins/telemetry/server/collection_manager.ts b/src/legacy/core_plugins/telemetry/server/collection_manager.ts
index 19bc735b9a965..799d9f4ee9c8b 100644
--- a/src/legacy/core_plugins/telemetry/server/collection_manager.ts
+++ b/src/legacy/core_plugins/telemetry/server/collection_manager.ts
@@ -18,83 +18,186 @@
*/
import { encryptTelemetry } from './collectors';
+import { CallCluster } from '../../elasticsearch';
export type EncryptedStatsGetterConfig = { unencrypted: false } & {
server: any;
- start: any;
- end: any;
- isDev: boolean;
+ start: string;
+ end: string;
};
export type UnencryptedStatsGetterConfig = { unencrypted: true } & {
req: any;
- start: any;
- end: any;
- isDev: boolean;
+ start: string;
+ end: string;
};
+export interface ClusterDetails {
+ clusterUuid: string;
+}
+
export interface StatsCollectionConfig {
- callCluster: any;
+ callCluster: CallCluster;
server: any;
- start: any;
- end: any;
+ start: string;
+ end: string;
}
export type StatsGetterConfig = UnencryptedStatsGetterConfig | EncryptedStatsGetterConfig;
+export type ClusterDetailsGetter = (config: StatsCollectionConfig) => Promise;
+export type StatsGetter = (
+ clustersDetails: ClusterDetails[],
+ config: StatsCollectionConfig
+) => Promise;
-export type StatsGetter = (config: StatsGetterConfig) => Promise;
-
-export const getStatsCollectionConfig = (
- config: StatsGetterConfig,
- esClustser: string
-): StatsCollectionConfig => {
- const { start, end } = config;
- const server = config.unencrypted ? config.req.server : config.server;
- const { callWithRequest, callWithInternalUser } = server.plugins.elasticsearch.getCluster(
- esClustser
- );
- const callCluster = config.unencrypted
- ? (...args: any[]) => callWithRequest(config.req, ...args)
- : callWithInternalUser;
-
- return { server, callCluster, start, end };
-};
+interface CollectionConfig {
+ title: string;
+ priority: number;
+ esCluster: string;
+ statsGetter: StatsGetter;
+ clusterDetailsGetter: ClusterDetailsGetter;
+}
+interface Collection {
+ statsGetter: StatsGetter;
+ clusterDetailsGetter: ClusterDetailsGetter;
+ esCluster: string;
+ title: string;
+}
export class TelemetryCollectionManager {
- private getterMethod?: StatsGetter;
- private collectionTitle?: string;
- private getterMethodPriority = -1;
-
- public setStatsGetter = (statsGetter: StatsGetter, title: string, priority = 0) => {
- if (priority > this.getterMethodPriority) {
- this.getterMethod = statsGetter;
- this.collectionTitle = title;
- this.getterMethodPriority = priority;
+ private usageGetterMethodPriority = -1;
+ private collections: Collection[] = [];
+
+ public setCollection = (collectionConfig: CollectionConfig) => {
+ const { title, priority, esCluster, statsGetter, clusterDetailsGetter } = collectionConfig;
+
+ if (typeof priority !== 'number') {
+ throw new Error('priority must be set.');
+ }
+ if (priority === this.usageGetterMethodPriority) {
+ throw new Error(`A Usage Getter with the same priority is already set.`);
}
- };
- private getStats = async (config: StatsGetterConfig) => {
- if (!this.getterMethod) {
- throw Error('Stats getter method not set.');
+ if (priority > this.usageGetterMethodPriority) {
+ if (!statsGetter) {
+ throw Error('Stats getter method not set.');
+ }
+ if (!esCluster) {
+ throw Error('esCluster name must be set for the getCluster method.');
+ }
+ if (!clusterDetailsGetter) {
+ throw Error('Cluser UUIds method is not set.');
+ }
+
+ this.collections.unshift({
+ statsGetter,
+ clusterDetailsGetter,
+ esCluster,
+ title,
+ });
+ this.usageGetterMethodPriority = priority;
}
- const usageData = await this.getterMethod(config);
+ };
- if (config.unencrypted) return usageData;
- return encryptTelemetry(usageData, config.isDev);
+ private getStatsCollectionConfig = async (
+ collection: Collection,
+ config: StatsGetterConfig
+ ): Promise => {
+ const { start, end } = config;
+ const server = config.unencrypted ? config.req.server : config.server;
+ const { callWithRequest, callWithInternalUser } = server.plugins.elasticsearch.getCluster(
+ collection.esCluster
+ );
+ const callCluster = config.unencrypted
+ ? (...args: any[]) => callWithRequest(config.req, ...args)
+ : callWithInternalUser;
+
+ return { server, callCluster, start, end };
};
- public getCollectionTitle = () => {
- return this.collectionTitle;
+
+ private getOptInStatsForCollection = async (
+ collection: Collection,
+ optInStatus: boolean,
+ statsCollectionConfig: StatsCollectionConfig
+ ) => {
+ const clustersDetails = await collection.clusterDetailsGetter(statsCollectionConfig);
+ return clustersDetails.map(({ clusterUuid }) => ({
+ cluster_uuid: clusterUuid,
+ opt_in_status: optInStatus,
+ }));
};
- public getStatsGetter = () => {
- if (!this.getterMethod) {
- throw Error('Stats getter method not set.');
+ private getUsageForCollection = async (
+ collection: Collection,
+ statsCollectionConfig: StatsCollectionConfig
+ ) => {
+ const clustersDetails = await collection.clusterDetailsGetter(statsCollectionConfig);
+
+ if (clustersDetails.length === 0) {
+ // don't bother doing a further lookup, try next collection.
+ return;
}
- return {
- getStats: this.getStats,
- priority: this.getterMethodPriority,
- title: this.collectionTitle,
- };
+
+ return await collection.statsGetter(clustersDetails, statsCollectionConfig);
+ };
+
+ public getOptInStats = async (optInStatus: boolean, config: StatsGetterConfig) => {
+ for (const collection of this.collections) {
+ const statsCollectionConfig = await this.getStatsCollectionConfig(collection, config);
+ try {
+ const optInStats = await this.getOptInStatsForCollection(
+ collection,
+ optInStatus,
+ statsCollectionConfig
+ );
+ if (optInStats && optInStats.length) {
+ statsCollectionConfig.server.log(
+ ['debug', 'telemetry', 'collection'],
+ `Got Opt In stats using ${collection.title} collection.`
+ );
+ if (config.unencrypted) {
+ return optInStats;
+ }
+ const isDev = statsCollectionConfig.server.config().get('env.dev');
+ return encryptTelemetry(optInStats, isDev);
+ }
+ } catch (err) {
+ statsCollectionConfig.server.log(
+ ['debu', 'telemetry', 'collection'],
+ `Failed to collect any opt in stats with registered collections.`
+ );
+ // swallow error to try next collection;
+ }
+ }
+
+ return [];
+ };
+ public getStats = async (config: StatsGetterConfig) => {
+ for (const collection of this.collections) {
+ const statsCollectionConfig = await this.getStatsCollectionConfig(collection, config);
+ try {
+ const usageData = await this.getUsageForCollection(collection, statsCollectionConfig);
+ if (usageData && usageData.length) {
+ statsCollectionConfig.server.log(
+ ['debug', 'telemetry', 'collection'],
+ `Got Usage using ${collection.title} collection.`
+ );
+ if (config.unencrypted) {
+ return usageData;
+ }
+ const isDev = statsCollectionConfig.server.config().get('env.dev');
+ return encryptTelemetry(usageData, isDev);
+ }
+ } catch (err) {
+ statsCollectionConfig.server.log(
+ ['debu', 'telemetry', 'collection'],
+ `Failed to collect any usage with registered collections.`
+ );
+ // swallow error to try next collection;
+ }
+ }
+
+ return [];
};
}
diff --git a/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts b/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts
index e092ceb5e8593..a172ba7dc6955 100644
--- a/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts
+++ b/src/legacy/core_plugins/telemetry/server/collectors/telemetry_plugin/telemetry_plugin_collector.ts
@@ -19,7 +19,7 @@
import { TELEMETRY_STATS_TYPE } from '../../../common/constants';
import { getTelemetrySavedObject, TelemetrySavedObject } from '../../telemetry_repository';
-import { getTelemetryOptIn, getTelemetryUsageFetcher } from '../../telemetry_config';
+import { getTelemetryOptIn, getTelemetrySendUsageFrom } from '../../telemetry_config';
export interface TelemetryUsageStats {
opt_in_status?: boolean | null;
usage_fetcher?: 'browser' | 'server';
@@ -53,7 +53,7 @@ export function createCollectorFetch(server: any) {
configTelemetryOptIn,
}),
last_reported: telemetrySavedObject ? telemetrySavedObject.lastReported : undefined,
- usage_fetcher: getTelemetryUsageFetcher({
+ usage_fetcher: getTelemetrySendUsageFrom({
telemetrySavedObject,
configTelemetrySendUsageFrom,
}),
diff --git a/src/legacy/core_plugins/telemetry/server/collectors/usage/ensure_deep_object.ts b/src/legacy/core_plugins/telemetry/server/collectors/usage/ensure_deep_object.ts
index 6594c7f8e7a6f..3b7a9355da746 100644
--- a/src/legacy/core_plugins/telemetry/server/collectors/usage/ensure_deep_object.ts
+++ b/src/legacy/core_plugins/telemetry/server/collectors/usage/ensure_deep_object.ts
@@ -42,19 +42,16 @@ export function ensureDeepObject(obj: any): any {
return obj.map(item => ensureDeepObject(item));
}
- return Object.keys(obj).reduce(
- (fullObject, propertyKey) => {
- const propertyValue = obj[propertyKey];
- if (!propertyKey.includes(separator)) {
- fullObject[propertyKey] = ensureDeepObject(propertyValue);
- } else {
- walk(fullObject, propertyKey.split(separator), propertyValue);
- }
+ return Object.keys(obj).reduce((fullObject, propertyKey) => {
+ const propertyValue = obj[propertyKey];
+ if (!propertyKey.includes(separator)) {
+ fullObject[propertyKey] = ensureDeepObject(propertyValue);
+ } else {
+ walk(fullObject, propertyKey.split(separator), propertyValue);
+ }
- return fullObject;
- },
- {} as any
- );
+ return fullObject;
+ }, {} as any);
}
function walk(obj: any, keys: string[], value: any) {
diff --git a/src/legacy/core_plugins/telemetry/server/fetcher.ts b/src/legacy/core_plugins/telemetry/server/fetcher.ts
index 43883395eac99..9edd8457f2b89 100644
--- a/src/legacy/core_plugins/telemetry/server/fetcher.ts
+++ b/src/legacy/core_plugins/telemetry/server/fetcher.ts
@@ -21,7 +21,7 @@ import moment from 'moment';
// @ts-ignore
import fetch from 'node-fetch';
import { telemetryCollectionManager } from './collection_manager';
-import { getTelemetryOptIn, getTelemetryUsageFetcher } from './telemetry_config';
+import { getTelemetryOptIn, getTelemetrySendUsageFrom } from './telemetry_config';
import { getTelemetrySavedObject, updateTelemetrySavedObject } from './telemetry_repository';
import { REPORT_INTERVAL_MS } from '../common/constants';
import { getXpackConfigWithDeprecated } from '../common/get_xpack_config_with_deprecated';
@@ -61,7 +61,7 @@ export class FetcherTask {
allowChangingOptInStatus,
configTelemetryOptIn,
}),
- telemetrySendUsageFrom: getTelemetryUsageFetcher({
+ telemetrySendUsageFrom: getTelemetrySendUsageFrom({
telemetrySavedObject,
configTelemetrySendUsageFrom,
}),
@@ -87,18 +87,13 @@ export class FetcherTask {
};
private fetchTelemetry = async () => {
- const { getStats, title } = telemetryCollectionManager.getStatsGetter();
- this.server.log(['debug', 'telemetry', 'fetcher'], `Fetching usage using ${title} getter.`);
- const config = this.server.config();
-
- return await getStats({
+ return await telemetryCollectionManager.getStats({
unencrypted: false,
server: this.server,
start: moment()
.subtract(20, 'minutes')
.toISOString(),
end: moment().toISOString(),
- isDev: config.get('env.dev'),
});
};
diff --git a/src/legacy/core_plugins/telemetry/server/plugin.ts b/src/legacy/core_plugins/telemetry/server/plugin.ts
index a5f0f1234799a..f2628090c08af 100644
--- a/src/legacy/core_plugins/telemetry/server/plugin.ts
+++ b/src/legacy/core_plugins/telemetry/server/plugin.ts
@@ -19,8 +19,7 @@
import { CoreSetup, PluginInitializerContext } from 'src/core/server';
import { registerRoutes } from './routes';
-import { telemetryCollectionManager } from './collection_manager';
-import { getStats } from './telemetry_collection';
+import { registerCollection } from './telemetry_collection';
export class TelemetryPlugin {
private readonly currentKibanaVersion: string;
@@ -31,7 +30,7 @@ export class TelemetryPlugin {
public setup(core: CoreSetup) {
const currentKibanaVersion = this.currentKibanaVersion;
- telemetryCollectionManager.setStatsGetter(getStats, 'local');
+ registerCollection();
registerRoutes({ core, currentKibanaVersion });
}
}
diff --git a/src/legacy/core_plugins/telemetry/server/routes/index.ts b/src/legacy/core_plugins/telemetry/server/routes/index.ts
index 93654f6470555..66a7b2c97f3ae 100644
--- a/src/legacy/core_plugins/telemetry/server/routes/index.ts
+++ b/src/legacy/core_plugins/telemetry/server/routes/index.ts
@@ -18,8 +18,9 @@
*/
import { CoreSetup } from 'src/core/server';
-import { registerTelemetryConfigRoutes } from './telemetry_config';
-import { registerTelemetryDataRoutes } from './telemetry_stats';
+import { registerTelemetryOptInRoutes } from './telemetry_opt_in';
+import { registerTelemetryUsageStatsRoutes } from './telemetry_usage_stats';
+import { registerTelemetryOptInStatsRoutes } from './telemetry_opt_in_stats';
interface RegisterRoutesParams {
core: CoreSetup;
@@ -27,6 +28,7 @@ interface RegisterRoutesParams {
}
export function registerRoutes({ core, currentKibanaVersion }: RegisterRoutesParams) {
- registerTelemetryConfigRoutes({ core, currentKibanaVersion });
- registerTelemetryDataRoutes(core);
+ registerTelemetryOptInRoutes({ core, currentKibanaVersion });
+ registerTelemetryUsageStatsRoutes(core);
+ registerTelemetryOptInStatsRoutes(core);
}
diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_config.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts
similarity index 74%
rename from src/legacy/core_plugins/telemetry/server/routes/telemetry_config.ts
rename to src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts
index 440f83277340a..596c5c17c353e 100644
--- a/src/legacy/core_plugins/telemetry/server/routes/telemetry_config.ts
+++ b/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in.ts
@@ -18,9 +18,12 @@
*/
import Joi from 'joi';
+import moment from 'moment';
import { boomify } from 'boom';
import { CoreSetup } from 'src/core/server';
import { getTelemetryAllowChangingOptInStatus } from '../telemetry_config';
+import { sendTelemetryOptInStatus } from './telemetry_opt_in_stats';
+
import {
TelemetrySavedObjectAttributes,
updateTelemetrySavedObject,
@@ -31,7 +34,7 @@ interface RegisterOptInRoutesParams {
currentKibanaVersion: string;
}
-export function registerTelemetryConfigRoutes({
+export function registerTelemetryOptInRoutes({
core,
currentKibanaVersion,
}: RegisterOptInRoutesParams) {
@@ -49,8 +52,9 @@ export function registerTelemetryConfigRoutes({
},
handler: async (req: any, h: any) => {
try {
+ const newOptInStatus = req.payload.enabled;
const attributes: TelemetrySavedObjectAttributes = {
- enabled: req.payload.enabled,
+ enabled: newOptInStatus,
lastVersionChecked: currentKibanaVersion,
};
const config = req.server.config();
@@ -58,6 +62,7 @@ export function registerTelemetryConfigRoutes({
const configTelemetryAllowChangingOptInStatus = config.get(
'telemetry.allowChangingOptInStatus'
);
+
const allowChangingOptInStatus = getTelemetryAllowChangingOptInStatus({
telemetrySavedObject: savedObjectsClient,
configTelemetryAllowChangingOptInStatus,
@@ -65,11 +70,28 @@ export function registerTelemetryConfigRoutes({
if (!allowChangingOptInStatus) {
return h.response({ error: 'Not allowed to change Opt-in Status.' }).code(400);
}
+
+ const sendUsageFrom = config.get('telemetry.sendUsageFrom');
+ if (sendUsageFrom === 'server') {
+ const optInStatusUrl = config.get('telemetry.optInStatusUrl');
+ await sendTelemetryOptInStatus(
+ { optInStatusUrl, newOptInStatus },
+ {
+ start: moment()
+ .subtract(20, 'minutes')
+ .toISOString(),
+ end: moment().toISOString(),
+ server: req.server,
+ unencrypted: false,
+ }
+ );
+ }
+
await updateTelemetrySavedObject(savedObjectsClient, attributes);
+ return h.response({}).code(200);
} catch (err) {
return boomify(err);
}
- return h.response({}).code(200);
},
});
}
diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in_stats.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in_stats.ts
new file mode 100644
index 0000000000000..d3bf6dbb77d7a
--- /dev/null
+++ b/src/legacy/core_plugins/telemetry/server/routes/telemetry_opt_in_stats.ts
@@ -0,0 +1,87 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+// @ts-ignore
+import fetch from 'node-fetch';
+import Joi from 'joi';
+import moment from 'moment';
+import { CoreSetup } from 'src/core/server';
+import { telemetryCollectionManager, StatsGetterConfig } from '../collection_manager';
+
+interface SendTelemetryOptInStatusConfig {
+ optInStatusUrl: string;
+ newOptInStatus: boolean;
+}
+
+export async function sendTelemetryOptInStatus(
+ config: SendTelemetryOptInStatusConfig,
+ statsGetterConfig: StatsGetterConfig
+) {
+ const { optInStatusUrl, newOptInStatus } = config;
+ const optInStatus = await telemetryCollectionManager.getOptInStats(
+ newOptInStatus,
+ statsGetterConfig
+ );
+
+ await fetch(optInStatusUrl, {
+ method: 'post',
+ body: optInStatus,
+ });
+}
+
+export function registerTelemetryOptInStatsRoutes(core: CoreSetup) {
+ const { server } = core.http as any;
+
+ server.route({
+ method: 'POST',
+ path: '/api/telemetry/v2/clusters/_opt_in_stats',
+ options: {
+ validate: {
+ payload: Joi.object({
+ enabled: Joi.bool().required(),
+ unencrypted: Joi.bool().default(true),
+ }),
+ },
+ },
+ handler: async (req: any, h: any) => {
+ try {
+ const newOptInStatus = req.payload.enabled;
+ const unencrypted = req.payload.unencrypted;
+ const statsGetterConfig = {
+ start: moment()
+ .subtract(20, 'minutes')
+ .toISOString(),
+ end: moment().toISOString(),
+ server: req.server,
+ req,
+ unencrypted,
+ };
+
+ const optInStatus = await telemetryCollectionManager.getOptInStats(
+ newOptInStatus,
+ statsGetterConfig
+ );
+
+ return h.response(optInStatus).code(200);
+ } catch (err) {
+ return h.response([]).code(200);
+ }
+ },
+ });
+}
diff --git a/src/legacy/core_plugins/telemetry/server/routes/telemetry_stats.ts b/src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts
similarity index 86%
rename from src/legacy/core_plugins/telemetry/server/routes/telemetry_stats.ts
rename to src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts
index e87c041a263a5..c14314ca4da24 100644
--- a/src/legacy/core_plugins/telemetry/server/routes/telemetry_stats.ts
+++ b/src/legacy/core_plugins/telemetry/server/routes/telemetry_usage_stats.ts
@@ -22,7 +22,7 @@ import { boomify } from 'boom';
import { CoreSetup } from 'src/core/server';
import { telemetryCollectionManager } from '../collection_manager';
-export function registerTelemetryDataRoutes(core: CoreSetup) {
+export function registerTelemetryUsageStatsRoutes(core: CoreSetup) {
const { server } = core.http as any;
server.route({
@@ -44,21 +44,17 @@ export function registerTelemetryDataRoutes(core: CoreSetup) {
const start = req.payload.timeRange.min;
const end = req.payload.timeRange.max;
const unencrypted = req.payload.unencrypted;
- const isDev = config.get('env.dev');
try {
- const { getStats, title } = telemetryCollectionManager.getStatsGetter();
- server.log(['debug', 'telemetry', 'fetcher'], `Fetching usage using ${title} getter.`);
-
- return await getStats({
+ return await telemetryCollectionManager.getStats({
unencrypted,
server,
req,
start,
end,
- isDev,
});
} catch (err) {
+ const isDev = config.get('env.dev');
if (isDev) {
// don't ignore errors when running in dev mode
return boomify(err, { statusCode: err.status || 500 });
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_stats.js b/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_stats.js
index 9ca609cd88778..d60b330db7b5b 100644
--- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_stats.js
+++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_stats.js
@@ -35,9 +35,9 @@ export function mockGetClusterStats(callCluster, clusterStats, req) {
.returns(clusterStats);
}
-describe('get_cluster_stats', () => {
+describe.skip('get_cluster_stats', () => {
- it('uses callCluster to get cluster.stats API', () => {
+ it('uses callCluster to get cluster.stats API', async () => {
const callCluster = sinon.stub();
const response = Promise.resolve({});
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js b/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js
index 261012e594b1c..4cbdf18df4a74 100644
--- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js
+++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js
@@ -152,7 +152,7 @@ describe('get_local_stats', () => {
});
});
- describe('getLocalStats', () => {
+ describe.skip('getLocalStats', () => {
it('returns expected object without xpack data when X-Pack fails to respond', async () => {
const callClusterUsageFailed = sinon.stub();
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.js b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts
similarity index 65%
rename from src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.js
rename to src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts
index a840c39812e2c..4abd95f0cf66d 100644
--- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.js
+++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts
@@ -17,18 +17,24 @@
* under the License.
*/
+import { CallCluster } from 'src/legacy/core_plugins/elasticsearch';
import { TIMEOUT } from './constants';
-
+import { ClusterDetailsGetter } from '../collection_manager';
/**
* Get the cluster stats from the connected cluster.
*
* This is the equivalent to GET /_cluster/stats?timeout=30s.
- *
- * @param {function} callCluster The callWithInternalUser handler (exposed for testing)
- * @return {Promise} The response from Elasticsearch equivalent to GET /_cluster/stats.
*/
-export function getClusterStats(callCluster) {
- return callCluster('cluster.stats', {
- timeout: TIMEOUT
+export async function getClusterStats(callCluster: CallCluster) {
+ return await callCluster('cluster.stats', {
+ timeout: TIMEOUT,
});
}
+
+/**
+ * Get the cluster uuids from the connected cluster.
+ */
+export const getClusterUuids: ClusterDetailsGetter = async ({ callCluster }) => {
+ const result = await getClusterStats(callCluster);
+ return [{ clusterUuid: result.cluster_uuid }];
+};
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.js b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.ts
similarity index 72%
rename from src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.js
rename to src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.ts
index 6125dadc3646f..e11c6b1277d5b 100644
--- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.js
+++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/get_local_stats.ts
@@ -18,9 +18,12 @@
*/
import { get, omit } from 'lodash';
+// @ts-ignore
import { getClusterInfo } from './get_cluster_info';
import { getClusterStats } from './get_cluster_stats';
+// @ts-ignore
import { getKibana, handleKibanaStats } from './get_kibana';
+import { StatsGetter } from '../collection_manager';
/**
* Handle the separate local calls by combining them into a single object response that looks like the
@@ -30,9 +33,9 @@ import { getKibana, handleKibanaStats } from './get_kibana';
* @param {Object} clusterStats Cluster stats (GET /_cluster/stats)
* @return {Object} A combined object containing the different responses.
*/
-export function handleLocalStats(server, clusterInfo, clusterStats, kibana) {
+export function handleLocalStats(server: any, clusterInfo: any, clusterStats: any, kibana: any) {
return {
- timestamp: (new Date()).toISOString(),
+ timestamp: new Date().toISOString(),
cluster_uuid: get(clusterInfo, 'cluster_uuid'),
cluster_name: get(clusterInfo, 'cluster_name'),
version: get(clusterInfo, 'version.number'),
@@ -40,7 +43,7 @@ export function handleLocalStats(server, clusterInfo, clusterStats, kibana) {
collection: 'local',
stack_stats: {
kibana: handleKibanaStats(server, kibana),
- }
+ },
};
}
@@ -51,12 +54,16 @@ export function handleLocalStats(server, clusterInfo, clusterStats, kibana) {
* @param {function} callCluster The callWithInternalUser handler (exposed for testing)
* @return {Promise} The object containing the current Elasticsearch cluster's telemetry.
*/
-export async function getLocalStats({ server, callCluster }) {
- const [ clusterInfo, clusterStats, kibana ] = await Promise.all([
- getClusterInfo(callCluster), // cluster info
- getClusterStats(callCluster), // cluster stats (not to be confused with cluster _state_)
- getKibana(server, callCluster),
- ]);
-
- return handleLocalStats(server, clusterInfo, clusterStats, kibana);
-}
+export const getLocalStats: StatsGetter = async (clustersDetails, config) => {
+ const { server, callCluster } = config;
+ return await Promise.all(
+ clustersDetails.map(async clustersDetail => {
+ const [clusterInfo, clusterStats, kibana] = await Promise.all([
+ getClusterInfo(callCluster), // cluster info
+ getClusterStats(callCluster), // cluster stats (not to be confused with cluster _state_)
+ getKibana(server, callCluster),
+ ]);
+ return handleLocalStats(server, clusterInfo, clusterStats, kibana);
+ })
+ );
+};
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts
index f54aaf0ce1bc0..7f228dbc5e6f6 100644
--- a/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts
+++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/index.ts
@@ -19,4 +19,5 @@
// @ts-ignore
export { getLocalStats } from './get_local_stats';
-export { getStats } from './get_stats';
+export { getClusterUuids } from './get_cluster_stats';
+export { registerCollection } from './register_collection';
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_collection/register_collection.ts b/src/legacy/core_plugins/telemetry/server/telemetry_collection/register_collection.ts
new file mode 100644
index 0000000000000..faf8e9de79194
--- /dev/null
+++ b/src/legacy/core_plugins/telemetry/server/telemetry_collection/register_collection.ts
@@ -0,0 +1,51 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at..
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { telemetryCollectionManager } from '../collection_manager';
+import { getLocalStats } from './get_local_stats';
+import { getClusterUuids } from './get_cluster_stats';
+
+export function registerCollection() {
+ telemetryCollectionManager.setCollection({
+ esCluster: 'data',
+ title: 'local',
+ priority: 0,
+ statsGetter: getLocalStats,
+ clusterDetailsGetter: getClusterUuids,
+ });
+}
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.ts
index 057a8b0c47958..d83ffdf69b576 100644
--- a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.ts
+++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_opt_in.ts
@@ -44,7 +44,7 @@ export const getTelemetryOptIn: GetTelemetryOptIn = ({
}
if (telemetrySavedObject === null || typeof telemetrySavedObject.enabled !== 'boolean') {
- return null;
+ return configTelemetryOptIn;
}
const savedOptIn = telemetrySavedObject.enabled;
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.test.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.test.ts
similarity index 92%
rename from src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.test.ts
rename to src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.test.ts
index f2f99104433a3..69868a97a931d 100644
--- a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.test.ts
+++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.test.ts
@@ -17,10 +17,10 @@
* under the License.
*/
-import { getTelemetryUsageFetcher } from './get_telemetry_usage_fetcher';
+import { getTelemetrySendUsageFrom } from './get_telemetry_send_usage_from';
import { TelemetrySavedObject } from '../telemetry_repository/get_telemetry_saved_object';
-describe('getTelemetryUsageFetcher', () => {
+describe('getTelemetrySendUsageFrom', () => {
it('returns kibana.yml config when saved object not found', () => {
const params: CallGetTelemetryUsageFetcherParams = {
savedObjectNotFound: true,
@@ -65,7 +65,7 @@ interface CallGetTelemetryUsageFetcherParams {
function callGetTelemetryUsageFetcher(params: CallGetTelemetryUsageFetcherParams) {
const telemetrySavedObject = getMockTelemetrySavedObject(params);
const configTelemetrySendUsageFrom = params.configSendUsageFrom;
- return getTelemetryUsageFetcher({ configTelemetrySendUsageFrom, telemetrySavedObject });
+ return getTelemetrySendUsageFrom({ configTelemetrySendUsageFrom, telemetrySavedObject });
}
function getMockTelemetrySavedObject(
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.ts
similarity index 96%
rename from src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.ts
rename to src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.ts
index 98f2d6b0c7bbf..9e4ae14b6097c 100644
--- a/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_usage_fetcher.ts
+++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/get_telemetry_send_usage_from.ts
@@ -23,7 +23,7 @@ interface GetTelemetryUsageFetcherConfig {
telemetrySavedObject: TelemetrySavedObject;
}
-export function getTelemetryUsageFetcher({
+export function getTelemetrySendUsageFrom({
telemetrySavedObject,
configTelemetrySendUsageFrom,
}: GetTelemetryUsageFetcherConfig) {
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts
index 25b588b99a3b8..ab30dac1c3666 100644
--- a/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts
+++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/index.ts
@@ -19,5 +19,5 @@
export { replaceTelemetryInjectedVars } from './replace_injected_vars';
export { getTelemetryOptIn } from './get_telemetry_opt_in';
-export { getTelemetryUsageFetcher } from './get_telemetry_usage_fetcher';
+export { getTelemetrySendUsageFrom } from './get_telemetry_send_usage_from';
export { getTelemetryAllowChangingOptInStatus } from './get_telemetry_allow_changing_opt_in_status';
diff --git a/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts b/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts
index c9b4f4ebcd650..90d1f9cfdac65 100644
--- a/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts
+++ b/src/legacy/core_plugins/telemetry/server/telemetry_config/replace_injected_vars.ts
@@ -19,7 +19,7 @@
import { getTelemetrySavedObject } from '../telemetry_repository';
import { getTelemetryOptIn } from './get_telemetry_opt_in';
-import { getTelemetryUsageFetcher } from './get_telemetry_usage_fetcher';
+import { getTelemetrySendUsageFrom } from './get_telemetry_send_usage_from';
import { getTelemetryAllowChangingOptInStatus } from './get_telemetry_allow_changing_opt_in_status';
export async function replaceTelemetryInjectedVars(request: any) {
@@ -51,7 +51,7 @@ export async function replaceTelemetryInjectedVars(request: any) {
currentKibanaVersion,
});
- const telemetrySendUsageFrom = getTelemetryUsageFetcher({
+ const telemetrySendUsageFrom = getTelemetrySendUsageFrom({
configTelemetrySendUsageFrom,
telemetrySavedObject,
});
diff --git a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js
index 751f92fe88215..0e3c4fdd9d355 100644
--- a/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js
+++ b/src/legacy/core_plugins/tile_map/public/__tests__/coordinate_maps_visualization.js
@@ -20,7 +20,7 @@
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern';
-import * as visModule from 'ui/vis';
+import { Vis } from 'ui/vis';
import { ImageComparator } from 'test_utils/image_comparator';
import dummyESResponse from './dummy_es_response.json';
import initial from './initial.png';
@@ -65,7 +65,6 @@ let visRegComplete = false;
describe('CoordinateMapsVisualizationTest', function () {
let domNode;
let CoordinateMapsVisualization;
- let Vis;
let indexPattern;
let vis;
let dependencies;
@@ -91,7 +90,6 @@ describe('CoordinateMapsVisualizationTest', function () {
}
- Vis = Private(visModule.VisProvider);
CoordinateMapsVisualization = createTileMapVisualization(dependencies);
indexPattern = Private(LogstashIndexPatternStubProvider);
diff --git a/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx b/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx
index ef6b2eaea1e52..c5ccc3acba610 100644
--- a/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx
+++ b/src/legacy/core_plugins/tile_map/public/components/wms_options.tsx
@@ -23,23 +23,26 @@ import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import { TmsLayer } from 'ui/vis/map/service_settings';
+import { Vis } from 'ui/vis';
+import { RegionMapVisParams } from '../../../region_map/public/types';
import { SelectOption, SwitchOption } from '../../../kbn_vislib_vis_types/public/components';
-import { RegionMapOptionsProps } from '../../../region_map/public/components/region_map_options';
import { WmsInternalOptions } from './wms_internal_options';
-import { TileMapOptionsProps } from './tile_map_options';
-import { TileMapVisParams } from '../types';
+import { WMSOptions, TileMapVisParams } from '../types';
+
+interface Props {
+ stateParams: TileMapVisParams | RegionMapVisParams;
+ setValue: (title: 'wms', options: WMSOptions) => void;
+ vis: Vis;
+}
const mapLayerForOption = ({ id }: TmsLayer) => ({ text: id, value: id });
-function WmsOptions({ stateParams, setValue, vis }: TileMapOptionsProps | RegionMapOptionsProps) {
+function WmsOptions({ stateParams, setValue, vis }: Props) {
const { wms } = stateParams;
const { tmsLayers } = vis.type.editorConfig.collections;
const tmsLayerOptions = useMemo(() => tmsLayers.map(mapLayerForOption), [tmsLayers]);
- const setWmsOption = (
- paramName: T,
- value: TileMapVisParams['wms'][T]
- ) =>
+ const setWmsOption = (paramName: T, value: WMSOptions[T]) =>
setValue('wms', {
...wms,
[paramName]: value,
diff --git a/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts b/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts
index 6239e4027c392..35dea4a0deb9b 100644
--- a/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts
+++ b/src/legacy/core_plugins/timelion/public/vis/timelion_request_handler.ts
@@ -22,8 +22,7 @@ import { buildEsQuery, getEsQueryConfig } from '@kbn/es-query';
// @ts-ignore
import { timezoneProvider } from 'ui/vis/lib/timezone';
import { KIBANA_CONTEXT_NAME } from 'src/plugins/expressions/public';
-import { Query } from 'src/legacy/core_plugins/data/public';
-import { TimeRange, esFilters } from 'src/plugins/data/public';
+import { Query, TimeRange, esFilters } from 'src/plugins/data/public';
import { VisParams } from 'ui/vis';
import { i18n } from '@kbn/i18n';
import { TimelionVisualizationDependencies } from '../plugin';
diff --git a/src/legacy/core_plugins/vis_type_metric/public/__tests__/metric_vis.js b/src/legacy/core_plugins/vis_type_metric/public/__tests__/metric_vis.js
index 7f626df6a4ea3..384beb3764e2e 100644
--- a/src/legacy/core_plugins/vis_type_metric/public/__tests__/metric_vis.js
+++ b/src/legacy/core_plugins/vis_type_metric/public/__tests__/metric_vis.js
@@ -21,7 +21,7 @@ import $ from 'jquery';
import ngMock from 'ng_mock';
import expect from '@kbn/expect';
-import { VisProvider } from 'ui/vis';
+import { Vis } from 'ui/vis';
import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern';
import { createMetricVisTypeDefinition } from '../metric_vis_type';
@@ -34,7 +34,6 @@ describe('metric_vis - createMetricVisTypeDefinition', () => {
beforeEach(
ngMock.inject(Private => {
setup = () => {
- const Vis = Private(VisProvider);
const metricVisType = createMetricVisTypeDefinition();
const indexPattern = Private(LogstashIndexPatternStubProvider);
diff --git a/src/legacy/core_plugins/vis_type_table/public/__tests__/table_vis_controller.js b/src/legacy/core_plugins/vis_type_table/public/__tests__/table_vis_controller.js
index abebf8190dc9f..4153ce2da36a7 100644
--- a/src/legacy/core_plugins/vis_type_table/public/__tests__/table_vis_controller.js
+++ b/src/legacy/core_plugins/vis_type_table/public/__tests__/table_vis_controller.js
@@ -21,7 +21,7 @@ import $ from 'jquery';
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
import { legacyResponseHandlerProvider } from 'ui/vis/response_handlers/legacy';
-import { VisProvider } from 'ui/vis';
+import { Vis } from 'ui/vis';
import { VisFactoryProvider } from 'ui/vis/vis_factory';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
import { AppStateProvider } from 'ui/state_management/app_state';
@@ -36,7 +36,6 @@ describe('Table Vis - Controller', async function () {
let Private;
let $scope;
let $el;
- let Vis;
let fixtures;
let AppState;
let tableAggResponse;
@@ -63,7 +62,6 @@ describe('Table Vis - Controller', async function () {
$compile = $injector.get('$compile');
fixtures = require('fixtures/fake_hierarchical_data');
AppState = Private(AppStateProvider);
- Vis = Private(VisProvider);
tableAggResponse = legacyResponseHandlerProvider().handler;
})
);
diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js
index d22ff92c4d3f6..13e8a4fd9535a 100644
--- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js
+++ b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table.js
@@ -25,7 +25,7 @@ import fixtures from 'fixtures/fake_hierarchical_data';
import sinon from 'sinon';
import { legacyResponseHandlerProvider } from 'ui/vis/response_handlers/legacy';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
-import { VisProvider } from 'ui/vis';
+import { Vis } from 'ui/vis';
import { tabifyAggResponse } from 'ui/agg_response/tabify';
import { round } from 'lodash';
@@ -36,7 +36,6 @@ import { setup as visualizationsSetup } from '../../../../visualizations/public/
describe('Table Vis - AggTable Directive', function () {
let $rootScope;
let $compile;
- let Vis;
let indexPattern;
let settings;
let tableAggResponse;
@@ -113,7 +112,6 @@ describe('Table Vis - AggTable Directive', function () {
ngMock.inject(function ($injector, Private, config) {
tableAggResponse = legacyResponseHandlerProvider().handler;
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
- Vis = Private(VisProvider);
settings = config;
$rootScope = $injector.get('$rootScope');
diff --git a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js
index e8359e37d6186..f4e3a8e36605c 100644
--- a/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js
+++ b/src/legacy/core_plugins/vis_type_table/public/agg_table/__tests__/agg_table_group.js
@@ -23,13 +23,12 @@ import expect from '@kbn/expect';
import fixtures from 'fixtures/fake_hierarchical_data';
import { legacyResponseHandlerProvider } from 'ui/vis/response_handlers/legacy';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
-import { VisProvider } from 'ui/vis';
+import { Vis } from 'ui/vis';
import { tabifyAggResponse } from 'ui/agg_response/tabify';
describe('Table Vis - AggTableGroup Directive', function () {
let $rootScope;
let $compile;
- let Vis;
let indexPattern;
let tableAggResponse;
const tabifiedData = {};
@@ -69,7 +68,6 @@ describe('Table Vis - AggTableGroup Directive', function () {
tableAggResponse = legacyResponseHandlerProvider().handler;
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
- Vis = Private(VisProvider);
$rootScope = $injector.get('$rootScope');
$compile = $injector.get('$compile');
diff --git a/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js b/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js
index 69d08d8cb3f74..0cb903faac47c 100644
--- a/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js
+++ b/src/legacy/core_plugins/vis_type_tagcloud/public/components/__tests__/tag_cloud_visualization.js
@@ -20,7 +20,7 @@
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern';
-import * as visModule from 'ui/vis';
+import { Vis } from 'ui/vis';
import { ImageComparator } from 'test_utils/image_comparator';
import { TagCloudVisualization } from '../tag_cloud_visualization';
import basicdrawPng from './basicdraw.png';
@@ -33,7 +33,6 @@ const PIXEL_DIFF = 64;
describe('TagCloudVisualizationTest', function () {
let domNode;
- let Vis;
let indexPattern;
let vis;
let imageComparator;
@@ -57,7 +56,6 @@ describe('TagCloudVisualizationTest', function () {
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject((Private) => {
- Vis = Private(visModule.VisProvider);
indexPattern = Private(LogstashIndexPatternStubProvider);
}));
diff --git a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js b/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js
index 842d3aa6c4ad7..2b42c22ad7c43 100644
--- a/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js
+++ b/src/legacy/core_plugins/vis_type_timeseries/public/components/vis_editor.js
@@ -44,8 +44,7 @@ const APP_NAME = 'VisEditor';
export class VisEditor extends Component {
constructor(props) {
super(props);
- const { vis } = props;
- this.appState = vis.API.getAppState();
+ this.appState = props.appState;
this.localStorage = new Storage(window.localStorage);
this.state = {
model: props.visParams,
@@ -183,7 +182,6 @@ export class VisEditor extends Component {
dirty={this.state.dirty}
autoApply={this.state.autoApply}
model={model}
- appState={this.appState}
savedObj={this.props.savedObj}
timeRange={this.props.timeRange}
uiState={this.uiState}
@@ -239,4 +237,5 @@ VisEditor.propTypes = {
isEditorMode: PropTypes.bool,
savedObj: PropTypes.object,
timeRange: PropTypes.object,
+ appState: PropTypes.object,
};
diff --git a/src/legacy/core_plugins/vis_type_vega/public/__tests__/vega_visualization.js b/src/legacy/core_plugins/vis_type_vega/public/__tests__/vega_visualization.js
index 46725a2c5d01f..191f35d2e03ea 100644
--- a/src/legacy/core_plugins/vis_type_vega/public/__tests__/vega_visualization.js
+++ b/src/legacy/core_plugins/vis_type_vega/public/__tests__/vega_visualization.js
@@ -23,7 +23,7 @@ import ngMock from 'ng_mock';
import $ from 'jquery';
import { createVegaVisualization } from '../vega_visualization';
import LogstashIndexPatternStubProvider from 'fixtures/stubbed_logstash_index_pattern';
-import * as visModule from 'ui/vis';
+import { Vis } from 'ui/vis';
import { ImageComparator } from 'test_utils/image_comparator';
import vegaliteGraph from '!!raw-loader!./vegalite_graph.hjson';
@@ -50,7 +50,6 @@ const PIXEL_DIFF = 30;
describe('VegaVisualizations', () => {
let domNode;
let VegaVisualization;
- let Vis;
let indexPattern;
let vis;
let imageComparator;
@@ -73,7 +72,6 @@ describe('VegaVisualizations', () => {
);
}
- Vis = Private(visModule.VisProvider);
VegaVisualization = createVegaVisualization(vegaVisualizationDependencies);
indexPattern = Private(LogstashIndexPatternStubProvider);
diff --git a/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts b/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts
index b4c32f37eb90c..accc52c1e5a14 100644
--- a/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts
+++ b/src/legacy/core_plugins/vis_type_vega/public/vega_request_handler.ts
@@ -18,11 +18,9 @@
*/
import { timefilter } from 'ui/timefilter';
-import { TimeRange } from 'src/plugins/data/public';
-import { Query } from 'src/legacy/core_plugins/data/public';
-import { buildEsQuery, getEsQueryConfig } from '@kbn/es-query';
-import { esFilters } from '../../../../plugins/data/public';
+import { buildEsQuery, getEsQueryConfig } from '@kbn/es-query';
+import { esFilters, TimeRange, Query } from '../../../../plugins/data/public';
// @ts-ignore
import { VegaParser } from './data_model/vega_parser';
diff --git a/src/legacy/core_plugins/visualizations/public/index.ts b/src/legacy/core_plugins/visualizations/public/index.ts
index ad86c9ddb14c5..ca79f547890f9 100644
--- a/src/legacy/core_plugins/visualizations/public/index.ts
+++ b/src/legacy/core_plugins/visualizations/public/index.ts
@@ -39,7 +39,6 @@ export { DefaultEditorSize } from 'ui/vis/editor_size';
import * as types from 'ui/vis/vis';
export type Vis = types.Vis;
export type VisParams = types.VisParams;
-export type VisProvider = types.VisProvider;
export type VisState = types.VisState;
export { VisualizationController } from 'ui/vis/vis_types/vis_type';
export { Status } from 'ui/vis/update_status';
diff --git a/src/legacy/plugin_discovery/types.ts b/src/legacy/plugin_discovery/types.ts
index c14daa37f5706..dfd36f2aa7b2b 100644
--- a/src/legacy/plugin_discovery/types.ts
+++ b/src/legacy/plugin_discovery/types.ts
@@ -62,7 +62,6 @@ export interface LegacyPluginOptions {
}>;
apps: any;
hacks: string[];
- devTools: string[];
styleSheetPaths: string;
injectDefaultVars: (server: Server) => Record;
noParse: string[];
diff --git a/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js b/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js
index 27b390ed7e471..39303e94adc6f 100644
--- a/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js
+++ b/src/legacy/ui/public/agg_response/tabify/__tests__/_get_columns.js
@@ -20,15 +20,13 @@
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
import { tabifyGetColumns } from '../_get_columns';
-import { VisProvider } from '../../../vis';
+import { Vis } from '../../../vis';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
describe('get columns', function () {
- let Vis;
let indexPattern;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
- Vis = Private(VisProvider);
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
}));
diff --git a/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js b/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js
index fd8df904b600f..dabd66a22fcd2 100644
--- a/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js
+++ b/src/legacy/ui/public/agg_response/tabify/__tests__/_integration.js
@@ -22,16 +22,14 @@ import fixtures from 'fixtures/fake_hierarchical_data';
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
import { tabifyAggResponse } from '../tabify';
-import { VisProvider } from '../../../vis';
+import { Vis } from '../../../vis';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
describe('tabifyAggResponse Integration', function () {
- let Vis;
let indexPattern;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
- Vis = Private(VisProvider);
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
}));
diff --git a/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js b/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js
index 09668c638d695..001132f97c95a 100644
--- a/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js
+++ b/src/legacy/ui/public/agg_response/tabify/__tests__/_response_writer.js
@@ -20,11 +20,10 @@
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
import { TabbedAggResponseWriter } from '../_response_writer';
-import { VisProvider } from '../../../vis';
+import { Vis } from '../../../vis';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
describe('TabbedAggResponseWriter class', function () {
- let Vis;
let Private;
let indexPattern;
@@ -32,7 +31,6 @@ describe('TabbedAggResponseWriter class', function () {
beforeEach(ngMock.inject(function ($injector) {
Private = $injector.get('Private');
- Vis = Private(VisProvider);
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
}));
diff --git a/src/legacy/ui/public/agg_types/__tests__/buckets/_terms_other_bucket_helper.js b/src/legacy/ui/public/agg_types/__tests__/buckets/_terms_other_bucket_helper.js
index dcadeacb3d1fe..759a6b80d8faf 100644
--- a/src/legacy/ui/public/agg_types/__tests__/buckets/_terms_other_bucket_helper.js
+++ b/src/legacy/ui/public/agg_types/__tests__/buckets/_terms_other_bucket_helper.js
@@ -20,7 +20,7 @@
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
import { buildOtherBucketAgg, mergeOtherBucketAggResponse, updateMissingBucket } from '../../buckets/_terms_other_bucket_helper';
-import { VisProvider } from '../../../vis';
+import { Vis } from '../../../vis';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
const visConfigSingleTerm = {
@@ -158,7 +158,6 @@ describe('Terms Agg Other bucket helper', () => {
function init(aggConfig) {
ngMock.module('kibana');
ngMock.inject((Private) => {
- const Vis = Private(VisProvider);
const indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
vis = new Vis(indexPattern, aggConfig);
diff --git a/src/legacy/ui/public/agg_types/agg_configs.ts b/src/legacy/ui/public/agg_types/agg_configs.ts
index 675d37d05c33c..7c0245f30a1fd 100644
--- a/src/legacy/ui/public/agg_types/agg_configs.ts
+++ b/src/legacy/ui/public/agg_types/agg_configs.ts
@@ -253,13 +253,10 @@ export class AggConfigs {
// collect all the aggregations
const aggregations = this.aggs
.filter(agg => agg.enabled && agg.type)
- .reduce(
- (requestValuesAggs, agg: AggConfig) => {
- const aggs = agg.getRequestAggs();
- return aggs ? requestValuesAggs.concat(aggs) : requestValuesAggs;
- },
- [] as AggConfig[]
- );
+ .reduce((requestValuesAggs, agg: AggConfig) => {
+ const aggs = agg.getRequestAggs();
+ return aggs ? requestValuesAggs.concat(aggs) : requestValuesAggs;
+ }, [] as AggConfig[]);
// move metrics to the end
return _.sortBy(aggregations, (agg: AggConfig) =>
agg.type.type === AggGroupNames.Metrics ? 1 : 0
@@ -282,13 +279,10 @@ export class AggConfigs {
* @return {array[AggConfig]}
*/
getResponseAggs(): AggConfig[] {
- return this.getRequestAggs().reduce(
- function(responseValuesAggs, agg: AggConfig) {
- const aggs = agg.getResponseAggs();
- return aggs ? responseValuesAggs.concat(aggs) : responseValuesAggs;
- },
- [] as AggConfig[]
- );
+ return this.getRequestAggs().reduce(function(responseValuesAggs, agg: AggConfig) {
+ const aggs = agg.getResponseAggs();
+ return aggs ? responseValuesAggs.concat(aggs) : responseValuesAggs;
+ }, [] as AggConfig[]);
}
/**
diff --git a/src/legacy/ui/public/agg_types/buckets/filters.ts b/src/legacy/ui/public/agg_types/buckets/filters.ts
index 44a97abb7a1d7..a8d509d507c6b 100644
--- a/src/legacy/ui/public/agg_types/buckets/filters.ts
+++ b/src/legacy/ui/public/agg_types/buckets/filters.ts
@@ -27,10 +27,9 @@ import { buildEsQuery } from '@kbn/es-query';
import { FiltersParamEditor, FilterValue } from '../../vis/editors/default/controls/filters';
import { createFilterFilters } from './create_filter/filters';
import { BucketAggType, IBucketAggConfig } from './_bucket_agg_type';
-import { setup as data } from '../../../../core_plugins/data/public/legacy';
import { Storage } from '../../../../../plugins/kibana_utils/public';
+import { getQueryLog } from '../../../../../plugins/data/public';
-const { getQueryLog } = data.query.helpers;
const config = chrome.getUiSettingsClient();
const storage = new Storage(window.localStorage);
diff --git a/src/legacy/ui/public/agg_types/buckets/geo_hash.test.ts b/src/legacy/ui/public/agg_types/buckets/geo_hash.test.ts
index 5c599f16e09c2..effa49f0ade6b 100644
--- a/src/legacy/ui/public/agg_types/buckets/geo_hash.test.ts
+++ b/src/legacy/ui/public/agg_types/buckets/geo_hash.test.ts
@@ -156,8 +156,9 @@ describe('Geohash Agg', () => {
describe('aggregation options', () => {
it('should only create geohash_grid and geo_centroid aggregations when isFilteredByCollar is false', () => {
const aggConfigs = getAggConfigs({ isFilteredByCollar: false });
- const requestAggs = geoHashBucketAgg.getRequestAggs(aggConfigs
- .aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
+ const requestAggs = geoHashBucketAgg.getRequestAggs(
+ aggConfigs.aggs[0] as IBucketGeoHashGridAggConfig
+ ) as IBucketGeoHashGridAggConfig[];
expect(requestAggs.length).toEqual(2);
expect(requestAggs[0].type.name).toEqual('geohash_grid');
@@ -166,8 +167,9 @@ describe('Geohash Agg', () => {
it('should only create filter and geohash_grid aggregations when useGeocentroid is false', () => {
const aggConfigs = getAggConfigs({ useGeocentroid: false });
- const requestAggs = geoHashBucketAgg.getRequestAggs(aggConfigs
- .aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
+ const requestAggs = geoHashBucketAgg.getRequestAggs(
+ aggConfigs.aggs[0] as IBucketGeoHashGridAggConfig
+ ) as IBucketGeoHashGridAggConfig[];
expect(requestAggs.length).toEqual(2);
expect(requestAggs[0].type.name).toEqual('filter');
@@ -179,36 +181,43 @@ describe('Geohash Agg', () => {
let originalRequestAggs: IBucketGeoHashGridAggConfig[];
beforeEach(() => {
- originalRequestAggs = geoHashBucketAgg.getRequestAggs(getAggConfigs()
- .aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
+ originalRequestAggs = geoHashBucketAgg.getRequestAggs(
+ getAggConfigs().aggs[0] as IBucketGeoHashGridAggConfig
+ ) as IBucketGeoHashGridAggConfig[];
});
it('should change geo_bounding_box filter aggregation and vis session state when map movement is outside map collar', () => {
- const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(getAggConfigs({
- mapBounds: {
- top_left: { lat: 10.0, lon: -10.0 },
- bottom_right: { lat: 9.0, lon: -9.0 },
- },
- }).aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
+ const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(
+ getAggConfigs({
+ mapBounds: {
+ top_left: { lat: 10.0, lon: -10.0 },
+ bottom_right: { lat: 9.0, lon: -9.0 },
+ },
+ }).aggs[0] as IBucketGeoHashGridAggConfig
+ ) as IBucketGeoHashGridAggConfig[];
expect(originalRequestAggs[1].params).not.toEqual(geoBoxingBox.params);
});
it('should not change geo_bounding_box filter aggregation and vis session state when map movement is within map collar', () => {
- const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(getAggConfigs({
- mapBounds: {
- top_left: { lat: 1, lon: -1 },
- bottom_right: { lat: -1, lon: 1 },
- },
- }).aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
+ const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(
+ getAggConfigs({
+ mapBounds: {
+ top_left: { lat: 1, lon: -1 },
+ bottom_right: { lat: -1, lon: 1 },
+ },
+ }).aggs[0] as IBucketGeoHashGridAggConfig
+ ) as IBucketGeoHashGridAggConfig[];
expect(originalRequestAggs[1].params).toEqual(geoBoxingBox.params);
});
it('should change geo_bounding_box filter aggregation and vis session state when map zoom level changes', () => {
- const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(getAggConfigs({
- mapZoom: -1,
- }).aggs[0] as IBucketGeoHashGridAggConfig) as IBucketGeoHashGridAggConfig[];
+ const [, geoBoxingBox] = geoHashBucketAgg.getRequestAggs(
+ getAggConfigs({
+ mapZoom: -1,
+ }).aggs[0] as IBucketGeoHashGridAggConfig
+ ) as IBucketGeoHashGridAggConfig[];
expect(originalRequestAggs[1].lastMapCollar).not.toEqual(geoBoxingBox.lastMapCollar);
});
diff --git a/src/legacy/ui/public/agg_types/buckets/range.test.ts b/src/legacy/ui/public/agg_types/buckets/range.test.ts
index f7cae60cce773..1b423e64c48ae 100644
--- a/src/legacy/ui/public/agg_types/buckets/range.test.ts
+++ b/src/legacy/ui/public/agg_types/buckets/range.test.ts
@@ -72,7 +72,10 @@ describe('Range Agg', () => {
schema: 'segment',
params: {
field: 'bytes',
- ranges: [{ from: 0, to: 1000 }, { from: 1000, to: 2000 }],
+ ranges: [
+ { from: 0, to: 1000 },
+ { from: 1000, to: 2000 },
+ ],
},
},
],
diff --git a/src/legacy/ui/public/agg_types/buckets/range.ts b/src/legacy/ui/public/agg_types/buckets/range.ts
index 348fccdab3fe3..230675ab487ad 100644
--- a/src/legacy/ui/public/agg_types/buckets/range.ts
+++ b/src/legacy/ui/public/agg_types/buckets/range.ts
@@ -98,7 +98,10 @@ export const rangeBucketAgg = new BucketAggType({
},
{
name: 'ranges',
- default: [{ from: 0, to: 1000 }, { from: 1000, to: 2000 }],
+ default: [
+ { from: 0, to: 1000 },
+ { from: 1000, to: 2000 },
+ ],
editorComponent: RangesEditor,
write(aggConfig: IBucketAggConfig, output: Record) {
output.params.ranges = aggConfig.params.ranges;
diff --git a/src/legacy/ui/public/agg_types/filter/prop_filter.ts b/src/legacy/ui/public/agg_types/filter/prop_filter.ts
index 45f350ea6adc8..e6b5f3831e65d 100644
--- a/src/legacy/ui/public/agg_types/filter/prop_filter.ts
+++ b/src/legacy/ui/public/agg_types/filter/prop_filter.ts
@@ -59,24 +59,21 @@ function propFilter(prop: P) {
return list;
}
- const options = filters.reduce(
- (acc, filter) => {
- let type = 'include';
- let value = filter;
+ const options = filters.reduce((acc, filter) => {
+ let type = 'include';
+ let value = filter;
- if (filter.charAt(0) === '!') {
- type = 'exclude';
- value = filter.substr(1);
- }
+ if (filter.charAt(0) === '!') {
+ type = 'exclude';
+ value = filter.substr(1);
+ }
- if (!acc[type]) {
- acc[type] = [];
- }
- acc[type].push(value);
- return acc;
- },
- {} as { [type: string]: string[] }
- );
+ if (!acc[type]) {
+ acc[type] = [];
+ }
+ acc[type].push(value);
+ return acc;
+ }, {} as { [type: string]: string[] });
return list.filter(item => {
const value = item[prop];
diff --git a/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts b/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts
index 66bc205cead13..c1f5528825bcc 100644
--- a/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts
+++ b/src/legacy/ui/public/agg_types/metrics/metric_agg_type.ts
@@ -58,8 +58,9 @@ export class MetricAggType<
config.getValue ||
((agg, bucket) => {
// Metric types where an empty set equals `zero`
- const isSettableToZero = [METRIC_TYPES.CARDINALITY, METRIC_TYPES.SUM].includes(agg.type
- .name as METRIC_TYPES);
+ const isSettableToZero = [METRIC_TYPES.CARDINALITY, METRIC_TYPES.SUM].includes(
+ agg.type.name as METRIC_TYPES
+ );
// Return proper values when no buckets are present
// `Count` handles empty sets properly
diff --git a/src/legacy/ui/public/agg_types/metrics/percentile_ranks.test.ts b/src/legacy/ui/public/agg_types/metrics/percentile_ranks.test.ts
index f3882ca57161f..7461b5cf07ee7 100644
--- a/src/legacy/ui/public/agg_types/metrics/percentile_ranks.test.ts
+++ b/src/legacy/ui/public/agg_types/metrics/percentile_ranks.test.ts
@@ -63,8 +63,9 @@ describe('AggTypesMetricsPercentileRanksProvider class', function() {
});
it('uses the custom label if it is set', function() {
- const responseAggs: any = percentileRanksMetricAgg.getResponseAggs(aggConfigs
- .aggs[0] as IPercentileRanksAggConfig);
+ const responseAggs: any = percentileRanksMetricAgg.getResponseAggs(
+ aggConfigs.aggs[0] as IPercentileRanksAggConfig
+ );
const percentileRankLabelFor5kBytes = responseAggs[0].makeLabel();
const percentileRankLabelFor10kBytes = responseAggs[1].makeLabel();
diff --git a/src/legacy/ui/public/agg_types/metrics/percentiles.test.ts b/src/legacy/ui/public/agg_types/metrics/percentiles.test.ts
index 1503f43b22dc3..c9f4bcc3862a0 100644
--- a/src/legacy/ui/public/agg_types/metrics/percentiles.test.ts
+++ b/src/legacy/ui/public/agg_types/metrics/percentiles.test.ts
@@ -63,8 +63,9 @@ describe('AggTypesMetricsPercentilesProvider class', () => {
});
it('uses the custom label if it is set', () => {
- const responseAggs: any = percentilesMetricAgg.getResponseAggs(aggConfigs
- .aggs[0] as IPercentileAggConfig);
+ const responseAggs: any = percentilesMetricAgg.getResponseAggs(
+ aggConfigs.aggs[0] as IPercentileAggConfig
+ );
const ninetyFifthPercentileLabel = responseAggs[0].makeLabel();
diff --git a/src/legacy/ui/public/agg_types/metrics/std_deviation.test.ts b/src/legacy/ui/public/agg_types/metrics/std_deviation.test.ts
index ae09b5cd78977..3125026a52185 100644
--- a/src/legacy/ui/public/agg_types/metrics/std_deviation.test.ts
+++ b/src/legacy/ui/public/agg_types/metrics/std_deviation.test.ts
@@ -58,8 +58,9 @@ describe('AggTypeMetricStandardDeviationProvider class', () => {
it('uses the custom label if it is set', () => {
const aggConfigs = getAggConfigs('custom label');
- const responseAggs: any = stdDeviationMetricAgg.getResponseAggs(aggConfigs
- .aggs[0] as IStdDevAggConfig);
+ const responseAggs: any = stdDeviationMetricAgg.getResponseAggs(
+ aggConfigs.aggs[0] as IStdDevAggConfig
+ );
const lowerStdDevLabel = responseAggs[0].makeLabel();
const upperStdDevLabel = responseAggs[1].makeLabel();
@@ -71,8 +72,9 @@ describe('AggTypeMetricStandardDeviationProvider class', () => {
it('uses the default labels if custom label is not set', () => {
const aggConfigs = getAggConfigs();
- const responseAggs: any = stdDeviationMetricAgg.getResponseAggs(aggConfigs
- .aggs[0] as IStdDevAggConfig);
+ const responseAggs: any = stdDeviationMetricAgg.getResponseAggs(
+ aggConfigs.aggs[0] as IStdDevAggConfig
+ );
const lowerStdDevLabel = responseAggs[0].makeLabel();
const upperStdDevLabel = responseAggs[1].makeLabel();
diff --git a/src/legacy/ui/public/filter_manager/__tests__/filter_generator.js b/src/legacy/ui/public/filter_manager/__tests__/filter_generator.js
deleted file mode 100644
index 5b6455bf20847..0000000000000
--- a/src/legacy/ui/public/filter_manager/__tests__/filter_generator.js
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import sinon from 'sinon';
-import MockState from 'fixtures/mock_state';
-import expect from '@kbn/expect';
-import ngMock from 'ng_mock';
-import { getFilterGenerator } from '..';
-import { FilterBarQueryFilterProvider } from '../../filter_manager/query_filter';
-import { uniqFilters, esFilters } from '../../../../../plugins/data/public';
-
-let queryFilter;
-let filterGen;
-let appState;
-
-function checkAddFilters(length, comps, idx) {
- idx = idx || 0;
- const filters = queryFilter.addFilters.getCall(idx).args[0];
-
- expect(filters.length).to.be(length);
- if (!Array.isArray(comps)) return;
- comps.forEach(function (comp, i) {
- expect(filters[i]).to.eql(comp);
- });
-}
-
-describe('Filter Manager', function () {
- beforeEach(ngMock.module(
- 'kibana',
- 'kibana/global_state',
- function ($provide) {
- $provide.service('indexPatterns', require('fixtures/mock_index_patterns'));
-
- appState = new MockState({ filters: [] });
- $provide.service('getAppState', function () {
- return function () { return appState; };
- });
- }
- ));
-
- beforeEach(ngMock.inject(function (_$rootScope_, Private) {
-
- // mock required queryFilter methods, used in the manager
- queryFilter = Private(FilterBarQueryFilterProvider);
- filterGen = getFilterGenerator(queryFilter);
- sinon.stub(queryFilter, 'getAppFilters').callsFake(() => appState.filters);
- sinon.stub(queryFilter, 'addFilters').callsFake((filters) => {
- if (!Array.isArray(filters)) filters = [filters];
- appState.filters = uniqFilters(appState.filters.concat(filters));
- });
- }));
-
- it('should have an `add` function', function () {
- expect(filterGen.add).to.be.a(Function);
- });
-
- it('should add a filter', function () {
- filterGen.add('myField', 1, '+', 'myIndex');
- expect(queryFilter.addFilters.callCount).to.be(1);
- checkAddFilters(1, [{
- meta: { index: 'myIndex', negate: false },
- query: { match_phrase: { myField: 1 } }
- }]);
- });
-
- it('should add multiple filters if passed an array of values', function () {
- filterGen.add('myField', [1, 2, 3], '+', 'myIndex');
- expect(queryFilter.addFilters.callCount).to.be(1);
- checkAddFilters(3, [{
- meta: { index: 'myIndex', negate: false },
- query: { match_phrase: { myField: 1 } }
- }, {
- meta: { index: 'myIndex', negate: false },
- query: { match_phrase: { myField: 2 } }
- }, {
- meta: { index: 'myIndex', negate: false },
- query: { match_phrase: { myField: 3 } }
- }]);
- });
-
- it('should add an exists filter if _exists_ is used as the field', function () {
- filterGen.add('_exists_', 'myField', '+', 'myIndex');
- checkAddFilters(1, [{
- meta: { index: 'myIndex', negate: false },
- exists: { field: 'myField' }
- }]);
- });
-
- it('should negate existing filter instead of added a conflicting filter', function () {
- filterGen.add('myField', 1, '+', 'myIndex');
- checkAddFilters(1, [{
- meta: { index: 'myIndex', negate: false },
- query: { match_phrase: { myField: 1 } }
- }], 0);
- expect(appState.filters).to.have.length(1);
-
- // NOTE: negating exists filters also forces disabled to false
- filterGen.add('myField', 1, '-', 'myIndex');
- checkAddFilters(1, [{
- meta: { index: 'myIndex', negate: true, disabled: false },
- query: { match_phrase: { myField: 1 } }
- }], 1);
- expect(appState.filters).to.have.length(1);
-
- filterGen.add('_exists_', 'myField', '+', 'myIndex');
- checkAddFilters(1, [{
- meta: { index: 'myIndex', negate: false },
- exists: { field: 'myField' }
- }], 2);
- expect(appState.filters).to.have.length(2);
-
- filterGen.add('_exists_', 'myField', '-', 'myIndex');
- checkAddFilters(1, [{
- meta: { index: 'myIndex', negate: true, disabled: false },
- exists: { field: 'myField' }
- }], 3);
- expect(appState.filters).to.have.length(2);
-
- const scriptedField = { name: 'scriptedField', scripted: true, script: 1, lang: 'painless' };
- filterGen.add(scriptedField, 1, '+', 'myIndex');
- checkAddFilters(1, [{
- meta: { index: 'myIndex', negate: false, field: 'scriptedField' },
- script: esFilters.getPhraseScript(scriptedField, 1)
- }], 4);
- expect(appState.filters).to.have.length(3);
-
- filterGen.add(scriptedField, 1, '-', 'myIndex');
- checkAddFilters(1, [{
- meta: { index: 'myIndex', negate: true, disabled: false, field: 'scriptedField' },
- script: esFilters.getPhraseScript(scriptedField, 1)
- }], 5);
- expect(appState.filters).to.have.length(3);
- });
-
- it('should enable matching filters being changed', function () {
- _.each([true, false], function (negate) {
- appState.filters = [{
- query: { match_phrase: { myField: 1 } },
- meta: { disabled: true, negate: negate }
- }];
- expect(appState.filters.length).to.be(1);
- expect(appState.filters[0].meta.disabled).to.be(true);
-
- filterGen.add('myField', 1, '+', 'myIndex');
- expect(appState.filters.length).to.be(1);
- expect(appState.filters[0].meta.disabled).to.be(false);
- });
- });
-});
diff --git a/src/legacy/ui/public/filter_manager/filter_generator.js b/src/legacy/ui/public/filter_manager/filter_generator.js
deleted file mode 100644
index e11e0ff6653a7..0000000000000
--- a/src/legacy/ui/public/filter_manager/filter_generator.js
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to Elasticsearch B.V. under one or more contributor
- * license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright
- * ownership. Elasticsearch B.V. licenses this file to you under
- * the Apache License, Version 2.0 (the "License"); you may
- * not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-import _ from 'lodash';
-import { esFilters } from '../../../../plugins/data/public';
-
-// Adds a filter to a passed state
-export function getFilterGenerator(queryFilter) {
- const filterGen = {};
-
- filterGen.generate = (field, values, operation, index) => {
- values = Array.isArray(values) ? values : [values];
- const fieldName = _.isObject(field) ? field.name : field;
- const filters = _.flatten([queryFilter.getAppFilters()]);
- const newFilters = [];
-
- const negate = (operation === '-');
-
- // TODO: On array fields, negating does not negate the combination, rather all terms
- _.each(values, function (value) {
- let filter;
- const existing = _.find(filters, function (filter) {
- if (!filter) return;
-
- if (fieldName === '_exists_' && filter.exists) {
- return filter.exists.field === value;
- }
-
- if (esFilters.isPhraseFilter(filter)) {
- return esFilters.getPhraseFilterField(filter) === fieldName && esFilters.getPhraseFilterValue(filter) === value;
- }
-
- if (filter.script) {
- return filter.meta.field === fieldName && filter.script.script.params.value === value;
- }
- });
-
- if (existing) {
- existing.meta.disabled = false;
- if (existing.meta.negate !== negate) {
- existing.meta.negate = !existing.meta.negate;
- }
- newFilters.push(existing);
- return;
- }
-
- switch (fieldName) {
- case '_exists_':
- filter = {
- meta: { negate, index },
- exists: {
- field: value
- }
- };
- break;
- default:
- if (field.scripted) {
- filter = {
- meta: { negate, index, field: fieldName },
- script: esFilters.getPhraseScript(field, value)
- };
- } else {
- filter = { meta: { negate, index }, query: { match_phrase: {} } };
- filter.query.match_phrase[fieldName] = value;
- }
-
- break;
- }
-
- newFilters.push(filter);
- });
-
- return newFilters;
- };
-
- filterGen.add = function (field, values, operation, index) {
- const newFilters = this.generate(field, values, operation, index);
- return queryFilter.addFilters(newFilters);
- };
-
- return filterGen;
-}
diff --git a/src/legacy/ui/public/filter_manager/index.js b/src/legacy/ui/public/filter_manager/index.js
index 6adc4e0965ccd..ce99d4cac3017 100644
--- a/src/legacy/ui/public/filter_manager/index.js
+++ b/src/legacy/ui/public/filter_manager/index.js
@@ -17,4 +17,3 @@
* under the License.
*/
-export { getFilterGenerator } from './filter_generator';
diff --git a/src/legacy/ui/public/legacy_compat/angular_config.tsx b/src/legacy/ui/public/legacy_compat/angular_config.tsx
index 58b8422cb2f8a..788718e848430 100644
--- a/src/legacy/ui/public/legacy_compat/angular_config.tsx
+++ b/src/legacy/ui/public/legacy_compat/angular_config.tsx
@@ -40,6 +40,7 @@ import { fatalError } from 'ui/notify';
import { capabilities } from 'ui/capabilities';
// @ts-ignore
import { modifyUrl } from 'ui/url';
+import { toMountPoint } from '../../../../plugins/kibana_react/public';
// @ts-ignore
import { UrlOverflowService } from '../error_url_overflow';
import { npStart } from '../new_platform';
@@ -329,7 +330,7 @@ const $setupUrlOverflowHandling = (newPlatform: CoreStart) => (
title: i18n.translate('common.ui.chrome.bigUrlWarningNotificationTitle', {
defaultMessage: 'The URL is big and Kibana might stop working',
}),
- text: (
+ text: toMountPoint(
{},
+ },
inspector: {
registerView: () => undefined,
__LEGACY: {
@@ -97,6 +100,9 @@ export const npStart = {
registerRenderer: sinon.fake(),
registerType: sinon.fake(),
},
+ devTools: {
+ getSortedDevTools: () => [],
+ },
data: {
autocomplete: {
getProvider: sinon.fake(),
diff --git a/src/legacy/ui/public/new_platform/new_platform.ts b/src/legacy/ui/public/new_platform/new_platform.ts
index 0c7b28e7da3df..9ee5d8580a90b 100644
--- a/src/legacy/ui/public/new_platform/new_platform.ts
+++ b/src/legacy/ui/public/new_platform/new_platform.ts
@@ -28,6 +28,7 @@ import {
Start as InspectorStart,
} from '../../../../plugins/inspector/public';
import { EuiUtilsStart } from '../../../../plugins/eui_utils/public';
+import { DevToolsSetup, DevToolsStart } from '../../../../plugins/dev_tools/public';
import {
FeatureCatalogueSetup,
FeatureCatalogueStart,
@@ -40,6 +41,7 @@ export interface PluginsSetup {
feature_catalogue: FeatureCatalogueSetup;
inspector: InspectorSetup;
uiActions: IUiActionsSetup;
+ devTools: DevToolsSetup;
}
export interface PluginsStart {
@@ -50,6 +52,7 @@ export interface PluginsStart {
feature_catalogue: FeatureCatalogueStart;
inspector: InspectorStart;
uiActions: IUiActionsStart;
+ devTools: DevToolsStart;
}
export const npSetup = {
diff --git a/src/legacy/ui/public/utils/migrate_legacy_query.ts b/src/legacy/ui/public/utils/migrate_legacy_query.ts
index 06e819d6a64a2..8d9b50d5a66b2 100644
--- a/src/legacy/ui/public/utils/migrate_legacy_query.ts
+++ b/src/legacy/ui/public/utils/migrate_legacy_query.ts
@@ -18,7 +18,7 @@
*/
import { has } from 'lodash';
-import { Query } from 'plugins/data';
+import { Query } from 'src/plugins/data/public';
/**
* Creates a standardized query object from old queries that were either strings or pure ES query DSL
diff --git a/src/legacy/ui/public/vis/__tests__/_agg_config.js b/src/legacy/ui/public/vis/__tests__/_agg_config.js
index 46d7ed4601f29..2e2e0c31bdb8a 100644
--- a/src/legacy/ui/public/vis/__tests__/_agg_config.js
+++ b/src/legacy/ui/public/vis/__tests__/_agg_config.js
@@ -20,7 +20,7 @@
import sinon from 'sinon';
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
-import { VisProvider } from '..';
+import { Vis } from '..';
import { AggType } from '../../agg_types/agg_type';
import { AggConfig } from '../../agg_types/agg_config';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
@@ -28,12 +28,10 @@ import { fieldFormats } from '../../registry/field_formats';
describe('AggConfig', function () {
- let Vis;
let indexPattern;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
- Vis = Private(VisProvider);
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
}));
diff --git a/src/legacy/ui/public/vis/__tests__/_agg_configs.js b/src/legacy/ui/public/vis/__tests__/_agg_configs.js
index 96e4aa943ed1d..3240bd56f1502 100644
--- a/src/legacy/ui/public/vis/__tests__/_agg_configs.js
+++ b/src/legacy/ui/public/vis/__tests__/_agg_configs.js
@@ -22,7 +22,7 @@ import sinon from 'sinon';
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
import { AggConfig } from '../../agg_types/agg_config';
-import { VisProvider } from '..';
+import { Vis } from '..';
import { AggConfigs } from '../../agg_types/agg_configs';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
import { Schemas } from '../editors/default/schemas';
@@ -30,13 +30,11 @@ import { AggGroupNames } from '../editors/default/agg_groups';
describe('AggConfigs', function () {
- let Vis;
let indexPattern;
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
// load main deps
- Vis = Private(VisProvider);
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
}));
diff --git a/src/legacy/ui/public/vis/__tests__/_vis.js b/src/legacy/ui/public/vis/__tests__/_vis.js
index 5a2f93ab35b50..1d5e2de6dafe3 100644
--- a/src/legacy/ui/public/vis/__tests__/_vis.js
+++ b/src/legacy/ui/public/vis/__tests__/_vis.js
@@ -20,13 +20,12 @@
import _ from 'lodash';
import ngMock from 'ng_mock';
import expect from '@kbn/expect';
-import { VisProvider } from '..';
+import { Vis } from '..';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
import { start as visualizations } from '../../../../core_plugins/visualizations/public/np_ready/public/legacy';
describe('Vis Class', function () {
let indexPattern;
- let Vis;
let visTypes;
let vis;
@@ -43,7 +42,6 @@ describe('Vis Class', function () {
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private) {
- Vis = Private(VisProvider);
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
visTypes = visualizations.types;
}));
diff --git a/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx b/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx
index 7806b1c0f78fb..661ece5944fa3 100644
--- a/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx
+++ b/src/legacy/ui/public/vis/editors/default/components/agg.test.tsx
@@ -248,10 +248,9 @@ describe('DefaultEditorAgg component', () => {
expect(compHistogram.find(DefaultEditorAggParams).props()).toHaveProperty('disabledParams', [
'min_doc_count',
]);
- expect(compDateHistogram.find(DefaultEditorAggParams).props()).toHaveProperty(
- 'disabledParams',
- ['min_doc_count']
- );
+ expect(
+ compDateHistogram.find(DefaultEditorAggParams).props()
+ ).toHaveProperty('disabledParams', ['min_doc_count']);
});
it('should set error when agg is not histogram or date_histogram', () => {
diff --git a/src/legacy/ui/public/vis/editors/default/components/agg_group_state.tsx b/src/legacy/ui/public/vis/editors/default/components/agg_group_state.tsx
index 8e8926f027cad..980889743c20d 100644
--- a/src/legacy/ui/public/vis/editors/default/components/agg_group_state.tsx
+++ b/src/legacy/ui/public/vis/editors/default/components/agg_group_state.tsx
@@ -53,13 +53,10 @@ function aggGroupReducer(state: AggsState, action: AggsAction): AggsState {
}
function initAggsState(group: AggConfig[]): AggsState {
- return group.reduce(
- (state, agg) => {
- state[agg.id] = { touched: false, valid: true };
- return state;
- },
- {} as AggsState
- );
+ return group.reduce((state, agg) => {
+ state[agg.id] = { touched: false, valid: true };
+ return state;
+ }, {} as AggsState);
}
export { aggGroupReducer, initAggsState };
diff --git a/src/legacy/ui/public/vis/editors/default/components/agg_params_helper.test.ts b/src/legacy/ui/public/vis/editors/default/components/agg_params_helper.test.ts
index 5fb241714b2e8..eb6bef4887642 100644
--- a/src/legacy/ui/public/vis/editors/default/components/agg_params_helper.test.ts
+++ b/src/legacy/ui/public/vis/editors/default/components/agg_params_helper.test.ts
@@ -121,7 +121,10 @@ describe('DefaultEditorAggParams helpers', () => {
},
schema: {},
getIndexPattern: jest.fn(() => ({
- fields: [{ name: '@timestamp', type: 'date' }, { name: 'geo_desc', type: 'string' }],
+ fields: [
+ { name: '@timestamp', type: 'date' },
+ { name: 'geo_desc', type: 'string' },
+ ],
})),
params: {
orderBy: 'orderBy',
diff --git a/src/legacy/ui/public/vis/editors/default/controls/auto_precision.tsx b/src/legacy/ui/public/vis/editors/default/controls/auto_precision.tsx
index 3b6aebe8c2b0c..53f74465e90a5 100644
--- a/src/legacy/ui/public/vis/editors/default/controls/auto_precision.tsx
+++ b/src/legacy/ui/public/vis/editors/default/controls/auto_precision.tsx
@@ -23,7 +23,7 @@ import { EuiSwitch, EuiFormRow } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { AggParamEditorProps } from '..';
-function AutoPrecisionParamEditor({ value, setValue }: AggParamEditorProps) {
+function AutoPrecisionParamEditor({ value = false, setValue }: AggParamEditorProps) {
const label = i18n.translate('common.ui.aggTypes.changePrecisionLabel', {
defaultMessage: 'Change precision on map zoom',
});
diff --git a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts
index 3928c0a62eeaa..c6772cc108762 100644
--- a/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts
+++ b/src/legacy/ui/public/vis/editors/default/controls/components/number_list/utils.test.ts
@@ -35,7 +35,10 @@ describe('NumberList utils', () => {
let range: Range;
beforeEach(() => {
- modelList = [{ value: 1, id: '1', isInvalid: false }, { value: 2, id: '2', isInvalid: false }];
+ modelList = [
+ { value: 1, id: '1', isInvalid: false },
+ { value: 2, id: '2', isInvalid: false },
+ ];
range = {
min: 1,
max: 10,
diff --git a/src/legacy/ui/public/vis/editors/default/controls/filter.tsx b/src/legacy/ui/public/vis/editors/default/controls/filter.tsx
index 4ebe7b0d835d7..e847a95ead478 100644
--- a/src/legacy/ui/public/vis/editors/default/controls/filter.tsx
+++ b/src/legacy/ui/public/vis/editors/default/controls/filter.tsx
@@ -20,7 +20,8 @@
import React, { useState } from 'react';
import { EuiForm, EuiButtonIcon, EuiFieldText, EuiFormRow, EuiSpacer } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { Query, QueryBarInput } from 'plugins/data';
+import { QueryBarInput } from 'plugins/data';
+import { Query } from 'src/plugins/data/public';
import { AggConfig } from '../../..';
import { npStart } from '../../../../new_platform';
import { Storage } from '../../../../../../../plugins/kibana_utils/public';
diff --git a/src/legacy/ui/public/vis/editors/default/controls/filters.tsx b/src/legacy/ui/public/vis/editors/default/controls/filters.tsx
index fe72e8dddd68d..aa654d26a23fd 100644
--- a/src/legacy/ui/public/vis/editors/default/controls/filters.tsx
+++ b/src/legacy/ui/public/vis/editors/default/controls/filters.tsx
@@ -21,7 +21,7 @@ import React, { useState, useEffect } from 'react';
import { omit, isEqual } from 'lodash';
import { htmlIdGenerator, EuiButton, EuiSpacer } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
-import { Query } from 'plugins/data';
+import { Query } from 'src/plugins/data/public';
import chrome from '../../../../chrome';
import { FilterRow } from './filter';
import { AggParamEditorProps } from '..';
diff --git a/src/legacy/ui/public/vis/editors/default/controls/switch.tsx b/src/legacy/ui/public/vis/editors/default/controls/switch.tsx
index a5fc9682bd954..de675386d9100 100644
--- a/src/legacy/ui/public/vis/editors/default/controls/switch.tsx
+++ b/src/legacy/ui/public/vis/editors/default/controls/switch.tsx
@@ -30,7 +30,7 @@ interface SwitchParamEditorProps extends AggParamEditorProps {
}
function SwitchParamEditor({
- value,
+ value = false,
setValue,
dataTestSubj,
displayToolTip,
diff --git a/src/legacy/ui/public/vis/editors/default/controls/use_geocentroid.tsx b/src/legacy/ui/public/vis/editors/default/controls/use_geocentroid.tsx
index 6da32690912e7..932a4d19b495c 100644
--- a/src/legacy/ui/public/vis/editors/default/controls/use_geocentroid.tsx
+++ b/src/legacy/ui/public/vis/editors/default/controls/use_geocentroid.tsx
@@ -23,7 +23,7 @@ import { EuiSwitch, EuiFormRow } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { AggParamEditorProps } from '..';
-function UseGeocentroidParamEditor({ value, setValue }: AggParamEditorProps) {
+function UseGeocentroidParamEditor({ value = false, setValue }: AggParamEditorProps) {
const label = i18n.translate('common.ui.aggTypes.placeMarkersOffGridLabel', {
defaultMessage: 'Place markers off grid (use geocentroid)',
});
diff --git a/src/legacy/ui/public/vis/editors/default/utils.tsx b/src/legacy/ui/public/vis/editors/default/utils.tsx
index efc424488ec41..4f82298aaca41 100644
--- a/src/legacy/ui/public/vis/editors/default/utils.tsx
+++ b/src/legacy/ui/public/vis/editors/default/utils.tsx
@@ -44,24 +44,21 @@ function groupAndSortBy<
TGroupBy extends string = 'type',
TLabelName extends string = 'title'
>(objects: T[], groupBy: TGroupBy, labelName: TLabelName): ComboBoxGroupedOptions {
- const groupedOptions = objects.reduce(
- (array, obj) => {
- const group = array.find(element => element.label === obj[groupBy]);
- const option = {
- label: obj[labelName],
- target: obj,
- };
+ const groupedOptions = objects.reduce((array, obj) => {
+ const group = array.find(element => element.label === obj[groupBy]);
+ const option = {
+ label: obj[labelName],
+ target: obj,
+ };
- if (group && group.options) {
- group.options.push(option);
- } else {
- array.push({ label: obj[groupBy], options: [option] });
- }
+ if (group && group.options) {
+ group.options.push(option);
+ } else {
+ array.push({ label: obj[groupBy], options: [option] });
+ }
- return array;
- },
- [] as Array>
- );
+ return array;
+ }, [] as Array>);
groupedOptions.sort(sortByLabel);
diff --git a/src/legacy/ui/public/vis/index.d.ts b/src/legacy/ui/public/vis/index.d.ts
index 5a2a7edb6329a..791ce2563e0f1 100644
--- a/src/legacy/ui/public/vis/index.d.ts
+++ b/src/legacy/ui/public/vis/index.d.ts
@@ -18,5 +18,5 @@
*/
export { AggConfig } from '../agg_types/agg_config';
-export { Vis, VisProvider, VisParams, VisState } from './vis';
+export { Vis, VisParams, VisState } from './vis';
export { VisualizationController, VisType } from './vis_types/vis_type';
diff --git a/src/legacy/ui/public/vis/index.js b/src/legacy/ui/public/vis/index.js
index 711b465a1e8a5..05cd030f7d100 100644
--- a/src/legacy/ui/public/vis/index.js
+++ b/src/legacy/ui/public/vis/index.js
@@ -17,4 +17,4 @@
* under the License.
*/
-export { VisProvider } from './vis';
+export { Vis } from './vis';
diff --git a/src/legacy/ui/public/vis/map/map_messages.js b/src/legacy/ui/public/vis/map/map_messages.js
index 7571547ecf0d4..a9a636ab9e4cf 100644
--- a/src/legacy/ui/public/vis/map/map_messages.js
+++ b/src/legacy/ui/public/vis/map/map_messages.js
@@ -24,6 +24,7 @@ import {
EuiSpacer,
EuiButtonEmpty
} from '@elastic/eui';
+import { toMountPoint } from '../../../../../plugins/kibana_react/public';
export const createZoomWarningMsg = (function () {
let disableZoomMsg = false;
@@ -107,7 +108,7 @@ export const createZoomWarningMsg = (function () {
const zoomToast = ({
title: 'No additional zoom levels',
- text: ,
+ text: toMountPoint(),
'data-test-subj': 'maxZoomWarning',
});
diff --git a/src/legacy/ui/public/vis/vis.d.ts b/src/legacy/ui/public/vis/vis.d.ts
index be73cccf06a59..e16562641801e 100644
--- a/src/legacy/ui/public/vis/vis.d.ts
+++ b/src/legacy/ui/public/vis/vis.d.ts
@@ -30,8 +30,6 @@ export interface Vis {
[key: string]: any;
}
-export type VisProvider = (...dependencies: any[]) => Vis;
-
export interface VisParams {
[key: string]: any;
}
diff --git a/src/legacy/ui/public/vis/vis.js b/src/legacy/ui/public/vis/vis.js
index c1fff1556e3ad..304289a5cfa07 100644
--- a/src/legacy/ui/public/vis/vis.js
+++ b/src/legacy/ui/public/vis/vis.js
@@ -38,181 +38,178 @@ import { start as visualizations } from '../../../core_plugins/visualizations/pu
import '../directives/bind';
-export function VisProvider(Private, getAppState) {
- const visTypes = visualizations.types;
-
- class Vis extends EventEmitter {
- constructor(indexPattern, visState) {
- super();
- visState = visState || {};
-
- if (_.isString(visState)) {
- visState = {
- type: visState
- };
- }
- this.indexPattern = indexPattern;
- this._setUiState(new PersistedState());
- this.setCurrentState(visState);
- this.setState(this.getCurrentState(), false);
-
- // Session state is for storing information that is transitory, and will not be saved with the visualization.
- // For instance, map bounds, which depends on the view port, browser window size, etc.
- this.sessionState = {};
-
- this.API = {
- SearchSource: SearchSource,
- events: {
- filter: data => this.eventsSubject.next({ name: 'filterBucket', data }),
- brush: data => this.eventsSubject.next({ name: 'brush', data }),
- },
- getAppState,
+const visTypes = visualizations.types;
+
+class Vis extends EventEmitter {
+ constructor(indexPattern, visState) {
+ super();
+ visState = visState || {};
+
+ if (_.isString(visState)) {
+ visState = {
+ type: visState
};
}
+ this.indexPattern = indexPattern;
+ this._setUiState(new PersistedState());
+ this.setCurrentState(visState);
+ this.setState(this.getCurrentState(), false);
+
+ // Session state is for storing information that is transitory, and will not be saved with the visualization.
+ // For instance, map bounds, which depends on the view port, browser window size, etc.
+ this.sessionState = {};
+
+ this.API = {
+ SearchSource: SearchSource,
+ events: {
+ filter: data => this.eventsSubject.next({ name: 'filterBucket', data }),
+ brush: data => this.eventsSubject.next({ name: 'brush', data }),
+ },
+ };
+ }
- setCurrentState(state) {
- this.title = state.title || '';
- const type = state.type || this.type;
- if (_.isString(type)) {
- this.type = visTypes.get(type);
- if (!this.type) {
- throw new Error(`Invalid type "${type}"`);
- }
- } else {
- this.type = type;
+ setCurrentState(state) {
+ this.title = state.title || '';
+ const type = state.type || this.type;
+ if (_.isString(type)) {
+ this.type = visTypes.get(type);
+ if (!this.type) {
+ throw new Error(`Invalid type "${type}"`);
}
+ } else {
+ this.type = type;
+ }
- this.params = _.defaults({},
- _.cloneDeep(state.params || {}),
- _.cloneDeep(this.type.visConfig.defaults || {})
- );
+ this.params = _.defaults({},
+ _.cloneDeep(state.params || {}),
+ _.cloneDeep(this.type.visConfig.defaults || {})
+ );
- updateVisualizationConfig(state.params, this.params);
+ updateVisualizationConfig(state.params, this.params);
- if (state.aggs || !this.aggs) {
- this.aggs = new AggConfigs(this.indexPattern, state.aggs ? state.aggs.aggs || state.aggs : [], this.type.schemas.all);
- }
+ if (state.aggs || !this.aggs) {
+ this.aggs = new AggConfigs(this.indexPattern, state.aggs ? state.aggs.aggs || state.aggs : [], this.type.schemas.all);
}
+ }
- setState(state, updateCurrentState = true) {
- this._state = _.cloneDeep(state);
- if (updateCurrentState) {
- this.setCurrentState(this._state);
- }
+ setState(state, updateCurrentState = true) {
+ this._state = _.cloneDeep(state);
+ if (updateCurrentState) {
+ this.setCurrentState(this._state);
}
+ }
- updateState() {
- this.setState(this.getCurrentState(true));
- this.emit('update');
- }
+ updateState() {
+ this.setState(this.getCurrentState(true));
+ this.emit('update');
+ }
- forceReload() {
- this.emit('reload');
- }
+ forceReload() {
+ this.emit('reload');
+ }
- getCurrentState(includeDisabled) {
- return {
- title: this.title,
- type: this.type.name,
- params: _.cloneDeep(this.params),
- aggs: this.aggs.aggs
- .map(agg => agg.toJSON())
- .filter(agg => includeDisabled || agg.enabled)
- .filter(Boolean)
- };
- }
+ getCurrentState(includeDisabled) {
+ return {
+ title: this.title,
+ type: this.type.name,
+ params: _.cloneDeep(this.params),
+ aggs: this.aggs.aggs
+ .map(agg => agg.toJSON())
+ .filter(agg => includeDisabled || agg.enabled)
+ .filter(Boolean)
+ };
+ }
- getSerializableState(state) {
- return {
- title: state.title,
- type: state.type,
- params: _.cloneDeep(state.params),
- aggs: state.aggs.aggs
- .map(agg => agg.toJSON())
- .filter(agg => agg.enabled)
- .filter(Boolean)
- };
- }
+ getSerializableState(state) {
+ return {
+ title: state.title,
+ type: state.type,
+ params: _.cloneDeep(state.params),
+ aggs: state.aggs.aggs
+ .map(agg => agg.toJSON())
+ .filter(agg => agg.enabled)
+ .filter(Boolean)
+ };
+ }
- copyCurrentState(includeDisabled = false) {
- const state = this.getCurrentState(includeDisabled);
- state.aggs = new AggConfigs(this.indexPattern, state.aggs.aggs || state.aggs, this.type.schemas.all);
- return state;
- }
+ copyCurrentState(includeDisabled = false) {
+ const state = this.getCurrentState(includeDisabled);
+ state.aggs = new AggConfigs(this.indexPattern, state.aggs.aggs || state.aggs, this.type.schemas.all);
+ return state;
+ }
- getStateInternal(includeDisabled) {
- return {
- title: this._state.title,
- type: this._state.type,
- params: this._state.params,
- aggs: this._state.aggs
- .filter(agg => includeDisabled || agg.enabled)
- };
- }
+ getStateInternal(includeDisabled) {
+ return {
+ title: this._state.title,
+ type: this._state.type,
+ params: this._state.params,
+ aggs: this._state.aggs
+ .filter(agg => includeDisabled || agg.enabled)
+ };
+ }
- getEnabledState() {
- return this.getStateInternal(false);
- }
+ getEnabledState() {
+ return this.getStateInternal(false);
+ }
- getAggConfig() {
- return this.aggs.clone({ enabledOnly: true });
- }
+ getAggConfig() {
+ return this.aggs.clone({ enabledOnly: true });
+ }
- getState() {
- return this.getStateInternal(true);
- }
+ getState() {
+ return this.getStateInternal(true);
+ }
- isHierarchical() {
- if (_.isFunction(this.type.hierarchicalData)) {
- return !!this.type.hierarchicalData(this);
- } else {
- return !!this.type.hierarchicalData;
- }
+ isHierarchical() {
+ if (_.isFunction(this.type.hierarchicalData)) {
+ return !!this.type.hierarchicalData(this);
+ } else {
+ return !!this.type.hierarchicalData;
}
+ }
- hasSchemaAgg(schemaName, aggTypeName) {
- const aggs = this.aggs.bySchemaName(schemaName) || [];
- return aggs.some(function (agg) {
- if (!agg.type || !agg.type.name) return false;
- return agg.type.name === aggTypeName;
- });
- }
+ hasSchemaAgg(schemaName, aggTypeName) {
+ const aggs = this.aggs.bySchemaName(schemaName) || [];
+ return aggs.some(function (agg) {
+ if (!agg.type || !agg.type.name) return false;
+ return agg.type.name === aggTypeName;
+ });
+ }
- hasUiState() {
- return !!this.__uiState;
- }
+ hasUiState() {
+ return !!this.__uiState;
+ }
- /***
- * this should not be used outside of visualize
- * @param uiState
- * @private
- */
- _setUiState(uiState) {
- if (uiState instanceof PersistedState) {
- this.__uiState = uiState;
- }
+ /***
+ * this should not be used outside of visualize
+ * @param uiState
+ * @private
+ */
+ _setUiState(uiState) {
+ if (uiState instanceof PersistedState) {
+ this.__uiState = uiState;
}
+ }
- getUiState() {
- return this.__uiState;
- }
+ getUiState() {
+ return this.__uiState;
+ }
- /**
- * Currently this is only used to extract map-specific information
- * (e.g. mapZoom, mapCenter).
- */
- uiStateVal(key, val) {
- if (this.hasUiState()) {
- if (_.isUndefined(val)) {
- return this.__uiState.get(key);
- }
- return this.__uiState.set(key, val);
+ /**
+ * Currently this is only used to extract map-specific information
+ * (e.g. mapZoom, mapCenter).
+ */
+ uiStateVal(key, val) {
+ if (this.hasUiState()) {
+ if (_.isUndefined(val)) {
+ return this.__uiState.get(key);
}
- return val;
+ return this.__uiState.set(key, val);
}
+ return val;
}
+}
- Vis.prototype.type = 'histogram';
+Vis.prototype.type = 'histogram';
- return Vis;
-}
+export { Vis };
diff --git a/src/legacy/ui/public/vis/vis_types/__tests__/vislib_vis_legend.js b/src/legacy/ui/public/vis/vis_types/__tests__/vislib_vis_legend.js
index 18eef99f05a75..afb3fea15a430 100644
--- a/src/legacy/ui/public/vis/vis_types/__tests__/vislib_vis_legend.js
+++ b/src/legacy/ui/public/vis/vis_types/__tests__/vislib_vis_legend.js
@@ -21,7 +21,7 @@ import $ from 'jquery';
import _ from 'lodash';
import expect from '@kbn/expect';
import ngMock from 'ng_mock';
-import { VisProvider } from '../../vis';
+import { Vis } from '../../vis';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
describe('visualize_legend directive', function () {
@@ -29,7 +29,6 @@ describe('visualize_legend directive', function () {
let $compile;
let $timeout;
let $el;
- let Vis;
let indexPattern;
let fixtures;
@@ -39,7 +38,6 @@ describe('visualize_legend directive', function () {
$compile = $injector.get('$compile');
$timeout = $injector.get('$timeout');
fixtures = require('fixtures/fake_hierarchical_data');
- Vis = Private(VisProvider);
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
}));
diff --git a/src/legacy/ui/public/vislib/__tests__/visualizations/pie_chart.js b/src/legacy/ui/public/vislib/__tests__/visualizations/pie_chart.js
index a4f62e6ceb431..5692ae65af281 100644
--- a/src/legacy/ui/public/vislib/__tests__/visualizations/pie_chart.js
+++ b/src/legacy/ui/public/vislib/__tests__/visualizations/pie_chart.js
@@ -24,7 +24,7 @@ import _ from 'lodash';
import fixtures from 'fixtures/fake_hierarchical_data';
import $ from 'jquery';
import FixturesVislibVisFixtureProvider from 'fixtures/vislib/_vis_fixture';
-import { VisProvider } from '../../../vis';
+import { Vis } from '../../../vis';
import '../../../persisted_state';
import FixturesStubbedLogstashIndexPatternProvider from 'fixtures/stubbed_logstash_index_pattern';
import { vislibSlicesResponseHandlerProvider } from '../../../vis/response_handlers/vislib';
@@ -113,7 +113,6 @@ describe('No global chart settings', function () {
addTooltip: true
};
let chart1;
- let Vis;
let persistedState;
let indexPattern;
let responseHandler;
@@ -123,7 +122,6 @@ describe('No global chart settings', function () {
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private, $injector) {
chart1 = Private(FixturesVislibVisFixtureProvider)(visLibParams1);
- Vis = Private(VisProvider);
persistedState = new ($injector.get('PersistedState'))();
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
responseHandler = vislibSlicesResponseHandlerProvider().handler;
@@ -203,7 +201,6 @@ describe('Vislib PieChart Class Test Suite', function () {
addTooltip: true
};
let vis;
- let Vis;
let persistedState;
let indexPattern;
let data;
@@ -213,7 +210,6 @@ describe('Vislib PieChart Class Test Suite', function () {
beforeEach(ngMock.module('kibana'));
beforeEach(ngMock.inject(function (Private, $injector) {
vis = Private(FixturesVislibVisFixtureProvider)(visLibParams);
- Vis = Private(VisProvider);
persistedState = new ($injector.get('PersistedState'))();
indexPattern = Private(FixturesStubbedLogstashIndexPatternProvider);
responseHandler = vislibSlicesResponseHandlerProvider().handler;
diff --git a/src/legacy/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.ts b/src/legacy/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.ts
index 056f3e8cfc586..70e0c1f1382fa 100644
--- a/src/legacy/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.ts
+++ b/src/legacy/ui/public/visualize/loader/pipeline_helpers/build_pipeline.test.ts
@@ -172,7 +172,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => {
const visState = { ...visStateDef, params: { foo: 'bar' } };
const schemas = {
...schemasDef,
- metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }],
+ metric: [
+ { ...schemaConfig, accessor: 0 },
+ { ...schemaConfig, accessor: 1 },
+ ],
};
const actual = buildPipelineVisFunction.table(visState, schemas, uiState);
expect(actual).toMatchSnapshot();
@@ -192,7 +195,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => {
const visState = { ...visStateDef, params: { foo: 'bar' } };
const schemas = {
...schemasDef,
- metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }],
+ metric: [
+ { ...schemaConfig, accessor: 0 },
+ { ...schemaConfig, accessor: 1 },
+ ],
split_row: [2, 4],
bucket: [3],
};
@@ -250,7 +256,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => {
const visState = { ...visStateDef, params: { metric: {} } };
const schemas = {
...schemasDef,
- metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }],
+ metric: [
+ { ...schemaConfig, accessor: 0 },
+ { ...schemaConfig, accessor: 1 },
+ ],
};
const actual = buildPipelineVisFunction.metric(visState, schemas, uiState);
expect(actual).toMatchSnapshot();
@@ -260,7 +269,10 @@ describe('visualize loader pipeline helpers: build pipeline', () => {
const visState = { ...visStateDef, params: { metric: {} } };
const schemas = {
...schemasDef,
- metric: [{ ...schemaConfig, accessor: 0 }, { ...schemaConfig, accessor: 1 }],
+ metric: [
+ { ...schemaConfig, accessor: 0 },
+ { ...schemaConfig, accessor: 1 },
+ ],
group: [{ accessor: 2 }],
};
const actual = buildPipelineVisFunction.metric(visState, schemas, uiState);
diff --git a/src/legacy/ui/public/visualize/loader/utils/query_geohash_bounds.ts b/src/legacy/ui/public/visualize/loader/utils/query_geohash_bounds.ts
index 912afab74bef4..36759551a1723 100644
--- a/src/legacy/ui/public/visualize/loader/utils/query_geohash_bounds.ts
+++ b/src/legacy/ui/public/visualize/loader/utils/query_geohash_bounds.ts
@@ -22,11 +22,10 @@ import { get } from 'lodash';
import { toastNotifications } from 'ui/notify';
import { AggConfig } from 'ui/vis';
-import { Query } from 'src/legacy/core_plugins/data/public';
import { timefilter } from 'ui/timefilter';
import { Vis } from '../../../vis';
+import { esFilters, Query } from '../../../../../../plugins/data/public';
import { SearchSource } from '../../../courier';
-import { esFilters } from '../../../../../../plugins/data/public';
interface QueryGeohashBoundsParams {
filters?: esFilters.Filter[];
diff --git a/src/legacy/ui/public/visualize/loader/vis.js b/src/legacy/ui/public/visualize/loader/vis.js
index 1942fd58afebb..29208563055d0 100644
--- a/src/legacy/ui/public/visualize/loader/vis.js
+++ b/src/legacy/ui/public/visualize/loader/vis.js
@@ -33,114 +33,109 @@ import { PersistedState } from '../../persisted_state';
import { start as visualizations } from '../../../../core_plugins/visualizations/public/np_ready/public/legacy';
-export function VisProvider(getAppState) {
- const visTypes = visualizations.types;
-
- class Vis extends EventEmitter {
- constructor(visState = { type: 'histogram' }) {
- super();
-
- this._setUiState(new PersistedState());
- this.setState(visState);
-
- // Session state is for storing information that is transitory, and will not be saved with the visualization.
- // For instance, map bounds, which depends on the view port, browser window size, etc.
- this.sessionState = {};
-
- this.API = {
- events: {
- filter: data => {
- if (!this.eventsSubject) return;
- this.eventsSubject.next({ name: 'filterBucket', data });
- },
- brush: data => {
- if (!this.eventsSubject) return;
- this.eventsSubject.next({ name: 'brush', data });
- },
+const visTypes = visualizations.types;
+
+export class Vis extends EventEmitter {
+ constructor(visState = { type: 'histogram' }) {
+ super();
+
+ this._setUiState(new PersistedState());
+ this.setState(visState);
+
+ // Session state is for storing information that is transitory, and will not be saved with the visualization.
+ // For instance, map bounds, which depends on the view port, browser window size, etc.
+ this.sessionState = {};
+
+ this.API = {
+ events: {
+ filter: data => {
+ if (!this.eventsSubject) return;
+ this.eventsSubject.next({ name: 'filterBucket', data });
},
- getAppState,
- };
- }
+ brush: data => {
+ if (!this.eventsSubject) return;
+ this.eventsSubject.next({ name: 'brush', data });
+ },
+ },
+ };
+ }
- setState(state) {
- this.title = state.title || '';
- const type = state.type || this.type;
- if (_.isString(type)) {
- this.type = visTypes.get(type);
- if (!this.type) {
- throw new Error(`Invalid type "${type}"`);
- }
- } else {
- this.type = type;
+ setState(state) {
+ this.title = state.title || '';
+ const type = state.type || this.type;
+ if (_.isString(type)) {
+ this.type = visTypes.get(type);
+ if (!this.type) {
+ throw new Error(`Invalid type "${type}"`);
}
-
- this.params = _.defaultsDeep({},
- _.cloneDeep(state.params || {}),
- _.cloneDeep(this.type.visConfig.defaults || {})
- );
+ } else {
+ this.type = type;
}
- setCurrentState(state) {
- this.setState(state);
- }
+ this.params = _.defaultsDeep({},
+ _.cloneDeep(state.params || {}),
+ _.cloneDeep(this.type.visConfig.defaults || {})
+ );
+ }
- getState() {
- return {
- title: this.title,
- type: this.type.name,
- params: _.cloneDeep(this.params),
- };
- }
+ setCurrentState(state) {
+ this.setState(state);
+ }
- updateState() {
- this.emit('update');
- }
+ getState() {
+ return {
+ title: this.title,
+ type: this.type.name,
+ params: _.cloneDeep(this.params),
+ };
+ }
- forceReload() {
- this.emit('reload');
- }
+ updateState() {
+ this.emit('update');
+ }
- isHierarchical() {
- if (_.isFunction(this.type.hierarchicalData)) {
- return !!this.type.hierarchicalData(this);
- } else {
- return !!this.type.hierarchicalData;
- }
- }
+ forceReload() {
+ this.emit('reload');
+ }
- hasUiState() {
- return !!this.__uiState;
+ isHierarchical() {
+ if (_.isFunction(this.type.hierarchicalData)) {
+ return !!this.type.hierarchicalData(this);
+ } else {
+ return !!this.type.hierarchicalData;
}
+ }
- /***
- * this should not be used outside of visualize
- * @param uiState
- * @private
- */
- _setUiState(uiState) {
- if (uiState instanceof PersistedState) {
- this.__uiState = uiState;
- }
- }
+ hasUiState() {
+ return !!this.__uiState;
+ }
- getUiState() {
- return this.__uiState;
+ /***
+ * this should not be used outside of visualize
+ * @param uiState
+ * @private
+ */
+ _setUiState(uiState) {
+ if (uiState instanceof PersistedState) {
+ this.__uiState = uiState;
}
+ }
- /**
- * Currently this is only used to extract map-specific information
- * (e.g. mapZoom, mapCenter).
- */
- uiStateVal(key, val) {
- if (this.hasUiState()) {
- if (_.isUndefined(val)) {
- return this.__uiState.get(key);
- }
- return this.__uiState.set(key, val);
+ getUiState() {
+ return this.__uiState;
+ }
+
+ /**
+ * Currently this is only used to extract map-specific information
+ * (e.g. mapZoom, mapCenter).
+ */
+ uiStateVal(key, val) {
+ if (this.hasUiState()) {
+ if (_.isUndefined(val)) {
+ return this.__uiState.get(key);
}
- return val;
+ return this.__uiState.set(key, val);
}
+ return val;
}
-
- return Vis;
}
diff --git a/src/plugins/dashboard_embeddable_container/public/actions/replace_panel_flyout.tsx b/src/plugins/dashboard_embeddable_container/public/actions/replace_panel_flyout.tsx
index 02e5f45fae3bd..36efd0bcba676 100644
--- a/src/plugins/dashboard_embeddable_container/public/actions/replace_panel_flyout.tsx
+++ b/src/plugins/dashboard_embeddable_container/public/actions/replace_panel_flyout.tsx
@@ -19,15 +19,9 @@
import { i18n } from '@kbn/i18n';
import React from 'react';
-import {
- EuiFlyout,
- EuiFlyoutBody,
- EuiFlyoutHeader,
- EuiTitle,
- EuiGlobalToastListToast as Toast,
-} from '@elastic/eui';
+import { EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui';
import { DashboardPanelState } from '../embeddable';
-import { NotificationsStart } from '../../../../core/public';
+import { NotificationsStart, Toast } from '../../../../core/public';
import {
IContainer,
IEmbeddable,
diff --git a/src/plugins/dashboard_embeddable_container/public/embeddable/dashboard_container.tsx b/src/plugins/dashboard_embeddable_container/public/embeddable/dashboard_container.tsx
index 8b258f3558438..6cefd11c912f1 100644
--- a/src/plugins/dashboard_embeddable_container/public/embeddable/dashboard_container.tsx
+++ b/src/plugins/dashboard_embeddable_container/public/embeddable/dashboard_container.tsx
@@ -20,7 +20,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { I18nProvider } from '@kbn/i18n/react';
-import { RefreshInterval, TimeRange, Query } from '../../../data/public';
+import { RefreshInterval, TimeRange, Query, esFilters } from '../../../data/public';
import { CoreStart } from '../../../../core/public';
import { IUiActionsStart } from '../ui_actions_plugin';
import {
@@ -37,7 +37,6 @@ import { createPanelState } from './panel';
import { DashboardPanelState } from './types';
import { DashboardViewport } from './viewport/dashboard_viewport';
import { Start as InspectorStartContract } from '../../../inspector/public';
-import { esFilters } from '../../../../plugins/data/public';
import {
KibanaContextProvider,
KibanaReactContext,
diff --git a/src/plugins/dashboard_embeddable_container/public/plugin.tsx b/src/plugins/dashboard_embeddable_container/public/plugin.tsx
index eadf70a36416a..dbb5a06da9cd9 100644
--- a/src/plugins/dashboard_embeddable_container/public/plugin.tsx
+++ b/src/plugins/dashboard_embeddable_container/public/plugin.tsx
@@ -61,9 +61,10 @@ export class DashboardEmbeddableContainerPublicPlugin
const { application, notifications, overlays } = core;
const { embeddable, inspector, uiActions } = plugins;
- const SavedObjectFinder: React.FC<
- Exclude
- > = props => (
+ const SavedObjectFinder: React.FC> = props => (
string);
params?: any;
+ value?: string | ((formatter?: FilterValueFormatter) => string);
}
export interface Filter {
diff --git a/src/plugins/data/public/query/filter_manager/index.ts b/src/plugins/data/public/query/filter_manager/index.ts
index 7955cdd825ee6..ce7a479151797 100644
--- a/src/plugins/data/public/query/filter_manager/index.ts
+++ b/src/plugins/data/public/query/filter_manager/index.ts
@@ -22,3 +22,4 @@ export { FilterManager } from './filter_manager';
export { uniqFilters } from './lib/uniq_filters';
export { mapAndFlattenFilters } from './lib/map_and_flatten_filters';
export { onlyDisabledFiltersChanged } from './lib/only_disabled';
+export { generateFilters } from './lib/generate_filters';
diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts b/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts
new file mode 100644
index 0000000000000..46cf0fd9c111e
--- /dev/null
+++ b/src/plugins/data/public/query/filter_manager/lib/generate_filter.test.ts
@@ -0,0 +1,130 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { generateFilters } from './generate_filters';
+import { FilterManager } from '../filter_manager';
+import { esFilters } from '../../..';
+
+const INDEX_NAME = 'my-index';
+const EXISTS_FIELD_NAME = '_exists_';
+const FIELD = {
+ name: 'my-field',
+};
+const PHRASE_VALUE = 'my-value';
+
+describe('Generate filters', () => {
+ let mockFilterManager: FilterManager;
+ let filtersArray: esFilters.Filter[];
+
+ beforeEach(() => {
+ filtersArray = [];
+ mockFilterManager = {
+ getAppFilters: () => {
+ return filtersArray;
+ },
+ } as FilterManager;
+ });
+
+ it('should create exists filter', () => {
+ const filters = generateFilters(
+ mockFilterManager,
+ EXISTS_FIELD_NAME,
+ FIELD.name,
+ '',
+ INDEX_NAME
+ );
+ expect(filters).toHaveLength(1);
+ expect(filters[0].meta.index === INDEX_NAME);
+ expect(filters[0].meta.negate).toBeFalsy();
+ expect(esFilters.isExistsFilter(filters[0])).toBeTruthy();
+ });
+
+ it('should create negated exists filter', () => {
+ const filters = generateFilters(
+ mockFilterManager,
+ EXISTS_FIELD_NAME,
+ FIELD.name,
+ '-',
+ INDEX_NAME
+ );
+ expect(filters).toHaveLength(1);
+ expect(filters[0].meta.index === INDEX_NAME);
+ expect(filters[0].meta.negate).toBeTruthy();
+ expect(esFilters.isExistsFilter(filters[0])).toBeTruthy();
+ });
+
+ it('should update and re-enable EXISTING exists filter', () => {
+ const filter = esFilters.buildExistsFilter(FIELD, { id: INDEX_NAME });
+ filter.meta.disabled = true;
+ filtersArray.push(filter);
+
+ const filters = generateFilters(mockFilterManager, '_exists_', FIELD.name, '-', INDEX_NAME);
+ expect(filters).toHaveLength(1);
+ expect(filters[0].meta.index === INDEX_NAME);
+ expect(filters[0].meta.negate).toBeTruthy();
+ expect(filters[0].meta.disabled).toBeFalsy();
+ expect(esFilters.isExistsFilter(filters[0])).toBeTruthy();
+ });
+
+ it('should create phrase filter', () => {
+ const filters = generateFilters(mockFilterManager, FIELD, PHRASE_VALUE, '', INDEX_NAME);
+ expect(filters).toHaveLength(1);
+ expect(filters[0].meta.index === INDEX_NAME);
+ expect(filters[0].meta.negate).toBeFalsy();
+ expect(esFilters.isPhraseFilter(filters[0])).toBeTruthy();
+ expect((filters[0] as esFilters.PhraseFilter).query.match_phrase).toEqual({
+ [FIELD.name]: PHRASE_VALUE,
+ });
+ });
+
+ it('should create negated phrase filter', () => {
+ const filters = generateFilters(mockFilterManager, FIELD, PHRASE_VALUE, '-', INDEX_NAME);
+ expect(filters).toHaveLength(1);
+ expect(filters[0].meta.index === INDEX_NAME);
+ expect(filters[0].meta.negate).toBeTruthy();
+ expect(esFilters.isPhraseFilter(filters[0])).toBeTruthy();
+ expect((filters[0] as esFilters.PhraseFilter).query.match_phrase).toEqual({
+ [FIELD.name]: PHRASE_VALUE,
+ });
+ });
+
+ it('should create multiple phrase filters', () => {
+ const ANOTHER_PHRASE = 'another-value';
+ const filters = generateFilters(
+ mockFilterManager,
+ FIELD,
+ [PHRASE_VALUE, ANOTHER_PHRASE],
+ '',
+ INDEX_NAME
+ );
+ expect(filters).toHaveLength(2);
+ expect(filters[0].meta.index === INDEX_NAME);
+ expect(filters[0].meta.negate).toBeFalsy();
+ expect(filters[1].meta.index === INDEX_NAME);
+ expect(filters[1].meta.negate).toBeFalsy();
+ expect(esFilters.isPhraseFilter(filters[0])).toBeTruthy();
+ expect(esFilters.isPhraseFilter(filters[1])).toBeTruthy();
+ expect((filters[0] as esFilters.PhraseFilter).query.match_phrase).toEqual({
+ [FIELD.name]: PHRASE_VALUE,
+ });
+ expect((filters[1] as esFilters.PhraseFilter).query.match_phrase).toEqual({
+ [FIELD.name]: ANOTHER_PHRASE,
+ });
+ });
+});
diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts b/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts
new file mode 100644
index 0000000000000..5c4cdc2717338
--- /dev/null
+++ b/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts
@@ -0,0 +1,112 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import _ from 'lodash';
+import { FilterManager, esFilters, Field } from '../../..';
+
+function getExistingFilter(
+ appFilters: esFilters.Filter[],
+ fieldName: string,
+ value: any
+): esFilters.Filter | undefined {
+ // TODO: On array fields, negating does not negate the combination, rather all terms
+ return _.find(appFilters, function(filter) {
+ if (!filter) return;
+
+ if (fieldName === '_exists_' && esFilters.isExistsFilter(filter)) {
+ return filter.exists!.field === value;
+ }
+
+ if (esFilters.isPhraseFilter(filter)) {
+ return (
+ esFilters.getPhraseFilterField(filter) === fieldName &&
+ esFilters.getPhraseFilterValue(filter) === value
+ );
+ }
+
+ if (esFilters.isScriptedPhraseFilter(filter)) {
+ return filter.meta.field === fieldName && filter.meta.script!.script.params.value === value;
+ }
+ });
+}
+
+function updateExistingFilter(existingFilter: esFilters.Filter, negate: boolean) {
+ existingFilter.meta.disabled = false;
+ if (existingFilter.meta.negate !== negate) {
+ existingFilter.meta.negate = !existingFilter.meta.negate;
+ }
+}
+
+/**
+ * Generate filter objects, as a result of triggering a filter action on a
+ * specific index pattern field.
+ *
+ * @param {FilterManager} filterManager - The active filter manager to lookup for existing filters
+ * @param {Field | string} field - The field for which filters should be generated
+ * @param {any} values - One or more values to filter for.
+ * @param {string} operation - "-" to create a negated filter
+ * @param {string} index - Index string to generate filters for
+ *
+ * @returns {object} An array of filters to be added back to filterManager
+ */
+export function generateFilters(
+ filterManager: FilterManager,
+ field: Field | string,
+ values: any,
+ operation: string,
+ index: string
+): esFilters.Filter[] {
+ values = Array.isArray(values) ? values : [values];
+ const fieldObj = _.isObject(field)
+ ? field
+ : {
+ name: field,
+ };
+ const fieldName = fieldObj.name;
+ const newFilters: esFilters.Filter[] = [];
+ const appFilters = filterManager.getAppFilters();
+
+ const negate = operation === '-';
+ let filter;
+
+ _.each(values, function(value) {
+ const existing = getExistingFilter(appFilters, fieldName, value);
+
+ if (existing) {
+ updateExistingFilter(existing, negate);
+ filter = existing;
+ } else {
+ const tmpIndexPattern = { id: index };
+ switch (fieldName) {
+ case '_exists_':
+ filter = esFilters.buildExistsFilter(fieldObj, tmpIndexPattern);
+ break;
+ default:
+ filter = esFilters.buildPhraseFilter(fieldObj, value, tmpIndexPattern);
+ break;
+ }
+
+ filter.meta.negate = negate;
+ }
+
+ newFilters.push(filter);
+ });
+
+ return newFilters;
+}
diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.test.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.test.ts
index 3afa3891a24bb..1847296016c73 100644
--- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.test.ts
+++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_geo_polygon.test.ts
@@ -30,7 +30,10 @@ describe('filter manager utilities', () => {
},
geo_polygon: {
point: {
- points: [{ lat: 5, lon: 10 }, { lat: 15, lon: 20 }],
+ points: [
+ { lat: 5, lon: 10 },
+ { lat: 15, lon: 20 },
+ ],
},
},
} as esFilters.GeoPolygonFilter;
diff --git a/src/plugins/data/public/query/index.tsx b/src/plugins/data/public/query/index.tsx
index 9d7c2ffc56f70..224c2f3a04076 100644
--- a/src/plugins/data/public/query/index.tsx
+++ b/src/plugins/data/public/query/index.tsx
@@ -17,6 +17,8 @@
* under the License.
*/
+export * from './lib';
+
export * from './query_service';
export * from './filter_manager';
diff --git a/src/plugins/data/public/query/lib/from_user.test.ts b/src/plugins/data/public/query/lib/from_user.test.ts
new file mode 100644
index 0000000000000..b74a1a07dc356
--- /dev/null
+++ b/src/plugins/data/public/query/lib/from_user.test.ts
@@ -0,0 +1,45 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { fromUser } from '../';
+
+describe('user input helpers', function() {
+ describe('user input parser', function() {
+ it('should return the input if passed an object', function() {
+ expect(fromUser({ foo: 'bar' })).toEqual({ foo: 'bar' });
+ });
+
+ it('unless the object is empty, then convert it to an empty string', function() {
+ expect(fromUser({})).toEqual('');
+ });
+
+ it('should pass through input strings that not start with {', function() {
+ expect(fromUser('foo')).toEqual('foo');
+ expect(fromUser('400')).toEqual('400');
+ expect(fromUser('true')).toEqual('true');
+ });
+
+ it('should parse valid JSON and return the object instead of a string', function() {
+ expect(fromUser('{}')).toEqual({});
+
+ // invalid json remains a string
+ expect(fromUser('{a:b}')).toEqual('{a:b}');
+ });
+ });
+});
diff --git a/src/legacy/core_plugins/data/public/query/query_bar/lib/from_user.ts b/src/plugins/data/public/query/lib/from_user.ts
similarity index 96%
rename from src/legacy/core_plugins/data/public/query/query_bar/lib/from_user.ts
rename to src/plugins/data/public/query/lib/from_user.ts
index 15eebaa0b9fd6..fbb1726fc99ea 100644
--- a/src/legacy/core_plugins/data/public/query/query_bar/lib/from_user.ts
+++ b/src/plugins/data/public/query/lib/from_user.ts
@@ -28,6 +28,10 @@ import _ from 'lodash';
export function fromUser(userInput: object | string) {
const matchAll = '';
+ if (_.isEmpty(userInput)) {
+ return '';
+ }
+
if (_.isObject(userInput)) {
return userInput;
}
diff --git a/src/legacy/core_plugins/data/public/query/query_bar/lib/get_query_log.ts b/src/plugins/data/public/query/lib/get_query_log.ts
similarity index 94%
rename from src/legacy/core_plugins/data/public/query/query_bar/lib/get_query_log.ts
rename to src/plugins/data/public/query/lib/get_query_log.ts
index 66424d9a1d6a3..67073a9078046 100644
--- a/src/legacy/core_plugins/data/public/query/query_bar/lib/get_query_log.ts
+++ b/src/plugins/data/public/query/lib/get_query_log.ts
@@ -19,7 +19,7 @@
import { UiSettingsClientContract } from 'src/core/public';
import { IStorageWrapper } from 'src/plugins/kibana_utils/public';
-import { PersistedLog } from '../../../../../../../plugins/data/public';
+import { PersistedLog } from '../persisted_log';
export function getQueryLog(
uiSettings: UiSettingsClientContract,
diff --git a/src/legacy/core_plugins/data/public/query/query_bar/lib/index.ts b/src/plugins/data/public/query/lib/index.ts
similarity index 93%
rename from src/legacy/core_plugins/data/public/query/query_bar/lib/index.ts
rename to src/plugins/data/public/query/lib/index.ts
index 852f9fd269b32..19ac37fb59ae7 100644
--- a/src/legacy/core_plugins/data/public/query/query_bar/lib/index.ts
+++ b/src/plugins/data/public/query/lib/index.ts
@@ -20,3 +20,5 @@
export * from './match_pairs';
export * from './from_user';
export * from './to_user';
+export * from './to_user';
+export * from './get_query_log';
diff --git a/src/legacy/core_plugins/data/public/query/query_bar/lib/match_pairs.ts b/src/plugins/data/public/query/lib/match_pairs.ts
similarity index 100%
rename from src/legacy/core_plugins/data/public/query/query_bar/lib/match_pairs.ts
rename to src/plugins/data/public/query/lib/match_pairs.ts
diff --git a/src/plugins/data/public/query/lib/to_user.test.ts b/src/plugins/data/public/query/lib/to_user.test.ts
new file mode 100644
index 0000000000000..d13afa251ecb1
--- /dev/null
+++ b/src/plugins/data/public/query/lib/to_user.test.ts
@@ -0,0 +1,46 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { toUser } from '../';
+
+describe('user input helpers', function() {
+ describe('model presentation formatter', function() {
+ it('should present objects as strings', function() {
+ expect(toUser({ foo: 'bar' })).toBe('{"foo":"bar"}');
+ });
+
+ it('should present query_string queries as strings', function() {
+ expect(toUser({ query_string: { query: 'lucene query string' } })).toBe(
+ 'lucene query string'
+ );
+ });
+
+ it('should present query_string queries without a query as an empty string', function() {
+ expect(toUser({ query_string: {} })).toBe('');
+ });
+
+ it('should present string as strings', function() {
+ expect(toUser('foo')).toBe('foo');
+ });
+
+ it('should present numbers as strings', function() {
+ expect(toUser(400)).toBe('400');
+ });
+ });
+});
diff --git a/src/legacy/core_plugins/data/public/query/query_bar/lib/to_user.ts b/src/plugins/data/public/query/lib/to_user.ts
similarity index 89%
rename from src/legacy/core_plugins/data/public/query/query_bar/lib/to_user.ts
rename to src/plugins/data/public/query/lib/to_user.ts
index 1eb054ba40514..1fdb2d8ed03df 100644
--- a/src/legacy/core_plugins/data/public/query/query_bar/lib/to_user.ts
+++ b/src/plugins/data/public/query/lib/to_user.ts
@@ -17,14 +17,12 @@
* under the License.
*/
-import angular from 'angular';
-
/**
* Take text from the model and present it to the user as a string
* @param text model value
* @returns {string}
*/
-export function toUser(text: { [key: string]: any } | string): string {
+export function toUser(text: { [key: string]: any } | string | number): string {
if (text == null) {
return '';
}
@@ -35,7 +33,7 @@ export function toUser(text: { [key: string]: any } | string): string {
if (text.query_string) {
return toUser(text.query_string.query);
}
- return angular.toJson(text);
+ return JSON.stringify(text);
}
return '' + text;
}
diff --git a/src/plugins/data/public/search/create_app_mount_context_search.test.ts b/src/plugins/data/public/search/create_app_mount_context_search.test.ts
index deab9af4e3a01..fa7cdbcda3082 100644
--- a/src/plugins/data/public/search/create_app_mount_context_search.test.ts
+++ b/src/plugins/data/public/search/create_app_mount_context_search.test.ts
@@ -62,8 +62,10 @@ describe('Create app mount search context', () => {
});
},
});
- context
- .search({ greeting: 'hi' } as any, {}, 'mysearch')
- .subscribe(response => {}, () => {}, done);
+ context.search({ greeting: 'hi' } as any, {}, 'mysearch').subscribe(
+ response => {},
+ () => {},
+ done
+ );
});
});
diff --git a/src/plugins/data/public/search/es_search/es_search_strategy.ts b/src/plugins/data/public/search/es_search/es_search_strategy.ts
index 643ded120799e..d29f3b6882b26 100644
--- a/src/plugins/data/public/search/es_search/es_search_strategy.ts
+++ b/src/plugins/data/public/search/es_search/es_search_strategy.ts
@@ -20,6 +20,7 @@
import { Observable } from 'rxjs';
import { ES_SEARCH_STRATEGY, IEsSearchResponse } from '../../../common/search';
import { SYNC_SEARCH_STRATEGY } from '../sync_search_strategy';
+import { getEsPreference } from './get_es_preference';
import { TSearchStrategyProvider, ISearchStrategy, ISearchGeneric, ISearchContext } from '..';
export const esSearchStrategyProvider: TSearchStrategyProvider = (
@@ -27,11 +28,17 @@ export const esSearchStrategyProvider: TSearchStrategyProvider => {
return {
- search: (request, options) =>
- search(
+ search: (request, options) => {
+ if (typeof request.params.preference === 'undefined') {
+ const setPreference = context.core.uiSettings.get('courier:setRequestPreference');
+ const customPreference = context.core.uiSettings.get('courier:customRequestPreference');
+ request.params.preference = getEsPreference(setPreference, customPreference);
+ }
+ return search(
{ ...request, serverStrategy: ES_SEARCH_STRATEGY },
options,
SYNC_SEARCH_STRATEGY
- ) as Observable,
+ ) as Observable;
+ },
};
};
diff --git a/src/plugins/data/public/search/es_search/get_es_preference.test.ts b/src/plugins/data/public/search/es_search/get_es_preference.test.ts
new file mode 100644
index 0000000000000..27e6f9b48bbdd
--- /dev/null
+++ b/src/plugins/data/public/search/es_search/get_es_preference.test.ts
@@ -0,0 +1,46 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { getEsPreference } from './get_es_preference';
+
+jest.useFakeTimers();
+
+describe('Get ES preference', () => {
+ test('returns the session ID if set to sessionId', () => {
+ const setPreference = 'sessionId';
+ const customPreference = 'foobar';
+ const sessionId = 'my_session_id';
+ const preference = getEsPreference(setPreference, customPreference, sessionId);
+ expect(preference).toBe(sessionId);
+ });
+
+ test('returns the custom preference if set to custom', () => {
+ const setPreference = 'custom';
+ const customPreference = 'foobar';
+ const preference = getEsPreference(setPreference, customPreference);
+ expect(preference).toBe(customPreference);
+ });
+
+ test('returns undefined if set to none', () => {
+ const setPreference = 'none';
+ const customPreference = 'foobar';
+ const preference = getEsPreference(setPreference, customPreference);
+ expect(preference).toBe(undefined);
+ });
+});
diff --git a/src/legacy/ui/public/registry/dev_tools.js b/src/plugins/data/public/search/es_search/get_es_preference.ts
similarity index 70%
rename from src/legacy/ui/public/registry/dev_tools.js
rename to src/plugins/data/public/search/es_search/get_es_preference.ts
index 1741f39f86375..200e5bacb7f18 100644
--- a/src/legacy/ui/public/registry/dev_tools.js
+++ b/src/plugins/data/public/search/es_search/get_es_preference.ts
@@ -17,11 +17,13 @@
* under the License.
*/
-import { uiRegistry } from './_registry';
-
-export const DevToolsRegistryProvider = uiRegistry({
- name: 'devTools',
- index: ['name'],
- order: ['order']
-});
+const defaultSessionId = `${Date.now()}`;
+export function getEsPreference(
+ setRequestPreference: string,
+ customRequestPreference?: string,
+ sessionId: string = defaultSessionId
+) {
+ if (setRequestPreference === 'sessionId') return `${sessionId}`;
+ return setRequestPreference === 'custom' ? customRequestPreference : undefined;
+}
diff --git a/src/plugins/dev_tools/README.md b/src/plugins/dev_tools/README.md
new file mode 100644
index 0000000000000..1610411b9c98e
--- /dev/null
+++ b/src/plugins/dev_tools/README.md
@@ -0,0 +1,29 @@
+# Dev tools plugin
+
+The ui/registry/dev_tools is removed in favor of the `dev_tools` plugin which exposes a register method in the setup contract.
+Registering app works mostly the same as registering apps in core.application.register.
+Routing will be handled by the id of the dev tool - your dev tool will be mounted when the URL matches `/app/kibana#/dev_tools/`.
+This API doesn't support angular, for registering angular dev tools, bootstrap a local module on mount into the given HTML element.
+
+During the migration this plugin exposes the registered dev tools in the start contract. This is necessary to keep the dev tools app
+which is still living in the legacy platform working and will be removed once everything is moved over to the new platform. It should
+not be used by other plugins.
+
+## Example registration
+
+```ts
+// For legacy plugins
+import { npSetup } from 'ui/new_platform';
+npSetup.plugins.dev_tools.register(/* same details here */);
+
+// For new plugins: first add 'dev_tools' to the list of `optionalPlugins`
+// in your kibana.json file. Then access the plugin directly in `setup`:
+
+class MyPlugin {
+ setup(core, plugins) {
+ if (plugins.dev_tools) {
+ plugins.dev_tools.register(/* same details here. */);
+ }
+ }
+}
+```
diff --git a/src/plugins/dev_tools/kibana.json b/src/plugins/dev_tools/kibana.json
new file mode 100644
index 0000000000000..307035c7ec664
--- /dev/null
+++ b/src/plugins/dev_tools/kibana.json
@@ -0,0 +1,6 @@
+{
+ "id": "devTools",
+ "version": "kibana",
+ "server": false,
+ "ui": true
+}
diff --git a/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/actions/filter.js b/src/plugins/dev_tools/public/index.ts
similarity index 77%
rename from src/legacy/core_plugins/kibana/public/discover/angular/doc_table/actions/filter.js
rename to src/plugins/dev_tools/public/index.ts
index 1a2854ec15412..3a0d1455e2168 100644
--- a/src/legacy/core_plugins/kibana/public/discover/angular/doc_table/actions/filter.js
+++ b/src/plugins/dev_tools/public/index.ts
@@ -17,10 +17,11 @@
* under the License.
*/
-export function addFilter(field, values = [], operation, index, state, filterGen) {
- if (!Array.isArray(values)) {
- values = [values];
- }
+import { PluginInitializerContext } from 'kibana/public';
+import { DevToolsPlugin } from './plugin';
- filterGen.add(field, values, operation, index);
+export function plugin(initializerContext: PluginInitializerContext) {
+ return new DevToolsPlugin();
}
+
+export * from './plugin';
diff --git a/src/plugins/dev_tools/public/plugin.ts b/src/plugins/dev_tools/public/plugin.ts
new file mode 100644
index 0000000000000..8098308c0882b
--- /dev/null
+++ b/src/plugins/dev_tools/public/plugin.ts
@@ -0,0 +1,115 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import { App, CoreSetup, Plugin } from 'kibana/public';
+import { sortBy } from 'lodash';
+
+export interface DevToolsSetup {
+ /**
+ * Register a developer tool. It will be available
+ * in the dev tools app under a separate tab.
+ *
+ * Registering dev tools works almost similar to registering
+ * applications in the core application service,
+ * but they will be rendered with a frame containing tabs
+ * to switch between the tools.
+ * @param devTool The dev tools descriptor
+ */
+ register: (devTool: DevTool) => void;
+}
+
+export interface DevToolsStart {
+ /**
+ * Returns all registered dev tools in an ordered array.
+ * This function is only exposed because the dev tools app
+ * actually rendering the tool has to stay in the legacy platform
+ * for now. Once it is moved into this plugin, this function
+ * becomes an implementation detail.
+ * @deprecated
+ */
+ getSortedDevTools: () => readonly DevTool[];
+}
+
+/**
+ * Descriptor for a dev tool. A dev tool works similar to an application
+ * registered in the core application service.
+ */
+export interface DevTool {
+ /**
+ * The id of the dev tools. This will become part of the URL path
+ * (`dev_tools/${devTool.id}`. It has to be unique among registered
+ * dev tools.
+ */
+ id: string;
+ /**
+ * The human readable name of the dev tool. Should be internationalized.
+ * This will be used as a label in the tab above the actual tool.
+ */
+ title: string;
+ mount: App['mount'];
+ /**
+ * Flag indicating to disable the tab of this dev tool. Navigating to a
+ * disabled dev tool will be treated as the navigation to an unknown route
+ * (redirect to the console).
+ */
+ disabled?: boolean;
+ /**
+ * Optional tooltip content of the tab.
+ */
+ tooltipContent?: string;
+ /**
+ * Flag indicating whether the dev tool will do routing within the `dev_tools/${devTool.id}/`
+ * prefix. If it is set to true, the dev tool is responsible to redirect
+ * the user when navigating to unknown URLs within the prefix. If set
+ * to false only the root URL of the dev tool will be recognized as valid.
+ */
+ enableRouting: boolean;
+ /**
+ * Number used to order the tabs.
+ */
+ order: number;
+}
+
+export class DevToolsPlugin implements Plugin {
+ private readonly devTools = new Map();
+
+ private getSortedDevTools(): readonly DevTool[] {
+ return sortBy([...this.devTools.values()], 'order');
+ }
+
+ public setup(core: CoreSetup) {
+ return {
+ register: (devTool: DevTool) => {
+ if (this.devTools.has(devTool.id)) {
+ throw new Error(
+ `Dev tool with id [${devTool.id}] has already been registered. Use a unique id.`
+ );
+ }
+
+ this.devTools.set(devTool.id, devTool);
+ },
+ };
+ }
+
+ public start() {
+ return {
+ getSortedDevTools: this.getSortedDevTools.bind(this),
+ };
+ }
+}
diff --git a/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx b/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx
index b11bd167e15f2..70d7c99d3fb9d 100644
--- a/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx
+++ b/src/plugins/embeddable/public/tests/customize_panel_modal.test.tsx
@@ -173,7 +173,7 @@ test('Can set title to an empty string', async () => {
);
const inputField = findTestSubject(component, 'customizePanelHideTitle');
- inputField.simulate('change');
+ inputField.simulate('click');
findTestSubject(component, 'saveNewTitleButton').simulate('click');
expect(inputField.props().value).toBeUndefined();
diff --git a/src/plugins/es_ui_shared/static/forms/components/fields/toggle_field.tsx b/src/plugins/es_ui_shared/static/forms/components/fields/toggle_field.tsx
index 417f3436a2c63..0c075c497a4d0 100644
--- a/src/plugins/es_ui_shared/static/forms/components/fields/toggle_field.tsx
+++ b/src/plugins/es_ui_shared/static/forms/components/fields/toggle_field.tsx
@@ -18,7 +18,7 @@
*/
import React from 'react';
-import { EuiFormRow, EuiSwitch } from '@elastic/eui';
+import { EuiFormRow, EuiSwitch, EuiSwitchEvent } from '@elastic/eui';
import { FieldHook } from '../../hook_form_lib';
import { getFieldValidityAndErrorMessage } from '../helpers';
@@ -33,6 +33,14 @@ interface Props {
export const ToggleField = ({ field, euiFieldProps = {}, ...rest }: Props) => {
const { isInvalid, errorMessage } = getFieldValidityAndErrorMessage(field);
+ // Shim for sufficient overlap between EuiSwitchEvent and FieldHook[onChange] event
+ const onChange = (e: EuiSwitchEvent) => {
+ const event = ({ ...e, value: `${e.target.checked}` } as unknown) as React.ChangeEvent<{
+ value: string;
+ }>;
+ field.onChange(event);
+ };
+
return (
{
diff --git a/src/plugins/es_ui_shared/static/forms/helpers/serializers.ts b/src/plugins/es_ui_shared/static/forms/helpers/serializers.ts
index e288f61de8681..0bb89cc1af593 100644
--- a/src/plugins/es_ui_shared/static/forms/helpers/serializers.ts
+++ b/src/plugins/es_ui_shared/static/forms/helpers/serializers.ts
@@ -69,24 +69,21 @@ export const stripEmptyFields = (
): { [key: string]: any } => {
const { types = ['string', 'object'], recursive = false } = options || {};
- return Object.entries(object).reduce(
- (acc, [key, value]) => {
- const type = typeof value;
- const shouldStrip = types.includes(type as 'string');
+ return Object.entries(object).reduce((acc, [key, value]) => {
+ const type = typeof value;
+ const shouldStrip = types.includes(type as 'string');
- if (shouldStrip && type === 'string' && value.trim() === '') {
+ if (shouldStrip && type === 'string' && value.trim() === '') {
+ return acc;
+ } else if (type === 'object' && !Array.isArray(value) && value !== null) {
+ if (Object.keys(value).length === 0 && shouldStrip) {
return acc;
- } else if (type === 'object' && !Array.isArray(value) && value !== null) {
- if (Object.keys(value).length === 0 && shouldStrip) {
- return acc;
- } else if (recursive) {
- value = stripEmptyFields({ ...value }, options);
- }
+ } else if (recursive) {
+ value = stripEmptyFields({ ...value }, options);
}
+ }
- acc[key] = value;
- return acc;
- },
- {} as { [key: string]: any }
- );
+ acc[key] = value;
+ return acc;
+ }, {} as { [key: string]: any });
};
diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts
index 360182368ae63..3902b0615a33d 100644
--- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts
+++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/hooks/use_form.ts
@@ -65,15 +65,12 @@ export function useForm(
const stripEmptyFields = (fields: FieldsMap): FieldsMap => {
if (formOptions.stripEmptyFields) {
- return Object.entries(fields).reduce(
- (acc, [key, field]) => {
- if (typeof field.value !== 'string' || field.value.trim() !== '') {
- acc[key] = field;
- }
- return acc;
- },
- {} as FieldsMap
- );
+ return Object.entries(fields).reduce((acc, [key, field]) => {
+ if (typeof field.value !== 'string' || field.value.trim() !== '') {
+ acc[key] = field;
+ }
+ return acc;
+ }, {} as FieldsMap);
}
return fields;
};
diff --git a/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts b/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts
index 66c3e8d983f98..62867a0c07a6b 100644
--- a/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts
+++ b/src/plugins/es_ui_shared/static/forms/hook_form_lib/lib/utils.ts
@@ -50,10 +50,7 @@ export const mapFormFields = (
formFields: Record,
fn: (field: FieldHook) => any
) =>
- Object.entries(formFields).reduce(
- (acc, [key, field]) => {
- acc[key] = fn(field);
- return acc;
- },
- {} as Record
- );
+ Object.entries(formFields).reduce((acc, [key, field]) => {
+ acc[key] = fn(field);
+ return acc;
+ }, {} as Record);
diff --git a/src/plugins/expressions/public/interpreter_provider.ts b/src/plugins/expressions/public/interpreter_provider.ts
index cb84370ad69c5..15d6b1c025f54 100644
--- a/src/plugins/expressions/public/interpreter_provider.ts
+++ b/src/plugins/expressions/public/interpreter_provider.ts
@@ -163,9 +163,9 @@ export function interpreterProvider(config: InterpreterConfig): ExpressionInterp
// Check for missing required arguments
each(argDefs, argDef => {
- const { aliases, default: argDefault, name: argName, required } = argDef as (ArgumentType<
+ const { aliases, default: argDefault, name: argName, required } = argDef as ArgumentType<
any
- > & { name: string });
+ > & { name: string };
if (
typeof argDefault === 'undefined' &&
required &&
diff --git a/src/plugins/expressions/public/types/index.ts b/src/plugins/expressions/public/types/index.ts
index 87ef810682f60..faceef4f90a6f 100644
--- a/src/plugins/expressions/public/types/index.ts
+++ b/src/plugins/expressions/public/types/index.ts
@@ -21,8 +21,6 @@ import { ExpressionInterpret } from '../interpreter_provider';
import { TimeRange } from '../../../data/public';
import { Adapters } from '../../../inspector/public';
import { Query } from '../../../data/public';
-import { ExpressionAST } from '../../../expressions/public';
-import { ExpressionArgAST } from '../../../../plugins/expressions/public';
import { esFilters } from '../../../../plugins/data/public';
export { ArgumentType } from './arguments';
diff --git a/src/plugins/kibana_react/public/context/context.tsx b/src/plugins/kibana_react/public/context/context.tsx
index cbae5c4638ca2..cbf2ad07b463e 100644
--- a/src/plugins/kibana_react/public/context/context.tsx
+++ b/src/plugins/kibana_react/public/context/context.tsx
@@ -32,12 +32,11 @@ const defaultContextValue = {
export const context = createContext>(defaultContextValue);
-export const useKibana = (): KibanaReactContextValue<
- KibanaServices & Extra
-> =>
- useContext((context as unknown) as React.Context<
- KibanaReactContextValue
- >);
+export const useKibana = (): KibanaReactContextValue =>
+ useContext(
+ (context as unknown) as React.Context>
+ );
export const withKibana = }>(
type: React.ComponentType
diff --git a/src/plugins/kibana_react/public/index.ts b/src/plugins/kibana_react/public/index.ts
index cf025ec2e88d4..2d82f646c827b 100644
--- a/src/plugins/kibana_react/public/index.ts
+++ b/src/plugins/kibana_react/public/index.ts
@@ -24,3 +24,4 @@ export * from './overlays';
export * from './ui_settings';
export * from './field_icon';
export * from './table_list_view';
+export { toMountPoint } from './util';
diff --git a/src/plugins/kibana_react/public/notifications/create_notifications.test.tsx b/src/plugins/kibana_react/public/notifications/create_notifications.test.tsx
index 35c503d590b2c..4f64a2b95f512 100644
--- a/src/plugins/kibana_react/public/notifications/create_notifications.test.tsx
+++ b/src/plugins/kibana_react/public/notifications/create_notifications.test.tsx
@@ -52,9 +52,20 @@ test('can display string element as title', () => {
wrapper.toasts.show({ title: 'foo' });
expect(notifications.toasts.add).toHaveBeenCalledTimes(1);
- expect(notifications.toasts.add.mock.calls[0][0]).toMatchObject({
- title: 'foo',
- });
+ expect(notifications.toasts.add.mock.calls[0][0]).toMatchInlineSnapshot(`
+ Object {
+ "color": undefined,
+ "iconType": undefined,
+ "onClose": undefined,
+ "text": MountPoint {
+ "reactNode": ,
+ },
+ "title": MountPoint {
+ "reactNode": "foo",
+ },
+ "toastLifeTimeMs": undefined,
+ }
+ `);
});
test('can display React element as title', () => {
@@ -67,10 +78,12 @@ test('can display React element as title', () => {
expect(notifications.toasts.add).toHaveBeenCalledTimes(1);
expect((notifications.toasts.add.mock.calls[0][0] as any).title).toMatchInlineSnapshot(`
-
- bar
-
- `);
+ MountPoint {
+ "reactNode":
+ bar
+
,
+ }
+ `);
});
test('can display React element as toast body', () => {
@@ -81,12 +94,14 @@ test('can display React element as toast body', () => {
expect(notifications.toasts.add).toHaveBeenCalledTimes(1);
expect((notifications.toasts.add.mock.calls[0][0] as any).text).toMatchInlineSnapshot(`
-
-
- baz
-
-
- `);
+ MountPoint {
+ "reactNode":
+
+ baz
+
+ ,
+ }
+ `);
});
test('can set toast properties', () => {
@@ -102,17 +117,21 @@ test('can set toast properties', () => {
});
expect(notifications.toasts.add.mock.calls[0][0]).toMatchInlineSnapshot(`
- Object {
- "color": "danger",
- "iconType": "foo",
- "onClose": undefined,
- "text":
- 1
- ,
- "title": "2",
- "toastLifeTimeMs": 3,
- }
- `);
+ Object {
+ "color": "danger",
+ "iconType": "foo",
+ "onClose": undefined,
+ "text": MountPoint {
+ "reactNode":
+ 1
+ ,
+ },
+ "title": MountPoint {
+ "reactNode": "2",
+ },
+ "toastLifeTimeMs": 3,
+ }
+ `);
});
test('can display success, warning and danger toasts', () => {
@@ -124,21 +143,48 @@ test('can display success, warning and danger toasts', () => {
wrapper.toasts.danger({ title: '3' });
expect(notifications.toasts.add).toHaveBeenCalledTimes(3);
- expect(notifications.toasts.add.mock.calls[0][0]).toMatchObject({
- title: '1',
- color: 'success',
- iconType: 'check',
- });
- expect(notifications.toasts.add.mock.calls[1][0]).toMatchObject({
- title: '2',
- color: 'warning',
- iconType: 'help',
- });
- expect(notifications.toasts.add.mock.calls[2][0]).toMatchObject({
- title: '3',
- color: 'danger',
- iconType: 'alert',
- });
+ expect(notifications.toasts.add.mock.calls[0][0]).toMatchInlineSnapshot(`
+ Object {
+ "color": "success",
+ "iconType": "check",
+ "onClose": undefined,
+ "text": MountPoint {
+ "reactNode": ,
+ },
+ "title": MountPoint {
+ "reactNode": "1",
+ },
+ "toastLifeTimeMs": undefined,
+ }
+ `);
+ expect(notifications.toasts.add.mock.calls[1][0]).toMatchInlineSnapshot(`
+ Object {
+ "color": "warning",
+ "iconType": "help",
+ "onClose": undefined,
+ "text": MountPoint {
+ "reactNode": ,
+ },
+ "title": MountPoint {
+ "reactNode": "2",
+ },
+ "toastLifeTimeMs": undefined,
+ }
+ `);
+ expect(notifications.toasts.add.mock.calls[2][0]).toMatchInlineSnapshot(`
+ Object {
+ "color": "danger",
+ "iconType": "alert",
+ "onClose": undefined,
+ "text": MountPoint {
+ "reactNode": ,
+ },
+ "title": MountPoint {
+ "reactNode": "3",
+ },
+ "toastLifeTimeMs": undefined,
+ }
+ `);
});
test('if body is not set, renders it empty', () => {
@@ -147,7 +193,9 @@ test('if body is not set, renders it empty', () => {
wrapper.toasts.success({ title: '1' });
- expect((notifications.toasts.add.mock.calls[0][0] as any).text).toMatchInlineSnapshot(
- ``
- );
+ expect((notifications.toasts.add.mock.calls[0][0] as any).text).toMatchInlineSnapshot(`
+ MountPoint {
+ "reactNode": ,
+ }
+ `);
});
diff --git a/src/plugins/kibana_react/public/notifications/create_notifications.tsx b/src/plugins/kibana_react/public/notifications/create_notifications.tsx
index 28c1d5391d160..774f74863ee6f 100644
--- a/src/plugins/kibana_react/public/notifications/create_notifications.tsx
+++ b/src/plugins/kibana_react/public/notifications/create_notifications.tsx
@@ -20,6 +20,7 @@
import * as React from 'react';
import { KibanaServices } from '../context/types';
import { KibanaReactNotifications } from './types';
+import { toMountPoint } from '../util';
export const createNotifications = (services: KibanaServices): KibanaReactNotifications => {
const show: KibanaReactNotifications['toasts']['show'] = ({
@@ -34,8 +35,8 @@ export const createNotifications = (services: KibanaServices): KibanaReactNotifi
throw new TypeError('Could not show notification as notifications service is not available.');
}
services.notifications!.toasts.add({
- title,
- text: <>{body || null}>,
+ title: toMountPoint(title),
+ text: toMountPoint(<>{body || null}>),
color,
iconType,
toastLifeTimeMs,
diff --git a/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx b/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx
index e1e7f1c536342..bab710cdca595 100644
--- a/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx
+++ b/src/plugins/kibana_react/public/saved_objects/saved_object_save_modal.tsx
@@ -32,6 +32,7 @@ import {
EuiOverlayMask,
EuiSpacer,
EuiSwitch,
+ EuiSwitchEvent,
EuiTextArea,
} from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
@@ -227,7 +228,7 @@ export class SavedObjectSaveModal extends React.Component {
});
};
- private onCopyOnSaveChange = (event: React.ChangeEvent) => {
+ private onCopyOnSaveChange = (event: EuiSwitchEvent) => {
this.setState({
copyOnSave: event.target.checked,
});
diff --git a/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx b/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx
index 7d95c00e76419..dde8efa7e1106 100644
--- a/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx
+++ b/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx
@@ -38,6 +38,7 @@ import {
EuiCallOut,
} from '@elastic/eui';
import { ToastsStart, UiSettingsClientContract } from 'kibana/public';
+import { toMountPoint } from '../util';
export const EMPTY_FILTER = '';
@@ -166,7 +167,7 @@ class TableListView extends React.Component itemsById[id]));
} catch (error) {
this.props.toastNotifications.addDanger({
- title: (
+ title: toMountPoint(
{
+ const mount = (element: HTMLElement) => {
+ ReactDOM.render({node}, element);
+ return () => ReactDOM.unmountComponentAtNode(element);
+ };
+ // only used for tests and snapshots serialization
+ if (process.env.NODE_ENV !== 'production') {
+ mount.__reactMount__ = node;
}
-}
-
-uiModules.get('kibana').run(hideEmptyDevTools);
+ return mount;
+};
diff --git a/src/plugins/kibana_react/public/util/test_helpers/react_mount_serializer.ts b/src/plugins/kibana_react/public/util/test_helpers/react_mount_serializer.ts
new file mode 100644
index 0000000000000..45ad4cb407175
--- /dev/null
+++ b/src/plugins/kibana_react/public/util/test_helpers/react_mount_serializer.ts
@@ -0,0 +1,30 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+export function test(value: any) {
+ return value && value.__reactMount__;
+}
+
+export function print(value: any, serialize: any) {
+ // there is no proper way to correctly indent multiline values
+ // so the trick here is to use the Object representation and rewriting the root object name
+ return serialize({
+ reactNode: value.__reactMount__,
+ }).replace('Object', 'MountPoint');
+}
diff --git a/src/plugins/newsfeed/public/lib/api.test.ts b/src/plugins/newsfeed/public/lib/api.test.ts
index b9707ff91b936..4383b9e0f7dab 100644
--- a/src/plugins/newsfeed/public/lib/api.test.ts
+++ b/src/plugins/newsfeed/public/lib/api.test.ts
@@ -631,10 +631,7 @@ describe('getApi', () => {
.mockImplementationOnce(getHttpMockWithItems(successItems));
getApi(httpMock, configMock.newsfeed, '6.8.2')
- .pipe(
- take(4),
- toArray()
- )
+ .pipe(take(4), toArray())
.subscribe(result => {
expect(result).toMatchInlineSnapshot(`
Array [
diff --git a/test/functional/apps/discover/_shared_links.js b/test/functional/apps/discover/_shared_links.js
index f0d34207a87a2..0b2b4f14f126d 100644
--- a/test/functional/apps/discover/_shared_links.js
+++ b/test/functional/apps/discover/_shared_links.js
@@ -25,11 +25,12 @@ export default function ({ getService, getPageObjects }) {
const esArchiver = getService('esArchiver');
const kibanaServer = getService('kibanaServer');
const PageObjects = getPageObjects(['common', 'discover', 'share', 'timePicker']);
+ const browser = getService('browser');
describe('shared links', function describeIndexTests() {
let baseUrl;
- before(async function () {
+ async function setup({ storeStateInSessionStorage }) {
baseUrl = PageObjects.common.getHostPort();
log.debug('baseUrl = ' + baseUrl);
// browsers don't show the ':port' if it's 80 or 443 so we have to
@@ -47,9 +48,12 @@ export default function ({ getService, getPageObjects }) {
log.debug('load kibana index with default index pattern');
await esArchiver.load('discover');
-
await esArchiver.loadIfNeeded('logstash_functional');
+ await kibanaServer.uiSettings.replace({
+ 'state:storeInSessionStorage': storeStateInSessionStorage
+ });
+
log.debug('discover');
await PageObjects.common.navigateToApp('discover');
@@ -60,47 +64,103 @@ export default function ({ getService, getPageObjects }) {
await PageObjects.common.sleep(1000);
await PageObjects.share.clickShareTopNavButton();
- });
- describe('permalink', function () {
- it('should allow for copying the snapshot URL', async function () {
- const expectedUrl =
- baseUrl +
- '/app/kibana?_t=1453775307251#' +
- '/discover?_g=(refreshInterval:(pause:!t,value:0),time' +
- ':(from:\'2015-09-19T06:31:44.000Z\',to:\'2015-09' +
- '-23T18:31:44.000Z\'))&_a=(columns:!(_source),index:\'logstash-' +
- '*\',interval:auto,query:(language:kuery,query:\'\')' +
- ',sort:!(!(\'@timestamp\',desc)))';
- const actualUrl = await PageObjects.share.getSharedUrl();
- // strip the timestamp out of each URL
- expect(actualUrl.replace(/_t=\d{13}/, '_t=TIMESTAMP')).to.be(
- expectedUrl.replace(/_t=\d{13}/, '_t=TIMESTAMP')
- );
+ return async () => {
+ await kibanaServer.uiSettings.replace({
+ 'state:storeInSessionStorage': undefined
+ });
+ };
+ }
+
+ describe('shared links with state in query', async () => {
+ let teardown;
+ before(async function () {
+ teardown = await setup({ storeStateInSessionStorage: false });
+ });
+
+ after(async function () {
+ await teardown();
});
- it('should allow for copying the snapshot URL as a short URL', async function () {
- const re = new RegExp(baseUrl + '/goto/[0-9a-f]{32}$');
- await PageObjects.share.checkShortenUrl();
- await retry.try(async () => {
+ describe('permalink', function () {
+ it('should allow for copying the snapshot URL', async function () {
+ const expectedUrl =
+ baseUrl +
+ '/app/kibana?_t=1453775307251#' +
+ '/discover?_g=(refreshInterval:(pause:!t,value:0),time' +
+ ':(from:\'2015-09-19T06:31:44.000Z\',to:\'2015-09' +
+ '-23T18:31:44.000Z\'))&_a=(columns:!(_source),index:\'logstash-' +
+ '*\',interval:auto,query:(language:kuery,query:\'\')' +
+ ',sort:!(!(\'@timestamp\',desc)))';
+ const actualUrl = await PageObjects.share.getSharedUrl();
+ // strip the timestamp out of each URL
+ expect(actualUrl.replace(/_t=\d{13}/, '_t=TIMESTAMP')).to.be(
+ expectedUrl.replace(/_t=\d{13}/, '_t=TIMESTAMP')
+ );
+ });
+
+ it('should allow for copying the snapshot URL as a short URL', async function () {
+ const re = new RegExp(baseUrl + '/goto/[0-9a-f]{32}$');
+ await PageObjects.share.checkShortenUrl();
+ await retry.try(async () => {
+ const actualUrl = await PageObjects.share.getSharedUrl();
+ expect(actualUrl).to.match(re);
+ });
+ });
+
+ it('should allow for copying the saved object URL', async function () {
+ const expectedUrl =
+ baseUrl +
+ '/app/kibana#' +
+ '/discover/ab12e3c0-f231-11e6-9486-733b1ac9221a' +
+ '?_g=(refreshInterval%3A(pause%3A!t%2Cvalue%3A0)' +
+ '%2Ctime%3A(from%3A\'2015-09-19T06%3A31%3A44.000Z\'%2C' +
+ 'to%3A\'2015-09-23T18%3A31%3A44.000Z\'))';
+ await PageObjects.discover.loadSavedSearch('A Saved Search');
+ await PageObjects.share.clickShareTopNavButton();
+ await PageObjects.share.exportAsSavedObject();
const actualUrl = await PageObjects.share.getSharedUrl();
- expect(actualUrl).to.match(re);
+ expect(actualUrl).to.be(expectedUrl);
});
});
+ });
+
+ describe('shared links with state in sessionStorage', async () => {
+ let teardown;
+ before(async function () {
+ teardown = await setup({ storeStateInSessionStorage: true });
+ });
- it('should allow for copying the saved object URL', async function () {
- const expectedUrl =
- baseUrl +
- '/app/kibana#' +
- '/discover/ab12e3c0-f231-11e6-9486-733b1ac9221a' +
- '?_g=(refreshInterval%3A(pause%3A!t%2Cvalue%3A0)' +
- '%2Ctime%3A(from%3A\'2015-09-19T06%3A31%3A44.000Z\'%2C' +
- 'to%3A\'2015-09-23T18%3A31%3A44.000Z\'))';
- await PageObjects.discover.loadSavedSearch('A Saved Search');
- await PageObjects.share.clickShareTopNavButton();
- await PageObjects.share.exportAsSavedObject();
- const actualUrl = await PageObjects.share.getSharedUrl();
- expect(actualUrl).to.be(expectedUrl);
+ after(async function () {
+ await teardown();
+ });
+
+ describe('permalink', function () {
+ it('should allow for copying the snapshot URL as a short URL and should open it', async function () {
+ const re = new RegExp(baseUrl + '/goto/[0-9a-f]{32}$');
+ await PageObjects.share.checkShortenUrl();
+ let actualUrl;
+ await retry.try(async () => {
+ actualUrl = await PageObjects.share.getSharedUrl();
+ expect(actualUrl).to.match(re);
+ });
+
+ const actualTime = await PageObjects.timePicker.getTimeConfig();
+
+ await browser.clearSessionStorage();
+ await browser.get(actualUrl, false);
+ await retry.waitFor(
+ 'shortUrl resolves and opens',
+ async () => {
+ const resolvedUrl = await browser.getCurrentUrl();
+ expect(resolvedUrl).to.match(/discover/);
+ const resolvedTime = await PageObjects.timePicker.getTimeConfig();
+ expect(resolvedTime.start).to.equal(actualTime.start);
+ expect(resolvedTime.end).to.equal(actualTime.end);
+ return true;
+ }
+ );
+ });
});
});
});
diff --git a/test/functional/apps/visualize/input_control_vis/input_control_options.js b/test/functional/apps/visualize/input_control_vis/input_control_options.js
index b659d29b158b7..4088ab6193a59 100644
--- a/test/functional/apps/visualize/input_control_vis/input_control_options.js
+++ b/test/functional/apps/visualize/input_control_vis/input_control_options.js
@@ -133,13 +133,13 @@ export default function ({ getService, getPageObjects }) {
describe('updateFiltersOnChange is true', () => {
before(async () => {
await PageObjects.visualize.clickVisEditorTab('options');
- await PageObjects.visualize.checkCheckbox('inputControlEditorUpdateFiltersOnChangeCheckbox');
+ await PageObjects.visualize.checkSwitch('inputControlEditorUpdateFiltersOnChangeCheckbox');
await PageObjects.visualize.clickGo();
});
after(async () => {
await PageObjects.visualize.clickVisEditorTab('options');
- await PageObjects.visualize.uncheckCheckbox('inputControlEditorUpdateFiltersOnChangeCheckbox');
+ await PageObjects.visualize.uncheckSwitch('inputControlEditorUpdateFiltersOnChangeCheckbox');
await PageObjects.visualize.clickGo();
});
diff --git a/test/functional/page_objects/dashboard_page.js b/test/functional/page_objects/dashboard_page.js
index ca141114f976d..af3a15e9b3015 100644
--- a/test/functional/page_objects/dashboard_page.js
+++ b/test/functional/page_objects/dashboard_page.js
@@ -347,7 +347,7 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
async clickSave() {
log.debug('DashboardPage.clickSave');
- await testSubjects.clickWhenNotDisabled('confirmSaveSavedObjectButton');
+ await testSubjects.click('confirmSaveSavedObjectButton');
}
async pressEnterKey() {
@@ -543,9 +543,10 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
async setSaveAsNewCheckBox(checked) {
log.debug('saveAsNewCheckbox: ' + checked);
const saveAsNewCheckbox = await testSubjects.find('saveAsNewCheckbox');
- const isAlreadyChecked = (await saveAsNewCheckbox.getAttribute('checked') === 'true');
+ const isAlreadyChecked = (await saveAsNewCheckbox.getAttribute('aria-checked') === 'true');
if (isAlreadyChecked !== checked) {
log.debug('Flipping save as new checkbox');
+ const saveAsNewCheckbox = await testSubjects.find('saveAsNewCheckbox');
await retry.try(() => saveAsNewCheckbox.click());
}
}
@@ -553,9 +554,10 @@ export function DashboardPageProvider({ getService, getPageObjects }) {
async setStoreTimeWithDashboard(checked) {
log.debug('Storing time with dashboard: ' + checked);
const storeTimeCheckbox = await testSubjects.find('storeTimeWithDashboard');
- const isAlreadyChecked = (await storeTimeCheckbox.getAttribute('checked') === 'true');
+ const isAlreadyChecked = (await storeTimeCheckbox.getAttribute('aria-checked') === 'true');
if (isAlreadyChecked !== checked) {
log.debug('Flipping store time checkbox');
+ const storeTimeCheckbox = await testSubjects.find('storeTimeWithDashboard');
await retry.try(() => storeTimeCheckbox.click());
}
}
diff --git a/test/functional/page_objects/visual_builder_page.ts b/test/functional/page_objects/visual_builder_page.ts
index 570511bee4bc5..4b65de57f12d8 100644
--- a/test/functional/page_objects/visual_builder_page.ts
+++ b/test/functional/page_objects/visual_builder_page.ts
@@ -305,9 +305,9 @@ export function VisualBuilderPageProvider({ getService, getPageObjects }: FtrPro
public async getRhythmChartLegendValue(nth = 0) {
await PageObjects.visualize.waitForVisualizationRenderingStabilized();
- const metricValue = (await find.allByCssSelector(
- `.echLegendItem .echLegendItem__displayValue`
- ))[nth];
+ const metricValue = (
+ await find.allByCssSelector(`.echLegendItem .echLegendItem__displayValue`)
+ )[nth];
await metricValue.moveMouseTo();
return await metricValue.getVisibleText();
}
diff --git a/test/functional/page_objects/visualize_page.js b/test/functional/page_objects/visualize_page.js
index f3a90f20b6686..81d26a4b69478 100644
--- a/test/functional/page_objects/visualize_page.js
+++ b/test/functional/page_objects/visualize_page.js
@@ -372,6 +372,28 @@ export function VisualizePageProvider({ getService, getPageObjects, updateBaseli
}
}
+ async isSwitchChecked(selector) {
+ const checkbox = await testSubjects.find(selector);
+ const isChecked = await checkbox.getAttribute('aria-checked');
+ return isChecked === 'true';
+ }
+
+ async checkSwitch(selector) {
+ const isChecked = await this.isSwitchChecked(selector);
+ if (!isChecked) {
+ log.debug(`checking switch ${selector}`);
+ await testSubjects.click(selector);
+ }
+ }
+
+ async uncheckSwitch(selector) {
+ const isChecked = await this.isSwitchChecked(selector);
+ if (isChecked) {
+ log.debug(`unchecking switch ${selector}`);
+ await testSubjects.click(selector);
+ }
+ }
+
async setSelectByOptionText(selectId, optionText) {
const selectField = await find.byCssSelector(`#${selectId}`);
const options = await find.allByCssSelector(`#${selectId} > option`);
@@ -1009,7 +1031,7 @@ export function VisualizePageProvider({ getService, getPageObjects, updateBaseli
async setIsFilteredByCollarCheckbox(value = true) {
await retry.try(async () => {
- const isChecked = await this.isChecked('isFilteredByCollarCheckbox');
+ const isChecked = await this.isSwitchChecked('isFilteredByCollarCheckbox');
if (isChecked !== value) {
await testSubjects.click('isFilteredByCollarCheckbox');
throw new Error('isFilteredByCollar not set correctly');
diff --git a/test/functional/services/browser.ts b/test/functional/services/browser.ts
index 97e02958f3787..a8ce4270d4205 100644
--- a/test/functional/services/browser.ts
+++ b/test/functional/services/browser.ts
@@ -429,6 +429,15 @@ export async function BrowserProvider({ getService }: FtrProviderContext) {
);
}
+ /**
+ * Clears session storage for the focused window/frame.
+ *
+ * @return {Promise}
+ */
+ public async clearSessionStorage(): Promise {
+ await driver.executeScript('return window.sessionStorage.clear();');
+ }
+
/**
* Closes the currently focused window. In most environments, after the window has been
* closed, it is necessary to explicitly switch to whatever window is now focused.
diff --git a/test/functional/services/remote/poll_for_log_entry.ts b/test/functional/services/remote/poll_for_log_entry.ts
index b6b68cc0d3cf9..71e2711906fce 100644
--- a/test/functional/services/remote/poll_for_log_entry.ts
+++ b/test/functional/services/remote/poll_for_log_entry.ts
@@ -95,10 +95,7 @@ export function pollForLogEntry$(
[new logging.Entry('SEVERE', `ERROR FETCHING BROWSR LOGS: ${error.message}`)],
// pause 10 seconds then resubscribe
- Rx.of(1).pipe(
- delay(10 * 1000),
- mergeMapTo(resubscribe)
- )
+ Rx.of(1).pipe(delay(10 * 1000), mergeMapTo(resubscribe))
);
})
)
diff --git a/test/functional/services/saved_query_management_component.ts b/test/functional/services/saved_query_management_component.ts
index f134fde028e09..d6de0be0c172e 100644
--- a/test/functional/services/saved_query_management_component.ts
+++ b/test/functional/services/saved_query_management_component.ts
@@ -118,15 +118,17 @@ export function SavedQueryManagementComponentProvider({ getService }: FtrProvide
await testSubjects.setValue('saveQueryFormDescription', description);
const currentIncludeFiltersValue =
- (await testSubjects.getAttribute('saveQueryFormIncludeFiltersOption', 'checked')) ===
+ (await testSubjects.getAttribute('saveQueryFormIncludeFiltersOption', 'aria-checked')) ===
'true';
if (currentIncludeFiltersValue !== includeFilters) {
await testSubjects.click('saveQueryFormIncludeFiltersOption');
}
const currentIncludeTimeFilterValue =
- (await testSubjects.getAttribute('saveQueryFormIncludeTimeFilterOption', 'checked')) ===
- 'true';
+ (await testSubjects.getAttribute(
+ 'saveQueryFormIncludeTimeFilterOption',
+ 'aria-checked'
+ )) === 'true';
if (currentIncludeTimeFilterValue !== includeTimeFilter) {
await testSubjects.click('saveQueryFormIncludeTimeFilterOption');
}
diff --git a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json
index 766e6168002c2..da1bb597f5730 100644
--- a/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json
+++ b/test/interpreter_functional/plugins/kbn_tp_run_pipeline/package.json
@@ -7,7 +7,7 @@
},
"license": "Apache-2.0",
"dependencies": {
- "@elastic/eui": "14.8.0",
+ "@elastic/eui": "14.9.0",
"react": "^16.8.0",
"react-dom": "^16.8.0"
}
diff --git a/test/plugin_functional/plugins/core_plugin_a/package.json b/test/plugin_functional/plugins/core_plugin_a/package.json
index 7dede34f3c0cf..060ae49f43e8a 100644
--- a/test/plugin_functional/plugins/core_plugin_a/package.json
+++ b/test/plugin_functional/plugins/core_plugin_a/package.json
@@ -12,6 +12,6 @@
"build": "rm -rf './target' && tsc"
},
"devDependencies": {
- "typescript": "3.5.3"
+ "typescript": "3.7.2"
}
}
diff --git a/test/plugin_functional/plugins/core_plugin_b/package.json b/test/plugin_functional/plugins/core_plugin_b/package.json
index 18ff8cf7cc5c9..3eb878b9ed5dc 100644
--- a/test/plugin_functional/plugins/core_plugin_b/package.json
+++ b/test/plugin_functional/plugins/core_plugin_b/package.json
@@ -12,6 +12,6 @@
"build": "rm -rf './target' && tsc"
},
"devDependencies": {
- "typescript": "3.5.3"
+ "typescript": "3.7.2"
}
}
diff --git a/test/plugin_functional/plugins/core_plugin_chromeless/kibana.json b/test/plugin_functional/plugins/core_plugin_chromeless/kibana.json
new file mode 100644
index 0000000000000..a8a5616627726
--- /dev/null
+++ b/test/plugin_functional/plugins/core_plugin_chromeless/kibana.json
@@ -0,0 +1,8 @@
+{
+ "id": "core_plugin_chromeless",
+ "version": "0.0.1",
+ "kibanaVersion": "kibana",
+ "configPath": ["core_plugin_chromeless"],
+ "server": false,
+ "ui": true
+}
diff --git a/test/plugin_functional/plugins/core_plugin_chromeless/package.json b/test/plugin_functional/plugins/core_plugin_chromeless/package.json
new file mode 100644
index 0000000000000..eff6c1e1f142a
--- /dev/null
+++ b/test/plugin_functional/plugins/core_plugin_chromeless/package.json
@@ -0,0 +1,17 @@
+{
+ "name": "core_plugin_chromeless",
+ "version": "1.0.0",
+ "main": "target/test/plugin_functional/plugins/core_plugin_chromeless",
+ "kibana": {
+ "version": "kibana",
+ "templateVersion": "1.0.0"
+ },
+ "license": "Apache-2.0",
+ "scripts": {
+ "kbn": "node ../../../../scripts/kbn.js",
+ "build": "rm -rf './target' && tsc"
+ },
+ "devDependencies": {
+ "typescript": "3.5.3"
+ }
+}
diff --git a/test/plugin_functional/plugins/core_plugin_chromeless/public/application.tsx b/test/plugin_functional/plugins/core_plugin_chromeless/public/application.tsx
new file mode 100644
index 0000000000000..556a9ca140715
--- /dev/null
+++ b/test/plugin_functional/plugins/core_plugin_chromeless/public/application.tsx
@@ -0,0 +1,74 @@
+/*
+ * Licensed to Elasticsearch B.V. under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch B.V. licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import React from 'react';
+import { render, unmountComponentAtNode } from 'react-dom';
+import { BrowserRouter as Router, Route } from 'react-router-dom';
+import {
+ EuiPage,
+ EuiPageBody,
+ EuiPageContent,
+ EuiPageContentBody,
+ EuiPageContentHeader,
+ EuiPageContentHeaderSection,
+ EuiPageHeader,
+ EuiPageHeaderSection,
+ EuiTitle,
+} from '@elastic/eui';
+
+import { AppMountContext, AppMountParameters } from 'kibana/public';
+
+const Home = () => (
+
+
+
+
+ Welcome to Chromeless!
+
+
+
+
+
+
+
+ Chromeless home page section title
+
+
+
+ Where did all the chrome go?
+
+
+);
+
+const ChromelessApp = ({ basename }: { basename: string; context: AppMountContext }) => (
+
+
+
+
+
+);
+
+export const renderApp = (
+ context: AppMountContext,
+ { appBasePath, element }: AppMountParameters
+) => {
+ render(, element);
+
+ return () => unmountComponentAtNode(element);
+};
diff --git a/src/legacy/core_plugins/console/public/quarantined/hacks/register.js b/test/plugin_functional/plugins/core_plugin_chromeless/public/index.ts
similarity index 70%
rename from src/legacy/core_plugins/console/public/quarantined/hacks/register.js
rename to test/plugin_functional/plugins/core_plugin_chromeless/public/index.ts
index b5df1c1af99c5..6e9959ecbdf9e 100644
--- a/src/legacy/core_plugins/console/public/quarantined/hacks/register.js
+++ b/test/plugin_functional/plugins/core_plugin_chromeless/public/index.ts
@@ -17,14 +17,14 @@
* under the License.
*/
-import { DevToolsRegistryProvider } from 'ui/registry/dev_tools';
-import { i18n } from '@kbn/i18n';
+import { PluginInitializer } from 'kibana/public';
+import {
+ CorePluginChromelessPlugin,
+ CorePluginChromelessPluginSetup,
+ CorePluginChromelessPluginStart,
+} from './plugin';
-DevToolsRegistryProvider.register(() => ({
- order: 1,
- name: 'console',
- display: i18n.translate('console.consoleDisplayName', {
- defaultMessage: 'Console',
- }),
- url: '#/dev_tools/console',
-}));
+export const plugin: PluginInitializer<
+ CorePluginChromelessPluginSetup,
+ CorePluginChromelessPluginStart
+> = () => new CorePluginChromelessPlugin();
diff --git a/src/legacy/core_plugins/kibana/public/dev_tools/directives/dev_tools_app.js b/test/plugin_functional/plugins/core_plugin_chromeless/public/plugin.tsx
similarity index 51%
rename from src/legacy/core_plugins/kibana/public/dev_tools/directives/dev_tools_app.js
rename to test/plugin_functional/plugins/core_plugin_chromeless/public/plugin.tsx
index c7cb877be676b..03870410fb334 100644
--- a/src/legacy/core_plugins/kibana/public/dev_tools/directives/dev_tools_app.js
+++ b/test/plugin_functional/plugins/core_plugin_chromeless/public/plugin.tsx
@@ -17,34 +17,31 @@
* under the License.
*/
-import { uiModules } from 'ui/modules';
-import { DevToolsRegistryProvider } from 'ui/registry/dev_tools';
-import template from '../partials/dev_tools_app.html';
+import { Plugin, CoreSetup } from 'kibana/public';
-uiModules
- .get('apps/dev_tools')
- .directive('kbnDevToolsApp', function (Private, $location) {
- const devToolsRegistry = Private(DevToolsRegistryProvider);
+export class CorePluginChromelessPlugin
+ implements Plugin {
+ public setup(core: CoreSetup, deps: {}) {
+ core.application.register({
+ id: 'chromeless',
+ title: 'Chromeless',
+ chromeless: true,
+ async mount(context, params) {
+ const { renderApp } = await import('./application');
+ return renderApp(context, params);
+ },
+ });
return {
- restrict: 'E',
- replace: true,
- template,
- transclude: true,
- scope: {
- topNavConfig: '='
+ getGreeting() {
+ return 'Hello from Plugin Chromeless!';
},
- bindToController: true,
- controllerAs: 'kbnDevToolsApp',
- controller() {
- this.devTools = devToolsRegistry.inOrder;
- this.currentPath = `#${$location.path()}`;
-
- this.onClick = (item, $event) => {
- if (item.disabled) {
- $event.preventDefault();
- }
- };
- }
};
- });
+ }
+
+ public start() {}
+ public stop() {}
+}
+
+export type CorePluginChromelessPluginSetup = ReturnType;
+export type CorePluginChromelessPluginStart = ReturnType;
diff --git a/test/plugin_functional/plugins/core_plugin_chromeless/tsconfig.json b/test/plugin_functional/plugins/core_plugin_chromeless/tsconfig.json
new file mode 100644
index 0000000000000..5fcaeafbb0d85
--- /dev/null
+++ b/test/plugin_functional/plugins/core_plugin_chromeless/tsconfig.json
@@ -0,0 +1,14 @@
+{
+ "extends": "../../../../tsconfig.json",
+ "compilerOptions": {
+ "outDir": "./target",
+ "skipLibCheck": true
+ },
+ "include": [
+ "index.ts",
+ "public/**/*.ts",
+ "public/**/*.tsx",
+ "../../../../typings/**/*",
+ ],
+ "exclude": []
+}
diff --git a/test/plugin_functional/plugins/core_plugin_legacy/package.json b/test/plugin_functional/plugins/core_plugin_legacy/package.json
index 2ae83b28f7e85..5f784c7b836a5 100644
--- a/test/plugin_functional/plugins/core_plugin_legacy/package.json
+++ b/test/plugin_functional/plugins/core_plugin_legacy/package.json
@@ -12,6 +12,6 @@
"build": "rm -rf './target' && tsc"
},
"devDependencies": {
- "typescript": "3.5.3"
+ "typescript": "3.7.2"
}
}
diff --git a/test/plugin_functional/plugins/demo_search/public/demo_search_strategy.ts b/test/plugin_functional/plugins/demo_search/public/demo_search_strategy.ts
index 377163251010c..298eaaaf420e0 100644
--- a/test/plugin_functional/plugins/demo_search/public/demo_search_strategy.ts
+++ b/test/plugin_functional/plugins/demo_search/public/demo_search_strategy.ts
@@ -53,9 +53,7 @@ import { DEMO_SEARCH_STRATEGY, IDemoResponse } from '../common';
* @param context - context supplied by other plugins.
* @param search - a search function to access other strategies that have already been registered.
*/
-export const demoClientSearchStrategyProvider: TSearchStrategyProvider<
- typeof DEMO_SEARCH_STRATEGY
-> = (
+export const demoClientSearchStrategyProvider: TSearchStrategyProvider = (
context: ISearchContext,
search: ISearchGeneric
): ISearchStrategy => {
diff --git a/test/plugin_functional/plugins/demo_search/server/demo_search_strategy.ts b/test/plugin_functional/plugins/demo_search/server/demo_search_strategy.ts
index acb75b15196d6..d3f2360add6c0 100644
--- a/test/plugin_functional/plugins/demo_search/server/demo_search_strategy.ts
+++ b/test/plugin_functional/plugins/demo_search/server/demo_search_strategy.ts
@@ -20,9 +20,7 @@
import { TSearchStrategyProvider } from 'src/plugins/data/server';
import { DEMO_SEARCH_STRATEGY } from '../common';
-export const demoSearchStrategyProvider: TSearchStrategyProvider<
- typeof DEMO_SEARCH_STRATEGY
-> = () => {
+export const demoSearchStrategyProvider: TSearchStrategyProvider = () => {
return {
search: request => {
return Promise.resolve({
diff --git a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json
index 7c5b6f6be58af..4d0444265825a 100644
--- a/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json
+++ b/test/plugin_functional/plugins/kbn_tp_custom_visualizations/package.json
@@ -7,7 +7,7 @@
},
"license": "Apache-2.0",
"dependencies": {
- "@elastic/eui": "14.8.0",
+ "@elastic/eui": "14.9.0",
"react": "^16.8.0"
}
}
diff --git a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/package.json b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/package.json
index ef472b4026957..9df9352f76fc2 100644
--- a/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/package.json
+++ b/test/plugin_functional/plugins/kbn_tp_embeddable_explorer/package.json
@@ -8,7 +8,7 @@
},
"license": "Apache-2.0",
"dependencies": {
- "@elastic/eui": "14.8.0",
+ "@elastic/eui": "14.9.0",
"react": "^16.8.0"
},
"scripts": {
@@ -17,6 +17,6 @@
},
"devDependencies": {
"@kbn/plugin-helpers": "9.0.2",
- "typescript": "3.5.3"
+ "typescript": "3.7.2"
}
}
diff --git a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json
index 277bb09ac745c..054276b620907 100644
--- a/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json
+++ b/test/plugin_functional/plugins/kbn_tp_sample_panel_action/package.json
@@ -8,7 +8,7 @@
},
"license": "Apache-2.0",
"dependencies": {
- "@elastic/eui": "14.8.0",
+ "@elastic/eui": "14.9.0",
"react": "^16.8.0"
},
"scripts": {
@@ -17,6 +17,6 @@
},
"devDependencies": {
"@kbn/plugin-helpers": "9.0.2",
- "typescript": "3.5.3"
+ "typescript": "3.7.2"
}
}
diff --git a/test/plugin_functional/test_suites/core_plugins/applications.ts b/test/plugin_functional/test_suites/core_plugins/applications.ts
index eec2ec019a515..c16847dab9dc2 100644
--- a/test/plugin_functional/test_suites/core_plugins/applications.ts
+++ b/test/plugin_functional/test_suites/core_plugins/applications.ts
@@ -91,6 +91,22 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider
await testSubjects.existOrFail('fooAppPageA');
});
+ it('chromeless applications are not visible in apps list', async () => {
+ expect(await appsMenu.linkExists('Chromeless')).to.be(false);
+ });
+
+ it('navigating to chromeless application hides chrome', async () => {
+ await PageObjects.common.navigateToApp('chromeless');
+ await loadingScreenNotShown();
+ expect(await testSubjects.exists('headerGlobalNav')).to.be(false);
+ });
+
+ it('navigating away from chromeless application shows chrome', async () => {
+ await PageObjects.common.navigateToApp('foo');
+ await loadingScreenNotShown();
+ expect(await testSubjects.exists('headerGlobalNav')).to.be(true);
+ });
+
it('can navigate from NP apps to legacy apps', async () => {
await appsMenu.clickLink('Management');
await loadingScreenShown();
diff --git a/x-pack/dev-tools/jest/create_jest_config.js b/x-pack/dev-tools/jest/create_jest_config.js
index 0fba7d2cefbd5..9d601e680cf87 100644
--- a/x-pack/dev-tools/jest/create_jest_config.js
+++ b/x-pack/dev-tools/jest/create_jest_config.js
@@ -47,7 +47,10 @@ export function createJestConfig({ kibanaDirectory, xPackKibanaDirectory }) {
// since ESM modules are not natively supported in Jest yet (https://github.com/facebook/jest/issues/4842)
'[/\\\\]node_modules(?![\\/\\\\]@elastic[\\/\\\\]eui)(?![\\/\\\\]monaco-editor)[/\\\\].+\\.js$',
],
- snapshotSerializers: [`${kibanaDirectory}/node_modules/enzyme-to-json/serializer`],
+ snapshotSerializers: [
+ `${kibanaDirectory}/node_modules/enzyme-to-json/serializer`,
+ `${kibanaDirectory}/src/plugins/kibana_react/public/util/test_helpers/react_mount_serializer.ts`
+ ],
reporters: [
'default',
[
diff --git a/x-pack/legacy/common/eui_draggable/index.d.ts b/x-pack/legacy/common/eui_draggable/index.d.ts
index a85da7a69534c..322966b3c982e 100644
--- a/x-pack/legacy/common/eui_draggable/index.d.ts
+++ b/x-pack/legacy/common/eui_draggable/index.d.ts
@@ -8,7 +8,7 @@ import React from 'react';
import { EuiDraggable, EuiDragDropContext } from '@elastic/eui';
type PropsOf = T extends React.ComponentType ? ComponentProps : never;
-type FirstArgumentOf = Func extends ((arg1: infer FirstArgument, ...rest: any[]) => any)
+type FirstArgumentOf = Func extends (arg1: infer FirstArgument, ...rest: any[]) => any
? FirstArgument
: never;
export type DragHandleProps = FirstArgumentOf<
diff --git a/x-pack/legacy/common/eui_styled_components/eui_styled_components.tsx b/x-pack/legacy/common/eui_styled_components/eui_styled_components.tsx
index 8e5fba31ac5a4..8becf6892ff92 100644
--- a/x-pack/legacy/common/eui_styled_components/eui_styled_components.tsx
+++ b/x-pack/legacy/common/eui_styled_components/eui_styled_components.tsx
@@ -38,6 +38,6 @@ const {
injectGlobal,
keyframes,
withTheme,
-} = styledComponents as ThemedStyledComponentsModule;
+} = (styledComponents as unknown) as ThemedStyledComponentsModule;
export { css, euiStyled, EuiThemeProvider, injectGlobal, keyframes, withTheme };
diff --git a/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts b/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts
index 3e71725713070..a5bf42bc2cc01 100644
--- a/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts
+++ b/x-pack/legacy/plugins/actions/server/lib/task_runner_factory.test.ts
@@ -111,11 +111,9 @@ test('executes the task by calling the executor with proper parameters', async (
expect(runnerResult).toBeUndefined();
expect(spaceIdToNamespace).toHaveBeenCalledWith('test');
- expect(mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser).toHaveBeenCalledWith(
- 'action_task_params',
- '3',
- { namespace: 'namespace-test' }
- );
+ expect(
+ mockedEncryptedSavedObjectsPlugin.getDecryptedAsInternalUser
+ ).toHaveBeenCalledWith('action_task_params', '3', { namespace: 'namespace-test' });
expect(mockedActionExecutor.execute).toHaveBeenCalledWith({
actionId: '2',
params: { baz: true },
diff --git a/x-pack/legacy/plugins/apm/common/apm_saved_object_constants.ts b/x-pack/legacy/plugins/apm/common/apm_saved_object_constants.ts
new file mode 100644
index 0000000000000..ac43b700117c6
--- /dev/null
+++ b/x-pack/legacy/plugins/apm/common/apm_saved_object_constants.ts
@@ -0,0 +1,14 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+// APM Services telemetry
+export const APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE =
+ 'apm-services-telemetry';
+export const APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID = 'apm-services-telemetry';
+
+// APM indices
+export const APM_INDICES_SAVED_OBJECT_TYPE = 'apm-indices';
+export const APM_INDICES_SAVED_OBJECT_ID = 'apm-indices';
diff --git a/x-pack/legacy/plugins/apm/common/projections/util/merge_projection/index.ts b/x-pack/legacy/plugins/apm/common/projections/util/merge_projection/index.ts
index 9a8f11c6493c5..522f6d39ac71a 100644
--- a/x-pack/legacy/plugins/apm/common/projections/util/merge_projection/index.ts
+++ b/x-pack/legacy/plugins/apm/common/projections/util/merge_projection/index.ts
@@ -21,14 +21,14 @@ type SourceProjection = Omit, 'body'> & {
};
type DeepMerge = U extends PlainObject
- ? (T extends PlainObject
- ? (Omit &
- {
- [key in keyof U]: T extends { [k in key]: any }
- ? DeepMerge
- : U[key];
- })
- : U)
+ ? T extends PlainObject
+ ? Omit &
+ {
+ [key in keyof U]: T extends { [k in key]: any }
+ ? DeepMerge
+ : U[key];
+ }
+ : U
: U;
export function mergeProjection<
diff --git a/x-pack/legacy/plugins/grokdebugger/public/sections/grokdebugger/directives/grokdebugger/index.js b/x-pack/legacy/plugins/apm/common/transaction_types.ts
similarity index 61%
rename from x-pack/legacy/plugins/grokdebugger/public/sections/grokdebugger/directives/grokdebugger/index.js
rename to x-pack/legacy/plugins/apm/common/transaction_types.ts
index b33973ed71736..4dd59af63047d 100644
--- a/x-pack/legacy/plugins/grokdebugger/public/sections/grokdebugger/directives/grokdebugger/index.js
+++ b/x-pack/legacy/plugins/apm/common/transaction_types.ts
@@ -4,4 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import './grokdebugger';
+export const TRANSACTION_PAGE_LOAD = 'page-load';
+export const TRANSACTION_ROUTE_CHANGE = 'route-change';
+export const TRANSACTION_REQUEST = 'request';
diff --git a/x-pack/legacy/plugins/apm/cypress/package.json b/x-pack/legacy/plugins/apm/cypress/package.json
index 98dcd495b8594..ef8955fcbd1b0 100644
--- a/x-pack/legacy/plugins/apm/cypress/package.json
+++ b/x-pack/legacy/plugins/apm/cypress/package.json
@@ -11,11 +11,11 @@
"@cypress/snapshot": "^2.1.3",
"@cypress/webpack-preprocessor": "^4.1.0",
"@types/js-yaml": "^3.12.1",
- "cypress": "^3.4.1",
+ "cypress": "^3.5.0",
"js-yaml": "^3.13.1",
"p-limit": "^2.2.1",
"ts-loader": "^6.1.0",
- "typescript": "^3.6.3",
+ "typescript": "3.7.2",
"webpack": "^4.40.2"
}
}
diff --git a/x-pack/legacy/plugins/apm/index.ts b/x-pack/legacy/plugins/apm/index.ts
index 4655e5e6f92ea..bfbfb4bb99c6a 100644
--- a/x-pack/legacy/plugins/apm/index.ts
+++ b/x-pack/legacy/plugins/apm/index.ts
@@ -45,7 +45,10 @@ export const apm: LegacyPluginInitializer = kibana => {
},
hacks: ['plugins/apm/hacks/toggle_app_link_in_nav'],
savedObjectSchemas: {
- 'apm-telemetry': {
+ 'apm-services-telemetry': {
+ isNamespaceAgnostic: true
+ },
+ 'apm-indices': {
isNamespaceAgnostic: true
}
},
diff --git a/x-pack/legacy/plugins/apm/mappings.json b/x-pack/legacy/plugins/apm/mappings.json
index 0b31798242fad..02296606b1c01 100644
--- a/x-pack/legacy/plugins/apm/mappings.json
+++ b/x-pack/legacy/plugins/apm/mappings.json
@@ -1,5 +1,5 @@
{
- "apm-telemetry": {
+ "apm-services-telemetry": {
"properties": {
"has_any_services": {
"type": "boolean"
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/index.tsx
index 53f1893a168ac..69f0cf61af242 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/index.tsx
@@ -6,6 +6,7 @@
import { i18n } from '@kbn/i18n';
import React, { Component } from 'react';
+import { toMountPoint } from '../../../../../../../../../../src/plugins/kibana_react/public';
import { startMLJob } from '../../../../../services/rest/ml';
import { IUrlParams } from '../../../../../context/UrlParamsContext/types';
import { MLJobLink } from '../../../../shared/Links/MachineLearningLinks/MLJobLink';
@@ -71,7 +72,7 @@ export class MachineLearningFlyout extends Component {
defaultMessage: 'Job creation failed'
}
),
- text: (
+ text: toMountPoint(
{i18n.translate(
'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreationFailedNotificationText',
@@ -105,7 +106,7 @@ export class MachineLearningFlyout extends Component {
defaultMessage: 'Job successfully created'
}
),
- text: (
+ text: toMountPoint(
{i18n.translate(
'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.jobCreatedNotificationText',
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx
index 291208b2d9032..d52c869b95872 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx
@@ -30,6 +30,7 @@ import { padLeft, range } from 'lodash';
import moment from 'moment-timezone';
import React, { Component } from 'react';
import styled from 'styled-components';
+import { toMountPoint } from '../../../../../../../../../src/plugins/kibana_react/public';
import { KibanaCoreContext } from '../../../../../../observability/public';
import { IUrlParams } from '../../../../context/UrlParamsContext/types';
import { KibanaLink } from '../../../shared/Links/KibanaLink';
@@ -219,7 +220,7 @@ export class WatcherFlyout extends Component<
defaultMessage: 'Watch creation failed'
}
),
- text: (
+ text: toMountPoint(
{i18n.translate(
'xpack.apm.serviceDetails.enableErrorReportsPanel.watchCreationFailedNotificationText',
@@ -243,7 +244,7 @@ export class WatcherFlyout extends Component<
defaultMessage: 'New watch created!'
}
),
- text: (
+ text: toMountPoint(
{i18n.translate(
'xpack.apm.serviceDetails.enableErrorReportsPanel.watchCreatedNotificationText',
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx
index 276d309cbb3e3..8005fc17f2a20 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceMetrics/index.tsx
@@ -29,9 +29,7 @@ export function ServiceMetrics({ agentName }: ServiceMetricsProps) {
const { data } = useServiceMetricCharts(urlParams, agentName);
const { start, end } = urlParams;
- const localFiltersConfig: React.ComponentProps<
- typeof LocalUIFilters
- > = useMemo(
+ const localFiltersConfig: React.ComponentProps = useMemo(
() => ({
filterNames: ['host', 'containerId', 'podName'],
params: {
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx
index b69076b3a1f70..a118871a5e268 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx
@@ -34,9 +34,7 @@ const ServiceNodeOverview = () => {
const { uiFilters, urlParams } = useUrlParams();
const { serviceName, start, end } = urlParams;
- const localFiltersConfig: React.ComponentProps<
- typeof LocalUIFilters
- > = useMemo(
+ const localFiltersConfig: React.ComponentProps = useMemo(
() => ({
filterNames: ['host', 'containerId', 'podName'],
params: {
diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx
index d03e70fc99cc6..0702e092a714f 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceOverview/index.tsx
@@ -9,6 +9,7 @@ import { EuiLink } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useEffect, useMemo } from 'react';
import url from 'url';
+import { toMountPoint } from '../../../../../../../../src/plugins/kibana_react/public';
import { useFetcher } from '../../../hooks/useFetcher';
import { NoServicesMessage } from './NoServicesMessage';
import { ServiceList } from './ServiceList';
@@ -55,7 +56,7 @@ export function ServiceOverview() {
defaultMessage:
'Legacy data was detected within the selected time range'
}),
- text: (
+ text: toMountPoint(
{i18n.translate('xpack.apm.serviceOverview.toastText', {
defaultMessage:
@@ -84,9 +85,7 @@ export function ServiceOverview() {
useTrackPageview({ app: 'apm', path: 'services_overview' });
useTrackPageview({ app: 'apm', path: 'services_overview', delay: 15000 });
- const localFiltersConfig: React.ComponentProps<
- typeof LocalUIFilters
- > = useMemo(
+ const localFiltersConfig: React.ComponentProps = useMemo(
() => ({
filterNames: ['host', 'agentName'],
projection: PROJECTION.SERVICES
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx
index db0ddb56e7088..fc86f4bb78afb 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionDetails/Distribution/index.tsx
@@ -195,10 +195,9 @@ export const TransactionDistribution: FunctionComponent = (
}
backgroundHover={(bucket: IChartPoint) => bucket.y > 0 && bucket.sample}
tooltipHeader={(bucket: IChartPoint) =>
- `${timeFormatter(bucket.x0, { withUnit: false })} - ${timeFormatter(
- bucket.x,
- { withUnit: false }
- )} ${unit}`
+ `${timeFormatter(bucket.x0, {
+ withUnit: false
+ })} - ${timeFormatter(bucket.x, { withUnit: false })} ${unit}`
}
tooltipFooter={(bucket: IChartPoint) =>
!bucket.sample &&
diff --git a/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx b/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx
index d81b7417570a5..f016052df56a2 100644
--- a/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/app/TransactionOverview/index.tsx
@@ -94,9 +94,7 @@ export function TransactionOverview() {
}
}, [http, serviceName, transactionType]);
- const localFiltersConfig: React.ComponentProps<
- typeof LocalUIFilters
- > = useMemo(
+ const localFiltersConfig: React.ComponentProps = useMemo(
() => ({
filterNames: ['transactionResult', 'host', 'containerId', 'podName'],
params: {
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/KueryBar/index.tsx b/x-pack/legacy/plugins/apm/public/components/shared/KueryBar/index.tsx
index 7c0b6f24f87a7..9918f162a01f4 100644
--- a/x-pack/legacy/plugins/apm/public/components/shared/KueryBar/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/KueryBar/index.tsx
@@ -103,12 +103,14 @@ export function KueryBar() {
const boolFilter = getBoolFilter(urlParams);
try {
- const suggestions = (await getSuggestions(
- inputValue,
- selectionStart,
- indexPattern,
- boolFilter
- ))
+ const suggestions = (
+ await getSuggestions(
+ inputValue,
+ selectionStart,
+ indexPattern,
+ boolFilter
+ )
+ )
.filter(suggestion => !startsWith(suggestion.text, 'span.'))
.slice(0, 15);
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/Section.tsx b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/Section.tsx
index 6f67b2458ea10..0aaeae3e4ce44 100644
--- a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/Section.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/Section.tsx
@@ -5,17 +5,18 @@
*/
import React from 'react';
+import { isEmpty } from 'lodash';
import { i18n } from '@kbn/i18n';
import { EuiText } from '@elastic/eui';
import { KeyValueTable } from '../KeyValueTable';
import { KeyValuePair } from '../../../utils/flattenObject';
interface Props {
- keyValuePairs?: KeyValuePair[];
+ keyValuePairs: KeyValuePair[];
}
export function Section({ keyValuePairs }: Props) {
- if (keyValuePairs) {
+ if (!isEmpty(keyValuePairs)) {
return ;
}
return (
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/MetadataTable.test.tsx b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/MetadataTable.test.tsx
index bdf895f423913..4398c129aa7b8 100644
--- a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/MetadataTable.test.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/MetadataTable.test.tsx
@@ -21,7 +21,10 @@ describe('MetadataTable', () => {
label: 'Bar',
required: false,
properties: ['props.A', 'props.B'],
- rows: [{ key: 'props.A', value: 'A' }, { key: 'props.B', value: 'B' }]
+ rows: [
+ { key: 'props.A', value: 'A' },
+ { key: 'props.B', value: 'B' }
+ ]
}
] as unknown) as SectionsWithRows;
const output = render();
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/Section.test.tsx b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/Section.test.tsx
index 7e68b2f84eead..4378c7fdeee0c 100644
--- a/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/Section.test.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/MetadataTable/__test__/Section.test.tsx
@@ -11,7 +11,7 @@ import { expectTextsInDocument } from '../../../../utils/testHelpers';
describe('Section', () => {
it('shows "empty state message" if no data is available', () => {
- const output = render();
- expectTextsInDocument(output, ['No data available']);
+ const component = render();
+ expectTextsInDocument(component, ['No data available']);
});
});
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/Stacktrace/index.tsx b/x-pack/legacy/plugins/apm/public/components/shared/Stacktrace/index.tsx
index ca14be237d22b..b7963b5c75a92 100644
--- a/x-pack/legacy/plugins/apm/public/components/shared/Stacktrace/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/Stacktrace/index.tsx
@@ -78,29 +78,26 @@ interface StackframesGroup {
}
export function getGroupedStackframes(stackframes: IStackframe[]) {
- return stackframes.reduce(
- (acc, stackframe) => {
- const prevGroup = last(acc);
- const shouldAppend =
- prevGroup &&
- prevGroup.isLibraryFrame === stackframe.library_frame &&
- !prevGroup.excludeFromGrouping &&
- !stackframe.exclude_from_grouping;
+ return stackframes.reduce((acc, stackframe) => {
+ const prevGroup = last(acc);
+ const shouldAppend =
+ prevGroup &&
+ prevGroup.isLibraryFrame === stackframe.library_frame &&
+ !prevGroup.excludeFromGrouping &&
+ !stackframe.exclude_from_grouping;
- // append to group
- if (shouldAppend) {
- prevGroup.stackframes.push(stackframe);
- return acc;
- }
-
- // create new group
- acc.push({
- isLibraryFrame: Boolean(stackframe.library_frame),
- excludeFromGrouping: Boolean(stackframe.exclude_from_grouping),
- stackframes: [stackframe]
- });
+ // append to group
+ if (shouldAppend) {
+ prevGroup.stackframes.push(stackframe);
return acc;
- },
- [] as StackframesGroup[]
- );
+ }
+
+ // create new group
+ acc.push({
+ isLibraryFrame: Boolean(stackframe.library_frame),
+ excludeFromGrouping: Boolean(stackframe.exclude_from_grouping),
+ stackframes: [stackframe]
+ });
+ return acc;
+ }, [] as StackframesGroup[]);
}
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/charts/CustomPlot/VoronoiPlot.js b/x-pack/legacy/plugins/apm/public/components/shared/charts/CustomPlot/VoronoiPlot.js
index 52afdffcb0839..d765a57a56a18 100644
--- a/x-pack/legacy/plugins/apm/public/components/shared/charts/CustomPlot/VoronoiPlot.js
+++ b/x-pack/legacy/plugins/apm/public/components/shared/charts/CustomPlot/VoronoiPlot.js
@@ -32,7 +32,10 @@ class VoronoiPlot extends PureComponent {
onMouseLeave={this.props.onMouseLeave}
>
{
formatYShort={t => `${asDecimal(t)} occ.`}
formatYLong={t => `${asDecimal(t)} occurrences`}
tooltipHeader={bucket =>
- `${timeFormatter(bucket.x0, { withUnit: false })} - ${timeFormatter(
- bucket.x,
- { withUnit: false }
- )} ${unit}`
+ `${timeFormatter(bucket.x0, {
+ withUnit: false
+ })} - ${timeFormatter(bucket.x, { withUnit: false })} ${unit}`
}
width={800}
/>
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/charts/Histogram/index.js b/x-pack/legacy/plugins/apm/public/components/shared/charts/Histogram/index.js
index 7b9586634c7d0..50c94fe88e6ad 100644
--- a/x-pack/legacy/plugins/apm/public/components/shared/charts/Histogram/index.js
+++ b/x-pack/legacy/plugins/apm/public/components/shared/charts/Histogram/index.js
@@ -209,7 +209,10 @@ export class HistogramInner extends PureComponent {
)}
{
return {
...bucket,
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/ChoroplethToolTip.tsx b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/ChoroplethToolTip.tsx
index 12872fd64a3c4..adcce161c7ac1 100644
--- a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/ChoroplethToolTip.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/ChoroplethMap/ChoroplethToolTip.tsx
@@ -19,7 +19,7 @@ export const ChoroplethToolTip: React.SFC<{
{name}
{i18n.translate(
- 'xpack.apm.metrics.pageLoadCharts.RegionMapChart.ToolTip.avgPageLoadDuration',
+ 'xpack.apm.metrics.durationByCountryMap.RegionMapChart.ToolTip.avgPageLoadDuration',
{
defaultMessage: 'Avg. page load duration:'
}
@@ -31,7 +31,7 @@ export const ChoroplethToolTip: React.SFC<{
(
{i18n.translate(
- 'xpack.apm.metrics.pageLoadCharts.RegionMapChart.ToolTip.countPageLoads',
+ 'xpack.apm.metrics.durationByCountryMap.RegionMapChart.ToolTip.countPageLoads',
{
values: { docCount: asInteger(docCount) },
defaultMessage: '{docCount} page loads'
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/PageLoadCharts/index.tsx b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/DurationByCountryMap/index.tsx
similarity index 88%
rename from x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/PageLoadCharts/index.tsx
rename to x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/DurationByCountryMap/index.tsx
index 40c6150149eb5..6176397170797 100644
--- a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/PageLoadCharts/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/DurationByCountryMap/index.tsx
@@ -10,7 +10,7 @@ import React from 'react';
import { useAvgDurationByCountry } from '../../../../../hooks/useAvgDurationByCountry';
import { ChoroplethMap } from '../ChoroplethMap';
-export const PageLoadCharts: React.SFC = () => {
+export const DurationByCountryMap: React.SFC = () => {
const { data } = useAvgDurationByCountry();
return (
@@ -20,7 +20,7 @@ export const PageLoadCharts: React.SFC = () => {
{i18n.translate(
- 'xpack.apm.metrics.pageLoadCharts.avgPageLoadByCountryLabel',
+ 'xpack.apm.metrics.durationByCountryMap.avgPageLoadByCountryLabel',
{
defaultMessage:
'Avg. page load duration distribution by country'
diff --git a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx
index 132067a6c32b7..94f30a8a2325a 100644
--- a/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx
+++ b/x-pack/legacy/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx
@@ -34,7 +34,12 @@ import { LicenseContext } from '../../../../context/LicenseContext';
import { TransactionLineChart } from './TransactionLineChart';
import { isValidCoordinateValue } from '../../../../utils/isValidCoordinateValue';
import { getTimeFormatter } from '../../../../utils/formatters';
-import { PageLoadCharts } from './PageLoadCharts';
+import { DurationByCountryMap } from './DurationByCountryMap';
+import {
+ TRANSACTION_PAGE_LOAD,
+ TRANSACTION_ROUTE_CHANGE,
+ TRANSACTION_REQUEST
+} from '../../../../../common/transaction_types';
interface TransactionChartProps {
hasMLJob: boolean;
@@ -55,8 +60,6 @@ const ShiftedEuiText = styled(EuiText)`
top: 5px;
`;
-const RUM_PAGE_LOAD_TYPE = 'page-load';
-
export class TransactionCharts extends Component {
public getMaxY = (responseTimeSeries: TimeSeries[]) => {
const coordinates = flatten(
@@ -200,19 +203,19 @@ export class TransactionCharts extends Component {
- {transactionType === RUM_PAGE_LOAD_TYPE ? (
+ {transactionType === TRANSACTION_PAGE_LOAD && (
<>
-
+
>
- ) : null}
+ )}
>
);
}
}
function tpmLabel(type?: string) {
- return type === 'request'
+ return type === TRANSACTION_REQUEST
? i18n.translate(
'xpack.apm.metrics.transactionChart.requestsPerMinuteLabel',
{
@@ -229,14 +232,14 @@ function tpmLabel(type?: string) {
function responseTimeLabel(type?: string) {
switch (type) {
- case RUM_PAGE_LOAD_TYPE:
+ case TRANSACTION_PAGE_LOAD:
return i18n.translate(
'xpack.apm.metrics.transactionChart.pageLoadTimesLabel',
{
defaultMessage: 'Page load times'
}
);
- case 'route-change':
+ case TRANSACTION_ROUTE_CHANGE:
return i18n.translate(
'xpack.apm.metrics.transactionChart.routeChangeTimesLabel',
{
diff --git a/x-pack/legacy/plugins/apm/public/hooks/useAvgDurationByCountry.ts b/x-pack/legacy/plugins/apm/public/hooks/useAvgDurationByCountry.ts
index b794332d4aa63..6b3fa1f0d98f7 100644
--- a/x-pack/legacy/plugins/apm/public/hooks/useAvgDurationByCountry.ts
+++ b/x-pack/legacy/plugins/apm/public/hooks/useAvgDurationByCountry.ts
@@ -9,7 +9,7 @@ import { useUrlParams } from './useUrlParams';
export function useAvgDurationByCountry() {
const {
- urlParams: { serviceName, start, end },
+ urlParams: { serviceName, start, end, transactionName },
uiFilters
} = useUrlParams();
@@ -24,13 +24,14 @@ export function useAvgDurationByCountry() {
query: {
start,
end,
- uiFilters: JSON.stringify(uiFilters)
+ uiFilters: JSON.stringify(uiFilters),
+ transactionName
}
}
});
}
},
- [serviceName, start, end, uiFilters]
+ [serviceName, start, end, uiFilters, transactionName]
);
return {
diff --git a/x-pack/legacy/plugins/apm/public/hooks/useFetcher.tsx b/x-pack/legacy/plugins/apm/public/hooks/useFetcher.tsx
index ba74b0175ff71..bc6382841be3f 100644
--- a/x-pack/legacy/plugins/apm/public/hooks/useFetcher.tsx
+++ b/x-pack/legacy/plugins/apm/public/hooks/useFetcher.tsx
@@ -8,6 +8,7 @@ import React, { useContext, useEffect, useState, useMemo } from 'react';
import { idx } from '@kbn/elastic-idx';
import { i18n } from '@kbn/i18n';
import { IHttpFetchError } from 'src/core/public';
+import { toMountPoint } from '../../../../../../src/plugins/kibana_react/public';
import { LoadingIndicatorContext } from '../context/LoadingIndicatorContext';
import { useComponentId } from './useComponentId';
import { useKibanaCore } from '../../../observability/public';
@@ -92,7 +93,7 @@ export function useFetcher(
title: i18n.translate('xpack.apm.fetcher.error.title', {
defaultMessage: `Error while fetching resource`
}),
- text: (
+ text: toMountPoint(
{i18n.translate('xpack.apm.fetcher.error.status', {
diff --git a/x-pack/legacy/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts b/x-pack/legacy/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts
index 80a1b96efb3d6..2b0263f69db8f 100644
--- a/x-pack/legacy/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts
+++ b/x-pack/legacy/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts
@@ -35,9 +35,18 @@ describe('chartSelectors', () => {
describe('getResponseTimeSeries', () => {
const apmTimeseries = {
responseTimes: {
- avg: [{ x: 0, y: 100 }, { x: 1000, y: 200 }],
- p95: [{ x: 0, y: 200 }, { x: 1000, y: 300 }],
- p99: [{ x: 0, y: 300 }, { x: 1000, y: 400 }]
+ avg: [
+ { x: 0, y: 100 },
+ { x: 1000, y: 200 }
+ ],
+ p95: [
+ { x: 0, y: 200 },
+ { x: 1000, y: 300 }
+ ],
+ p99: [
+ { x: 0, y: 300 },
+ { x: 1000, y: 400 }
+ ]
},
tpmBuckets: [],
overallAvgDuration: 200
@@ -49,21 +58,30 @@ describe('chartSelectors', () => {
).toEqual([
{
color: '#3185fc',
- data: [{ x: 0, y: 100 }, { x: 1000, y: 200 }],
+ data: [
+ { x: 0, y: 100 },
+ { x: 1000, y: 200 }
+ ],
legendValue: '0 ms',
title: 'Avg.',
type: 'linemark'
},
{
color: '#e6c220',
- data: [{ x: 0, y: 200 }, { x: 1000, y: 300 }],
+ data: [
+ { x: 0, y: 200 },
+ { x: 1000, y: 300 }
+ ],
title: '95th percentile',
titleShort: '95th',
type: 'linemark'
},
{
color: '#f98510',
- data: [{ x: 0, y: 300 }, { x: 1000, y: 400 }],
+ data: [
+ { x: 0, y: 300 },
+ { x: 1000, y: 400 }
+ ],
title: '99th percentile',
titleShort: '99th',
type: 'linemark'
@@ -87,7 +105,13 @@ describe('chartSelectors', () => {
p99: []
},
tpmBuckets: [
- { key: 'HTTP 2xx', dataPoints: [{ x: 0, y: 5 }, { x: 0, y: 2 }] },
+ {
+ key: 'HTTP 2xx',
+ dataPoints: [
+ { x: 0, y: 5 },
+ { x: 0, y: 2 }
+ ]
+ },
{ key: 'HTTP 4xx', dataPoints: [{ x: 0, y: 1 }] },
{ key: 'HTTP 5xx', dataPoints: [{ x: 0, y: 0 }] }
],
@@ -99,7 +123,10 @@ describe('chartSelectors', () => {
expect(getTpmSeries(apmTimeseries, transactionType)).toEqual([
{
color: successColor,
- data: [{ x: 0, y: 5 }, { x: 0, y: 2 }],
+ data: [
+ { x: 0, y: 5 },
+ { x: 0, y: 2 }
+ ],
legendValue: '3.5 tpm',
title: 'HTTP 2xx',
type: 'linemark'
@@ -220,9 +247,18 @@ describe('chartSelectors', () => {
describe('when empty', () => {
it('produces an empty series', () => {
const responseTimes = {
- avg: [{ x: 0, y: 1 }, { x: 100, y: 1 }],
- p95: [{ x: 0, y: 1 }, { x: 100, y: 1 }],
- p99: [{ x: 0, y: 1 }, { x: 100, y: 1 }]
+ avg: [
+ { x: 0, y: 1 },
+ { x: 100, y: 1 }
+ ],
+ p95: [
+ { x: 0, y: 1 },
+ { x: 100, y: 1 }
+ ],
+ p99: [
+ { x: 0, y: 1 },
+ { x: 100, y: 1 }
+ ]
};
const series = getTpmSeries(
{ ...apmTimeseries, responseTimes, tpmBuckets: [] },
diff --git a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/apm_telemetry.test.ts b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/index.test.ts
similarity index 83%
rename from x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/apm_telemetry.test.ts
rename to x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/index.test.ts
index 6db6e8848ef07..26cae303542a4 100644
--- a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/apm_telemetry.test.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/__test__/index.test.ts
@@ -5,11 +5,11 @@
*/
import { SavedObjectAttributes } from 'src/core/server';
+import { createApmTelementry, storeApmServicesTelemetry } from '../index';
import {
- APM_TELEMETRY_DOC_ID,
- createApmTelementry,
- storeApmTelemetry
-} from '../apm_telemetry';
+ APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE,
+ APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID
+} from '../../../../common/apm_saved_object_constants';
describe('apm_telemetry', () => {
describe('createApmTelementry', () => {
@@ -44,7 +44,7 @@ describe('apm_telemetry', () => {
});
});
- describe('storeApmTelemetry', () => {
+ describe('storeApmServicesTelemetry', () => {
let server: any;
let apmTelemetry: SavedObjectAttributes;
let savedObjectsClientInstance: any;
@@ -75,24 +75,24 @@ describe('apm_telemetry', () => {
});
it('should call savedObjectsClient create with the given ApmTelemetry object', () => {
- storeApmTelemetry(server, apmTelemetry);
+ storeApmServicesTelemetry(server, apmTelemetry);
expect(savedObjectsClientInstance.create.mock.calls[0][1]).toBe(
apmTelemetry
);
});
it('should call savedObjectsClient create with the apm-telemetry document type and ID', () => {
- storeApmTelemetry(server, apmTelemetry);
+ storeApmServicesTelemetry(server, apmTelemetry);
expect(savedObjectsClientInstance.create.mock.calls[0][0]).toBe(
- 'apm-telemetry'
+ APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE
);
expect(savedObjectsClientInstance.create.mock.calls[0][2].id).toBe(
- APM_TELEMETRY_DOC_ID
+ APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID
);
});
it('should call savedObjectsClient create with overwrite: true', () => {
- storeApmTelemetry(server, apmTelemetry);
+ storeApmServicesTelemetry(server, apmTelemetry);
expect(savedObjectsClientInstance.create.mock.calls[0][2].overwrite).toBe(
true
);
diff --git a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/apm_telemetry.ts b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/apm_telemetry.ts
deleted file mode 100644
index 54106cce10bac..0000000000000
--- a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/apm_telemetry.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { Server } from 'hapi';
-import { countBy } from 'lodash';
-import { SavedObjectAttributes } from 'src/core/server';
-import { isAgentName } from '../../../common/agent_name';
-import { getSavedObjectsClient } from '../helpers/saved_objects_client';
-
-export const APM_TELEMETRY_DOC_ID = 'apm-telemetry';
-
-export function createApmTelementry(
- agentNames: string[] = []
-): SavedObjectAttributes {
- const validAgentNames = agentNames.filter(isAgentName);
- return {
- has_any_services: validAgentNames.length > 0,
- services_per_agent: countBy(validAgentNames)
- };
-}
-
-export async function storeApmTelemetry(
- server: Server,
- apmTelemetry: SavedObjectAttributes
-) {
- try {
- const savedObjectsClient = getSavedObjectsClient(server);
- await savedObjectsClient.create('apm-telemetry', apmTelemetry, {
- id: APM_TELEMETRY_DOC_ID,
- overwrite: true
- });
- } catch (e) {
- // eslint-disable-next-line no-console
- console.error('Could not send APM telemetry:', e.message);
- }
-}
diff --git a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts
index 754666b0a9fa2..640072d6ec4d8 100644
--- a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/index.ts
@@ -4,9 +4,77 @@
* you may not use this file except in compliance with the Elastic License.
*/
-export {
- storeApmTelemetry,
- createApmTelementry,
- APM_TELEMETRY_DOC_ID
-} from './apm_telemetry';
-export { makeApmUsageCollector } from './make_apm_usage_collector';
+import { Server } from 'hapi';
+import { countBy } from 'lodash';
+import { SavedObjectAttributes } from 'src/core/server';
+import { CoreSetup } from 'src/core/server';
+import { isAgentName } from '../../../common/agent_name';
+import { getInternalSavedObjectsClient } from '../helpers/saved_objects_client';
+import {
+ APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE,
+ APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID
+} from '../../../common/apm_saved_object_constants';
+import { LegacySetup } from '../../new-platform/plugin';
+
+export function createApmTelementry(
+ agentNames: string[] = []
+): SavedObjectAttributes {
+ const validAgentNames = agentNames.filter(isAgentName);
+ return {
+ has_any_services: validAgentNames.length > 0,
+ services_per_agent: countBy(validAgentNames)
+ };
+}
+
+export async function storeApmServicesTelemetry(
+ server: Server,
+ apmTelemetry: SavedObjectAttributes
+) {
+ try {
+ const internalSavedObjectsClient = getInternalSavedObjectsClient(server);
+ await internalSavedObjectsClient.create(
+ APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE,
+ apmTelemetry,
+ {
+ id: APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID,
+ overwrite: true
+ }
+ );
+ } catch (e) {
+ server.log(['error'], `Unable to save APM telemetry data: ${e.message}`);
+ }
+}
+
+interface LegacySetupWithUsageCollector extends LegacySetup {
+ server: LegacySetup['server'] & {
+ usage: {
+ collectorSet: {
+ makeUsageCollector: (options: unknown) => unknown;
+ register: (options: unknown) => unknown;
+ };
+ };
+ };
+}
+
+export function makeApmUsageCollector(
+ core: CoreSetup,
+ { server }: LegacySetupWithUsageCollector
+) {
+ const apmUsageCollector = server.usage.collectorSet.makeUsageCollector({
+ type: 'apm',
+ fetch: async () => {
+ const internalSavedObjectsClient = getInternalSavedObjectsClient(server);
+ try {
+ const apmTelemetrySavedObject = await internalSavedObjectsClient.get(
+ APM_SERVICES_TELEMETRY_SAVED_OBJECT_TYPE,
+ APM_SERVICES_TELEMETRY_SAVED_OBJECT_ID
+ );
+ return apmTelemetrySavedObject.attributes;
+ } catch (err) {
+ return createApmTelementry();
+ }
+ },
+ isReady: () => true
+ });
+ server.usage.collectorSet.register(apmUsageCollector);
+}
diff --git a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts b/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts
deleted file mode 100644
index 886c3890f1a9a..0000000000000
--- a/x-pack/legacy/plugins/apm/server/lib/apm_telemetry/make_apm_usage_collector.ts
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License;
- * you may not use this file except in compliance with the Elastic License.
- */
-
-import { CoreSetup } from 'src/core/server';
-import { getSavedObjectsClient } from '../helpers/saved_objects_client';
-import { APM_TELEMETRY_DOC_ID, createApmTelementry } from './apm_telemetry';
-import { LegacySetup } from '../../new-platform/plugin';
-
-export interface LegacySetupWithUsageCollector extends LegacySetup {
- server: LegacySetup['server'] & {
- usage: {
- collectorSet: {
- makeUsageCollector: (options: unknown) => unknown;
- register: (options: unknown) => unknown;
- };
- };
- };
-}
-
-export function makeApmUsageCollector(
- core: CoreSetup,
- { server }: LegacySetupWithUsageCollector
-) {
- const apmUsageCollector = server.usage.collectorSet.makeUsageCollector({
- type: 'apm',
- fetch: async () => {
- const savedObjectsClient = getSavedObjectsClient(server);
- try {
- const apmTelemetrySavedObject = await savedObjectsClient.get(
- 'apm-telemetry',
- APM_TELEMETRY_DOC_ID
- );
- return apmTelemetrySavedObject.attributes;
- } catch (err) {
- return createApmTelementry();
- }
- },
- isReady: () => true
- });
- server.usage.collectorSet.register(apmUsageCollector);
-}
diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts
index f38184fe460b1..9c111910f16f9 100644
--- a/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/helpers/es_client.ts
@@ -66,8 +66,12 @@ async function getParamsForSearchRequest(
apmOptions?: APMOptions
) {
const uiSettings = req.getUiSettingsService();
+ const { server } = req;
const [indices, includeFrozen] = await Promise.all([
- getApmIndices(req.server),
+ getApmIndices({
+ config: server.config(),
+ savedObjectsClient: server.savedObjects.getScopedSavedObjectsClient(req)
+ }),
uiSettings.get('search:includeFrozen')
]);
diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.test.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.test.ts
index 3af1d8c706f46..c685ffdd801dc 100644
--- a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.test.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.test.ts
@@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { getSavedObjectsClient } from './saved_objects_client';
+import { getInternalSavedObjectsClient } from './saved_objects_client';
describe('saved_objects/client', () => {
describe('getSavedObjectsClient', () => {
@@ -31,7 +31,7 @@ describe('saved_objects/client', () => {
});
it('should use internal user "admin"', () => {
- getSavedObjectsClient(server);
+ getInternalSavedObjectsClient(server);
expect(server.plugins.elasticsearch.getCluster).toHaveBeenCalledWith(
'admin'
@@ -39,7 +39,7 @@ describe('saved_objects/client', () => {
});
it('should call getSavedObjectsRepository with a cluster using the internal user context', () => {
- getSavedObjectsClient(server);
+ getInternalSavedObjectsClient(server);
expect(
server.savedObjects.getSavedObjectsRepository
@@ -47,9 +47,9 @@ describe('saved_objects/client', () => {
});
it('should return a SavedObjectsClient initialized with the saved objects internal repository', () => {
- const result = getSavedObjectsClient(server);
+ const internalSavedObjectsClient = getInternalSavedObjectsClient(server);
- expect(result).toBe(savedObjectsClientInstance);
+ expect(internalSavedObjectsClient).toBe(savedObjectsClientInstance);
expect(server.savedObjects.SavedObjectsClient).toHaveBeenCalledWith(
internalRepository
);
diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.ts
index 81dd8b34c8847..f164ca39d51c0 100644
--- a/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/helpers/saved_objects_client.ts
@@ -6,7 +6,10 @@
import { Server } from 'hapi';
-export function getSavedObjectsClient(server: Server, clusterName = 'admin') {
+export function getInternalSavedObjectsClient(
+ server: Server,
+ clusterName = 'admin'
+) {
const { SavedObjectsClient, getSavedObjectsRepository } = server.savedObjects;
const { callWithInternalUser } = server.plugins.elasticsearch.getCluster(
clusterName
diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts
index 6ebf7a896591f..f43b9ea11487a 100644
--- a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.test.ts
@@ -34,6 +34,9 @@ function getMockRequest() {
callWithInternalUser: callWithInternalUserSpy
})
}
+ },
+ savedObjects: {
+ getScopedSavedObjectsClient: () => ({ get: async () => false })
}
},
getUiSettingsService: () => ({ get: async () => false })
diff --git a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts
index 850de4939d599..ab0f47eb04d62 100644
--- a/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/helpers/setup_request.ts
@@ -7,10 +7,15 @@
import { Legacy } from 'kibana';
import { Server } from 'hapi';
import moment from 'moment';
+import { KibanaConfig } from 'src/legacy/server/kbn_server';
import { getESClient } from './es_client';
import { getUiFiltersES } from './convert_ui_filters/get_ui_filters_es';
-import { PromiseReturnType } from '../../../typings/common';
-import { getApmIndices } from '../settings/apm_indices/get_apm_indices';
+import {
+ getApmIndices,
+ ApmIndicesConfig
+} from '../settings/apm_indices/get_apm_indices';
+import { ESFilter } from '../../../typings/elasticsearch';
+import { ESClient } from './es_client';
function decodeUiFilters(server: Server, uiFiltersEncoded?: string) {
if (!uiFiltersEncoded) {
@@ -26,15 +31,29 @@ export interface APMRequestQuery {
end?: string;
uiFilters?: string;
}
+// Explicitly type Setup to prevent TS initialization errors
+// https://github.com/microsoft/TypeScript/issues/34933
-export type Setup = PromiseReturnType;
-export async function setupRequest(req: Legacy.Request) {
+export interface Setup {
+ start: number;
+ end: number;
+ uiFiltersES: ESFilter[];
+ client: ESClient;
+ internalClient: ESClient;
+ config: KibanaConfig;
+ indices: ApmIndicesConfig;
+}
+
+export async function setupRequest(req: Legacy.Request): Promise {
const query = (req.query as unknown) as APMRequestQuery;
const { server } = req;
+ const savedObjectsClient = server.savedObjects.getScopedSavedObjectsClient(
+ req
+ );
const config = server.config();
const [uiFiltersES, indices] = await Promise.all([
decodeUiFilters(server, query.uiFilters),
- getApmIndices(server)
+ getApmIndices({ config, savedObjectsClient })
]);
return {
diff --git a/x-pack/legacy/plugins/apm/server/lib/index_pattern/index.ts b/x-pack/legacy/plugins/apm/server/lib/index_pattern/index.ts
index 0b9407b288b1d..1aff1d772c5c2 100644
--- a/x-pack/legacy/plugins/apm/server/lib/index_pattern/index.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/index_pattern/index.ts
@@ -4,18 +4,21 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { Server } from 'hapi';
-import { getSavedObjectsClient } from '../helpers/saved_objects_client';
+import { getInternalSavedObjectsClient } from '../helpers/saved_objects_client';
import apmIndexPattern from '../../../../../../../src/legacy/core_plugins/kibana/server/tutorials/apm/index_pattern.json';
export async function getAPMIndexPattern(server: Server) {
const config = server.config();
const apmIndexPatternTitle = config.get('apm_oss.indexPattern');
- const savedObjectsClient = getSavedObjectsClient(server);
+ const internalSavedObjectsClient = getInternalSavedObjectsClient(server);
try {
- return await savedObjectsClient.get('index-pattern', apmIndexPattern.id);
+ return await internalSavedObjectsClient.get(
+ 'index-pattern',
+ apmIndexPattern.id
+ );
} catch (error) {
// if GET fails, then create a new index pattern saved object
- return await savedObjectsClient.create(
+ return await internalSavedObjectsClient.create(
'index-pattern',
{
...apmIndexPattern.attributes,
diff --git a/x-pack/legacy/plugins/apm/server/lib/metrics/transform_metrics_chart.ts b/x-pack/legacy/plugins/apm/server/lib/metrics/transform_metrics_chart.ts
index 594a0d35ed176..3764f18a6d692 100644
--- a/x-pack/legacy/plugins/apm/server/lib/metrics/transform_metrics_chart.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/metrics/transform_metrics_chart.ts
@@ -48,9 +48,10 @@ type GenericMetricsRequest = Overwrite<
}
>;
-export function transformDataToMetricsChart<
- TRequest extends GenericMetricsRequest
->(result: ESSearchResponse, chartBase: ChartBase) {
+export function transformDataToMetricsChart(
+ result: ESSearchResponse,
+ chartBase: ChartBase
+) {
const { aggregations, hits } = result;
const timeseriesData = idx(aggregations, _ => _.timeseriesData);
diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts
index 18f6aea610a68..434eda8c0f46e 100644
--- a/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/settings/agent_configuration/create_agent_config_index.ts
@@ -8,13 +8,19 @@ import { CoreSetup } from 'src/core/server';
import { CallCluster } from '../../../../../../../../src/legacy/core_plugins/elasticsearch';
import { getApmIndices } from '../apm_indices/get_apm_indices';
import { LegacySetup } from '../../../new-platform/plugin';
+import { getInternalSavedObjectsClient } from '../../helpers/saved_objects_client';
export async function createApmAgentConfigurationIndex(
core: CoreSetup,
{ server }: LegacySetup
) {
try {
- const indices = await getApmIndices(server);
+ const config = server.config();
+ const internalSavedObjectsClient = getInternalSavedObjectsClient(server);
+ const indices = await getApmIndices({
+ savedObjectsClient: internalSavedObjectsClient,
+ config
+ });
const index = indices['apm_oss.apmAgentConfigurationIndex'];
const { callWithInternalUser } = server.plugins.elasticsearch.getCluster(
'admin'
diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts b/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts
index cd237a5264099..e942a26da373e 100644
--- a/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/get_apm_indices.ts
@@ -4,12 +4,14 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { Server } from 'hapi';
import { merge } from 'lodash';
import { KibanaConfig } from 'src/legacy/server/kbn_server';
-import { getSavedObjectsClient } from '../../helpers/saved_objects_client';
-import { Setup } from '../../helpers/setup_request';
+import { Server } from 'hapi';
import { PromiseReturnType } from '../../../../typings/common';
+import {
+ APM_INDICES_SAVED_OBJECT_TYPE,
+ APM_INDICES_SAVED_OBJECT_ID
+} from '../../../../common/apm_saved_object_constants';
export interface ApmIndicesConfig {
'apm_oss.sourcemapIndices': string;
@@ -23,11 +25,13 @@ export interface ApmIndicesConfig {
export type ApmIndicesName = keyof ApmIndicesConfig;
-export const APM_INDICES_SAVED_OBJECT_TYPE = 'apm-indices';
-export const APM_INDICES_SAVED_OBJECT_ID = 'apm-indices';
+export type ScopedSavedObjectsClient = ReturnType<
+ Server['savedObjects']['getScopedSavedObjectsClient']
+>;
-async function getApmIndicesSavedObject(server: Server) {
- const savedObjectsClient = getSavedObjectsClient(server, 'data');
+async function getApmIndicesSavedObject(
+ savedObjectsClient: ScopedSavedObjectsClient
+) {
const apmIndices = await savedObjectsClient.get>(
APM_INDICES_SAVED_OBJECT_TYPE,
APM_INDICES_SAVED_OBJECT_ID
@@ -53,13 +57,21 @@ function getApmIndicesConfig(config: KibanaConfig): ApmIndicesConfig {
};
}
-export async function getApmIndices(server: Server) {
+export async function getApmIndices({
+ savedObjectsClient,
+ config
+}: {
+ savedObjectsClient: ScopedSavedObjectsClient;
+ config: KibanaConfig;
+}) {
try {
- const apmIndicesSavedObject = await getApmIndicesSavedObject(server);
- const apmIndicesConfig = getApmIndicesConfig(server.config());
+ const apmIndicesSavedObject = await getApmIndicesSavedObject(
+ savedObjectsClient
+ );
+ const apmIndicesConfig = getApmIndicesConfig(config);
return merge({}, apmIndicesConfig, apmIndicesSavedObject);
} catch (error) {
- return getApmIndicesConfig(server.config());
+ return getApmIndicesConfig(config);
}
}
@@ -74,16 +86,15 @@ const APM_UI_INDICES: ApmIndicesName[] = [
];
export async function getApmIndexSettings({
- setup,
- server
+ config,
+ savedObjectsClient
}: {
- setup: Setup;
- server: Server;
+ config: KibanaConfig;
+ savedObjectsClient: ScopedSavedObjectsClient;
}) {
- const { config } = setup;
let apmIndicesSavedObject: PromiseReturnType;
try {
- apmIndicesSavedObject = await getApmIndicesSavedObject(server);
+ apmIndicesSavedObject = await getApmIndicesSavedObject(savedObjectsClient);
} catch (error) {
if (error.output && error.output.statusCode === 404) {
apmIndicesSavedObject = {};
diff --git a/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts b/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts
index 8de47c5c44144..e57e64942ab89 100644
--- a/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/settings/apm_indices/save_apm_indices.ts
@@ -4,19 +4,16 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { Server } from 'hapi';
-import { getSavedObjectsClient } from '../../helpers/saved_objects_client';
+import { ApmIndicesConfig, ScopedSavedObjectsClient } from './get_apm_indices';
import {
- ApmIndicesConfig,
APM_INDICES_SAVED_OBJECT_TYPE,
APM_INDICES_SAVED_OBJECT_ID
-} from './get_apm_indices';
+} from '../../../../common/apm_saved_object_constants';
export async function saveApmIndices(
- server: Server,
+ savedObjectsClient: ScopedSavedObjectsClient,
apmIndicesSavedObject: Partial
) {
- const savedObjectsClient = getSavedObjectsClient(server, 'data');
return await savedObjectsClient.create(
APM_INDICES_SAVED_OBJECT_TYPE,
apmIndicesSavedObject,
diff --git a/x-pack/legacy/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts b/x-pack/legacy/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts
index e092942a25ba6..ed6bdf203f2d4 100644
--- a/x-pack/legacy/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/transactions/avg_duration_by_country/index.ts
@@ -9,19 +9,26 @@ import {
PROCESSOR_EVENT,
SERVICE_NAME,
TRANSACTION_DURATION,
- TRANSACTION_TYPE
+ TRANSACTION_TYPE,
+ TRANSACTION_NAME
} from '../../../../common/elasticsearch_fieldnames';
import { Setup } from '../../helpers/setup_request';
import { rangeFilter } from '../../helpers/range_filter';
+import { TRANSACTION_PAGE_LOAD } from '../../../../common/transaction_types';
export async function getTransactionAvgDurationByCountry({
setup,
- serviceName
+ serviceName,
+ transactionName
}: {
setup: Setup;
serviceName: string;
+ transactionName?: string;
}) {
const { uiFiltersES, client, start, end, indices } = setup;
+ const transactionNameFilter = transactionName
+ ? [{ term: { [TRANSACTION_NAME]: transactionName } }]
+ : [];
const params = {
index: indices['apm_oss.transactionIndices'],
body: {
@@ -30,8 +37,9 @@ export async function getTransactionAvgDurationByCountry({
bool: {
filter: [
{ term: { [SERVICE_NAME]: serviceName } },
+ ...transactionNameFilter,
{ term: { [PROCESSOR_EVENT]: 'transaction' } },
- { term: { [TRANSACTION_TYPE]: 'page-load' } },
+ { term: { [TRANSACTION_TYPE]: TRANSACTION_PAGE_LOAD } },
{ exists: { field: CLIENT_GEO_COUNTRY_ISO_CODE } },
{ range: rangeFilter(start, end) },
...uiFiltersES
diff --git a/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.ts b/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.ts
index a21c4f38ac30c..3d425415de832 100644
--- a/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/transactions/breakdown/index.ts
@@ -151,56 +151,53 @@ export async function getTransactionBreakdown({
const bucketsByDate = idx(resp.aggregations, _ => _.by_date.buckets) || [];
- const timeseriesPerSubtype = bucketsByDate.reduce(
- (prev, bucket) => {
- const formattedValues = formatBucket(bucket);
- const time = bucket.key;
-
- const updatedSeries = kpiNames.reduce((p, kpiName) => {
- const { name, percentage } = formattedValues.find(
- val => val.name === kpiName
- ) || {
- name: kpiName,
- percentage: null
- };
-
- if (!p[name]) {
- p[name] = [];
- }
- return {
- ...p,
- [name]: p[name].concat({
- x: time,
- y: percentage
- })
- };
- }, prev);
-
- const lastValues = Object.values(updatedSeries).map(last);
-
- // If for a given timestamp, some series have data, but others do not,
- // we have to set any null values to 0 to make sure the stacked area chart
- // is drawn correctly.
- // If we set all values to 0, the chart always displays null values as 0,
- // and the chart looks weird.
- const hasAnyValues = lastValues.some(value => value.y !== null);
- const hasNullValues = lastValues.some(value => value.y === null);
-
- if (hasAnyValues && hasNullValues) {
- Object.values(updatedSeries).forEach(series => {
- const value = series[series.length - 1];
- const isEmpty = value.y === null;
- if (isEmpty) {
- // local mutation to prevent complicated map/reduce calls
- value.y = 0;
- }
- });
+ const timeseriesPerSubtype = bucketsByDate.reduce((prev, bucket) => {
+ const formattedValues = formatBucket(bucket);
+ const time = bucket.key;
+
+ const updatedSeries = kpiNames.reduce((p, kpiName) => {
+ const { name, percentage } = formattedValues.find(
+ val => val.name === kpiName
+ ) || {
+ name: kpiName,
+ percentage: null
+ };
+
+ if (!p[name]) {
+ p[name] = [];
}
+ return {
+ ...p,
+ [name]: p[name].concat({
+ x: time,
+ y: percentage
+ })
+ };
+ }, prev);
+
+ const lastValues = Object.values(updatedSeries).map(last);
+
+ // If for a given timestamp, some series have data, but others do not,
+ // we have to set any null values to 0 to make sure the stacked area chart
+ // is drawn correctly.
+ // If we set all values to 0, the chart always displays null values as 0,
+ // and the chart looks weird.
+ const hasAnyValues = lastValues.some(value => value.y !== null);
+ const hasNullValues = lastValues.some(value => value.y === null);
+
+ if (hasAnyValues && hasNullValues) {
+ Object.values(updatedSeries).forEach(series => {
+ const value = series[series.length - 1];
+ const isEmpty = value.y === null;
+ if (isEmpty) {
+ // local mutation to prevent complicated map/reduce calls
+ value.y = 0;
+ }
+ });
+ }
- return updatedSeries;
- },
- {} as Record>
- );
+ return updatedSeries;
+ }, {} as Record>);
const timeseries = kpis.map(kpi => ({
title: kpi.name,
diff --git a/x-pack/legacy/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts b/x-pack/legacy/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts
index 5d10a4ae27060..a0149bec728c5 100644
--- a/x-pack/legacy/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts
+++ b/x-pack/legacy/plugins/apm/server/lib/ui_filters/local_ui_filters/config.ts
@@ -61,17 +61,14 @@ export const localUIFilterNames = Object.keys(
filtersByName
) as LocalUIFilterName[];
-export const localUIFilters = localUIFilterNames.reduce(
- (acc, key) => {
- const field = filtersByName[key];
+export const localUIFilters = localUIFilterNames.reduce((acc, key) => {
+ const field = filtersByName[key];
- return {
- ...acc,
- [key]: {
- ...field,
- name: key
- }
- };
- },
- {} as LocalUIFilterMap
-);
+ return {
+ ...acc,
+ [key]: {
+ ...field,
+ name: key
+ }
+ };
+}, {} as LocalUIFilterMap);
diff --git a/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts b/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts
index 351afe618901e..e1cb1774469f2 100644
--- a/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts
+++ b/x-pack/legacy/plugins/apm/server/new-platform/plugin.ts
@@ -7,7 +7,6 @@
import { Server } from 'hapi';
import { CoreSetup } from 'src/core/server';
import { makeApmUsageCollector } from '../lib/apm_telemetry';
-import { LegacySetupWithUsageCollector } from '../lib/apm_telemetry/make_apm_usage_collector';
import { createApmAgentConfigurationIndex } from '../lib/settings/agent_configuration/create_agent_config_index';
import { createApmApi } from '../routes/create_apm_api';
@@ -19,6 +18,6 @@ export class Plugin {
public setup(core: CoreSetup, __LEGACY: LegacySetup) {
createApmApi().init(core, __LEGACY);
createApmAgentConfigurationIndex(core, __LEGACY);
- makeApmUsageCollector(core, __LEGACY as LegacySetupWithUsageCollector);
+ makeApmUsageCollector(core, __LEGACY);
}
}
diff --git a/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts b/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts
index 2ce27fbc5e5e4..66f28a9bf6d44 100644
--- a/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts
+++ b/x-pack/legacy/plugins/apm/server/routes/create_api/index.ts
@@ -68,41 +68,38 @@ export function createApi() {
const parsedParams = (Object.keys(rts) as Array<
keyof typeof rts
- >).reduce(
- (acc, key) => {
- const codec = rts[key];
- const value = paramMap[key];
+ >).reduce((acc, key) => {
+ const codec = rts[key];
+ const value = paramMap[key];
- const result = codec.decode(value);
+ const result = codec.decode(value);
- if (isLeft(result)) {
- throw Boom.badRequest(PathReporter.report(result)[0]);
- }
+ if (isLeft(result)) {
+ throw Boom.badRequest(PathReporter.report(result)[0]);
+ }
- const strippedKeys = difference(
- Object.keys(value || {}),
- Object.keys(result.right || {})
- );
+ const strippedKeys = difference(
+ Object.keys(value || {}),
+ Object.keys(result.right || {})
+ );
- if (strippedKeys.length) {
- throw Boom.badRequest(
- `Unknown keys specified: ${strippedKeys}`
- );
- }
+ if (strippedKeys.length) {
+ throw Boom.badRequest(
+ `Unknown keys specified: ${strippedKeys}`
+ );
+ }
- // hide _debug from route handlers
- const parsedValue =
- key === 'query'
- ? omit(result.right, '_debug')
- : result.right;
+ // hide _debug from route handlers
+ const parsedValue =
+ key === 'query'
+ ? omit(result.right, '_debug')
+ : result.right;
- return {
- ...acc,
- [key]: parsedValue
- };
- },
- {} as Record
- );
+ return {
+ ...acc,
+ [key]: parsedValue
+ };
+ }, {} as Record);
return route.handler(
request,
diff --git a/x-pack/legacy/plugins/apm/server/routes/services.ts b/x-pack/legacy/plugins/apm/server/routes/services.ts
index 26fdf2ab65d1a..4b955c7a6e981 100644
--- a/x-pack/legacy/plugins/apm/server/routes/services.ts
+++ b/x-pack/legacy/plugins/apm/server/routes/services.ts
@@ -6,7 +6,10 @@
import * as t from 'io-ts';
import { AgentName } from '../../typings/es_schemas/ui/fields/Agent';
-import { createApmTelementry, storeApmTelemetry } from '../lib/apm_telemetry';
+import {
+ createApmTelementry,
+ storeApmServicesTelemetry
+} from '../lib/apm_telemetry';
import { setupRequest } from '../lib/helpers/setup_request';
import { getServiceAgentName } from '../lib/services/get_service_agent_name';
import { getServices } from '../lib/services/get_services';
@@ -30,7 +33,7 @@ export const servicesRoute = createRoute((core, { server }) => ({
({ agentName }) => agentName as AgentName
);
const apmTelemetry = createApmTelementry(agentNames);
- storeApmTelemetry(server, apmTelemetry);
+ storeApmServicesTelemetry(server, apmTelemetry);
return services;
}
diff --git a/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts b/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts
index 40c29f3050455..4afcf135a1a76 100644
--- a/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts
+++ b/x-pack/legacy/plugins/apm/server/routes/settings/apm_indices.ts
@@ -5,7 +5,6 @@
*/
import * as t from 'io-ts';
-import { setupRequest } from '../../lib/helpers/setup_request';
import { createRoute } from '../create_route';
import {
getApmIndices,
@@ -18,8 +17,11 @@ export const apmIndexSettingsRoute = createRoute((core, { server }) => ({
method: 'GET',
path: '/api/apm/settings/apm-index-settings',
handler: async req => {
- const setup = await setupRequest(req);
- return await getApmIndexSettings({ setup, server });
+ const config = server.config();
+ const savedObjectsClient = req.server.savedObjects.getScopedSavedObjectsClient(
+ req
+ );
+ return await getApmIndexSettings({ config, savedObjectsClient });
}
}));
@@ -28,12 +30,16 @@ export const apmIndicesRoute = createRoute((core, { server }) => ({
method: 'GET',
path: '/api/apm/settings/apm-indices',
handler: async req => {
- return await getApmIndices(server);
+ const config = server.config();
+ const savedObjectsClient = req.server.savedObjects.getScopedSavedObjectsClient(
+ req
+ );
+ return await getApmIndices({ config, savedObjectsClient });
}
}));
// save ui indices
-export const saveApmIndicesRoute = createRoute((core, { server }) => ({
+export const saveApmIndicesRoute = createRoute(() => ({
method: 'POST',
path: '/api/apm/settings/apm-indices/save',
params: {
@@ -48,6 +54,9 @@ export const saveApmIndicesRoute = createRoute((core, { server }) => ({
})
},
handler: async (req, { body }) => {
- return await saveApmIndices(server, body);
+ const savedObjectsClient = req.server.savedObjects.getScopedSavedObjectsClient(
+ req
+ );
+ return await saveApmIndices(savedObjectsClient, body);
}
}));
diff --git a/x-pack/legacy/plugins/apm/server/routes/transaction_groups.ts b/x-pack/legacy/plugins/apm/server/routes/transaction_groups.ts
index cde9fd1dd4ca9..0b5c29fc29857 100644
--- a/x-pack/legacy/plugins/apm/server/routes/transaction_groups.ts
+++ b/x-pack/legacy/plugins/apm/server/routes/transaction_groups.ts
@@ -150,14 +150,20 @@ export const transactionGroupsAvgDurationByCountry = createRoute(() => ({
path: t.type({
serviceName: t.string
}),
- query: t.intersection([uiFiltersRt, rangeRt])
+ query: t.intersection([
+ uiFiltersRt,
+ rangeRt,
+ t.partial({ transactionName: t.string })
+ ])
},
handler: async (req, { path, query }) => {
const setup = await setupRequest(req);
const { serviceName } = path;
+ const { transactionName } = query;
return getTransactionAvgDurationByCountry({
serviceName,
+ transactionName,
setup
});
}
diff --git a/x-pack/legacy/plugins/apm/server/routes/typings.ts b/x-pack/legacy/plugins/apm/server/routes/typings.ts
index cf1a6cf769452..77d96d3677494 100644
--- a/x-pack/legacy/plugins/apm/server/routes/typings.ts
+++ b/x-pack/legacy/plugins/apm/server/routes/typings.ts
@@ -95,7 +95,9 @@ type GetOptionalParamKeys = keyof PickByValue<
{
[key in keyof TParams]: TParams[key] extends t.PartialType
? false
- : (TParams[key] extends t.Any ? true : false);
+ : TParams[key] extends t.Any
+ ? true
+ : false;
},
false
>;
diff --git a/x-pack/legacy/plugins/apm/server/routes/ui_filters.ts b/x-pack/legacy/plugins/apm/server/routes/ui_filters.ts
index 9d36946d29cf6..36508e53acce7 100644
--- a/x-pack/legacy/plugins/apm/server/routes/ui_filters.ts
+++ b/x-pack/legacy/plugins/apm/server/routes/ui_filters.ts
@@ -45,9 +45,11 @@ export const uiFiltersEnvironmentsRoute = createRoute(() => ({
const filterNamesRt = t.type({
filterNames: jsonRt.pipe(
t.array(
- t.keyof(Object.fromEntries(
- localUIFilterNames.map(filterName => [filterName, null])
- ) as Record)
+ t.keyof(
+ Object.fromEntries(
+ localUIFilterNames.map(filterName => [filterName, null])
+ ) as Record
+ )
)
)
});
diff --git a/x-pack/legacy/plugins/apm/typings/elasticsearch/aggregations.ts b/x-pack/legacy/plugins/apm/typings/elasticsearch/aggregations.ts
index 9f17b0197a5b2..b694e9526e2b8 100644
--- a/x-pack/legacy/plugins/apm/typings/elasticsearch/aggregations.ts
+++ b/x-pack/legacy/plugins/apm/typings/elasticsearch/aggregations.ts
@@ -202,22 +202,19 @@ interface AggregationResponsePart<
TDocument
>
>
- : (TAggregationOptionsMap extends {
+ : TAggregationOptionsMap extends {
filters: {
filters: Record;
};
}
- ? {
- buckets: {
- [key in keyof TAggregationOptionsMap['filters']['filters']]: {
- doc_count: number;
- } & AggregationResponseMap<
- TAggregationOptionsMap['aggs'],
- TDocument
- >;
- };
- }
- : never);
+ ? {
+ buckets: {
+ [key in keyof TAggregationOptionsMap['filters']['filters']]: {
+ doc_count: number;
+ } & AggregationResponseMap;
+ };
+ }
+ : never;
sampler: {
doc_count: number;
} & AggregationResponseMap;
diff --git a/x-pack/legacy/plugins/apm/typings/elasticsearch/index.ts b/x-pack/legacy/plugins/apm/typings/elasticsearch/index.ts
index 56cd0ff23a3fb..eff39838bd957 100644
--- a/x-pack/legacy/plugins/apm/typings/elasticsearch/index.ts
+++ b/x-pack/legacy/plugins/apm/typings/elasticsearch/index.ts
@@ -36,8 +36,7 @@ export type ESSearchResponse<
TDocument
>;
}
- : {}) &
- ({
+ : {}) & {
hits: Omit['hits'], 'total'> &
(TOptions['restTotalHitsAsInt'] extends true
? {
@@ -49,7 +48,7 @@ export type ESSearchResponse<
relation: 'eq' | 'gte';
};
});
- });
+ };
export interface ESFilter {
[key: string]: {
diff --git a/x-pack/legacy/plugins/beats_management/common/config_block_validation.ts b/x-pack/legacy/plugins/beats_management/common/config_block_validation.ts
index 92137bdf5cc6e..8972084018d98 100644
--- a/x-pack/legacy/plugins/beats_management/common/config_block_validation.ts
+++ b/x-pack/legacy/plugins/beats_management/common/config_block_validation.ts
@@ -27,20 +27,17 @@ export const validateConfigurationBlocks = (configurationBlocks: ConfigurationBl
);
}
- const interfaceConfig = blockSchema.configs.reduce(
- (props, config) => {
- if (config.options) {
- props[config.id] = t.keyof(Object.fromEntries(
- config.options.map(opt => [opt.value, null])
- ) as Record);
- } else if (config.validation) {
- props[config.id] = validationMap[config.validation];
- }
+ const interfaceConfig = blockSchema.configs.reduce((props, config) => {
+ if (config.options) {
+ props[config.id] = t.keyof(
+ Object.fromEntries(config.options.map(opt => [opt.value, null])) as Record
+ );
+ } else if (config.validation) {
+ props[config.id] = validationMap[config.validation];
+ }
- return props;
- },
- {} as t.Props
- );
+ return props;
+ }, {} as t.Props);
const runtimeInterface = createConfigurationBlockInterface(
t.literal(blockSchema.id),
diff --git a/x-pack/legacy/plugins/beats_management/common/domain_types.ts b/x-pack/legacy/plugins/beats_management/common/domain_types.ts
index 0d5c67d09da8a..bc77abc9815be 100644
--- a/x-pack/legacy/plugins/beats_management/common/domain_types.ts
+++ b/x-pack/legacy/plugins/beats_management/common/domain_types.ts
@@ -13,9 +13,9 @@ export const OutputTypesArray = ['elasticsearch', 'logstash', 'kafka', 'redis'];
// We can also pass in optional params to create spacific runtime checks that
// can be used to validate blocs on the API and UI
export const createConfigurationBlockInterface = (
- configType: t.LiteralType | t.KeyofC> = t.keyof(Object.fromEntries(
- configBlockSchemas.map(s => [s.id, null])
- ) as Record),
+ configType: t.LiteralType | t.KeyofC> = t.keyof(
+ Object.fromEntries(configBlockSchemas.map(s => [s.id, null])) as Record
+ ),
beatConfigInterface: t.Mixed = t.Dictionary
) =>
t.interface(
diff --git a/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/index.tsx b/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/index.tsx
index 479be32ce1e12..3ac2ff72c0116 100644
--- a/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/index.tsx
+++ b/x-pack/legacy/plugins/beats_management/public/components/autocomplete_field/index.tsx
@@ -265,13 +265,11 @@ const withSuggestionsHidden = (state: AutocompleteFieldState) => ({
selectedIndex: null,
});
-const FixedEuiFieldSearch: React.SFC<
- React.InputHTMLAttributes &
- EuiFieldSearchProps & {
- inputRef?: (element: HTMLInputElement | null) => void;
- onSearch: (value: string) => void;
- }
-> = EuiFieldSearch as any;
+const FixedEuiFieldSearch: React.SFC &
+ EuiFieldSearchProps & {
+ inputRef?: (element: HTMLInputElement | null) => void;
+ onSearch: (value: string) => void;
+ }> = EuiFieldSearch as any;
const AutocompleteContainer = styled.div`
position: relative;
diff --git a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx b/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx
index 8736663dd08af..f15e08c2ca230 100644
--- a/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx
+++ b/x-pack/legacy/plugins/beats_management/public/components/navigation/breadcrumb/provider.tsx
@@ -53,16 +53,13 @@ export class BreadcrumbProvider extends Component {
- if (crumbStorageItem.parents) {
- crumbs = crumbs.concat(crumbStorageItem.parents);
- }
- crumbs.push(crumbStorageItem.breadcrumb);
- return crumbs;
- },
- [] as Breadcrumb[]
- ),
+ breadcrumbs: breadcrumbs.reduce((crumbs, crumbStorageItem) => {
+ if (crumbStorageItem.parents) {
+ crumbs = crumbs.concat(crumbStorageItem.parents);
+ }
+ crumbs.push(crumbStorageItem.breadcrumb);
+ return crumbs;
+ }, [] as Breadcrumb[]),
addCrumb: this.addCrumb,
removeCrumb: this.removeCrumb,
};
diff --git a/x-pack/legacy/plugins/beats_management/public/components/table/table_type_configs.tsx b/x-pack/legacy/plugins/beats_management/public/components/table/table_type_configs.tsx
index a93000a3e80f0..6f03f884563e1 100644
--- a/x-pack/legacy/plugins/beats_management/public/components/table/table_type_configs.tsx
+++ b/x-pack/legacy/plugins/beats_management/public/components/table/table_type_configs.tsx
@@ -246,7 +246,10 @@ export const BeatsTableType: TableType = {
name: i18n.translate('xpack.beatsManagement.beatsTable.typeLabel', {
defaultMessage: 'Type',
}),
- options: uniq(data.map(({ type }: { type: any }) => ({ value: type })), 'value'),
+ options: uniq(
+ data.map(({ type }: { type: any }) => ({ value: type })),
+ 'value'
+ ),
},
],
}),
diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts b/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts
index 4a7f768bd4740..b2e11461007fd 100644
--- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts
+++ b/x-pack/legacy/plugins/beats_management/public/lib/adapters/beats/rest_beats_adapter.ts
@@ -26,9 +26,9 @@ export class RestBeatsAdapter implements CMBeatsAdapter {
public async getBeatWithToken(enrollmentToken: string): Promise {
try {
- return (await this.REST.get>(
- `/api/beats/agent/unknown/${enrollmentToken}`
- )).item;
+ return (
+ await this.REST.get>(`/api/beats/agent/unknown/${enrollmentToken}`)
+ ).item;
} catch (e) {
return null;
}
@@ -59,16 +59,20 @@ export class RestBeatsAdapter implements CMBeatsAdapter {
public async removeTagsFromBeats(
removals: BeatsTagAssignment[]
): Promise {
- return (await this.REST.post(`/api/beats/agents_tags/removals`, {
- removals,
- })).results;
+ return (
+ await this.REST.post(`/api/beats/agents_tags/removals`, {
+ removals,
+ })
+ ).results;
}
public async assignTagsToBeats(
assignments: BeatsTagAssignment[]
): Promise {
- return (await this.REST.post(`/api/beats/agents_tags/assignments`, {
- assignments,
- })).results;
+ return (
+ await this.REST.post(`/api/beats/agents_tags/assignments`, {
+ assignments,
+ })
+ ).results;
}
}
diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts b/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts
index 31c55b9272193..190c9e265463d 100644
--- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts
+++ b/x-pack/legacy/plugins/beats_management/public/lib/adapters/tags/rest_tags_adapter.ts
@@ -20,9 +20,9 @@ export class RestTagsAdapter implements CMTagsAdapter {
public async getTagsWithIds(tagIds: string[]): Promise {
try {
- return (await this.REST.get>(
- `/api/beats/tags/${uniq(tagIds).join(',')}`
- )).items;
+ return (
+ await this.REST.get>(`/api/beats/tags/${uniq(tagIds).join(',')}`)
+ ).items;
} catch (e) {
return [];
}
@@ -37,9 +37,9 @@ export class RestTagsAdapter implements CMTagsAdapter {
}
public async delete(tagIds: string[]): Promise {
- return (await this.REST.delete(
- `/api/beats/tags/${uniq(tagIds).join(',')}`
- )).success;
+ return (
+ await this.REST.delete(`/api/beats/tags/${uniq(tagIds).join(',')}`)
+ ).success;
}
public async upsertTag(tag: BeatTag): Promise {
@@ -53,9 +53,11 @@ export class RestTagsAdapter implements CMTagsAdapter {
public async getAssignable(beats: CMBeat[]) {
try {
- return (await this.REST.get>(
- `/api/beats/tags/assignable/${beats.map(beat => beat.id).join(',')}`
- )).items;
+ return (
+ await this.REST.get>(
+ `/api/beats/tags/assignable/${beats.map(beat => beat.id).join(',')}`
+ )
+ ).items;
} catch (e) {
return [];
}
diff --git a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts b/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts
index 8274764e759ab..92cfcc935ad9b 100644
--- a/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts
+++ b/x-pack/legacy/plugins/beats_management/public/lib/adapters/tokens/rest_tokens_adapter.ts
@@ -12,12 +12,11 @@ export class RestTokensAdapter implements CMTokensAdapter {
constructor(private readonly REST: RestAPIAdapter) {}
public async createEnrollmentTokens(numTokens: number = 1): Promise {
- const results = (await this.REST.post>(
- '/api/beats/enrollment_tokens',
- {
+ const results = (
+ await this.REST.post>('/api/beats/enrollment_tokens', {
num_tokens: numTokens,
- }
- )).results;
+ })
+ ).results;
return results.map(result => result.item);
}
}
diff --git a/x-pack/legacy/plugins/beats_management/public/lib/compose/scripts.ts b/x-pack/legacy/plugins/beats_management/public/lib/compose/scripts.ts
index 4718abc1b7153..83129384a77df 100644
--- a/x-pack/legacy/plugins/beats_management/public/lib/compose/scripts.ts
+++ b/x-pack/legacy/plugins/beats_management/public/lib/compose/scripts.ts
@@ -22,7 +22,11 @@ import { FrontendLibs } from '../types';
export function compose(basePath: string): FrontendLibs {
const api = new NodeAxiosAPIAdapter('elastic', 'changeme', basePath);
- const esAdapter = new MemoryElasticsearchAdapter(() => true, () => '', []);
+ const esAdapter = new MemoryElasticsearchAdapter(
+ () => true,
+ () => '',
+ []
+ );
const elasticsearchLib = new ElasticsearchLib(esAdapter);
const configBlocks = new ConfigBlocksLib(
new RestConfigBlocksAdapter(api),
diff --git a/x-pack/legacy/plugins/beats_management/public/utils/typed_react.ts b/x-pack/legacy/plugins/beats_management/public/utils/typed_react.ts
index 5557befa9d7e5..dbc0894ab8071 100644
--- a/x-pack/legacy/plugins/beats_management/public/utils/typed_react.ts
+++ b/x-pack/legacy/plugins/beats_management/public/utils/typed_react.ts
@@ -43,7 +43,9 @@ export const asChildFunctionRenderer =