').height(SCROLLER_HEIGHT);
+
+ /**
+ * Remove the listeners bound in listen()
+ * @type {function}
+ */
+ let unlisten = _.noop;
+
+ /**
+ * Listen for scroll events on the $scroller and the $el, sets unlisten()
+ *
+ * unlisten must be called before calling or listen() will throw an Error
+ *
+ * Since the browser emits "scroll" events after setting scrollLeft
+ * the listeners also prevent tug-of-war
+ *
+ * @throws {Error} If unlisten was not called first
+ * @return {undefined}
+ */
+ function listen() {
+ if (unlisten !== _.noop) {
+ throw new Error('fixedScroll listeners were not cleaned up properly before re-listening!');
}
- let width;
- let scrollWidth;
- function checkWidth() {
- const newScrollWidth = $el.prop('scrollWidth');
- const newWidth = $el.width();
-
- if (scrollWidth !== newScrollWidth || width !== newWidth) {
- $scope.$apply(setup);
-
- scrollWidth = newScrollWidth;
- width = newWidth;
+ let blockTo;
+ function bind($from, $to) {
+ function handler() {
+ if (blockTo === $to) return (blockTo = null);
+ $to.scrollLeft((blockTo = $from).scrollLeft());
}
- }
- const debouncedCheckWidth = debounce(checkWidth, 100, {
- invokeApply: false,
- });
- $scope.$watch(debouncedCheckWidth);
+ $from.on('scroll', handler);
+ return function () {
+ $from.off('scroll', handler);
+ };
+ }
- // cleanup when the scope is destroyed
- $scope.$on('$destroy', function () {
- cleanUp();
- debouncedCheckWidth.cancel();
- $scroller = $window = null;
+ unlisten = _.flow(bind($el, $scroller), bind($scroller, $el), function () {
+ unlisten = _.noop;
});
- },
+ }
+
+ /**
+ * Revert DOM changes and event listeners
+ * @return {undefined}
+ */
+ function cleanUp() {
+ unlisten();
+ $scroller.detach();
+ $el.css('padding-bottom', 0);
+ }
+
+ /**
+ * Modify the DOM and attach event listeners based on need.
+ * Is called many times to re-setup, must be idempotent
+ * @return {undefined}
+ */
+ function setup() {
+ cleanUp();
+
+ const containerWidth = $el.width();
+ const contentWidth = $el.prop('scrollWidth');
+ const containerHorizOverflow = contentWidth - containerWidth;
+
+ const elTop = $el.offset().top - $window.scrollTop();
+ const elBottom = elTop + $el.height();
+ const windowVertOverflow = elBottom - $window.height();
+
+ const requireScroller = containerHorizOverflow > 0 && windowVertOverflow > 0;
+ if (!requireScroller) return;
+
+ // push the content away from the scroller
+ $el.css('padding-bottom', SCROLLER_HEIGHT);
+
+ // fill the scroller with a dummy element that mimics the content
+ $scroller
+ .width(containerWidth)
+ .html($('
').css({ width: contentWidth, height: SCROLLER_HEIGHT }))
+ .insertAfter($el);
+
+ // listen for scroll events
+ listen();
+ }
+
+ let width;
+ let scrollWidth;
+ function checkWidth() {
+ const newScrollWidth = $el.prop('scrollWidth');
+ const newWidth = $el.width();
+
+ if (scrollWidth !== newScrollWidth || width !== newWidth) {
+ $scope.$apply(setup);
+
+ scrollWidth = newScrollWidth;
+ width = newWidth;
+ }
+ }
+
+ const debouncedCheckWidth = debounce(checkWidth, 100, {
+ invokeApply: false,
+ });
+ $scope.$watch(debouncedCheckWidth);
+
+ function destroy() {
+ cleanUp();
+ debouncedCheckWidth.cancel();
+ $scroller = $window = null;
+ }
+ return destroy;
};
}
diff --git a/src/plugins/discover/public/application/angular/directives/fixed_scroll.test.js b/src/plugins/discover/public/application/angular/directives/fixed_scroll.test.js
index 16293ca621e05..0e40499d1c9b5 100644
--- a/src/plugins/discover/public/application/angular/directives/fixed_scroll.test.js
+++ b/src/plugins/discover/public/application/angular/directives/fixed_scroll.test.js
@@ -23,17 +23,12 @@ import $ from 'jquery';
import sinon from 'sinon';
-import { PrivateProvider, initAngularBootstrap } from '../../../../../kibana_legacy/public';
+import { initAngularBootstrap } from '../../../../../kibana_legacy/public';
import { FixedScrollProvider } from './fixed_scroll';
-import { DebounceProviderTimeout } from './debounce/debounce';
const testModuleName = 'fixedScroll';
-angular
- .module(testModuleName, [])
- .provider('Private', PrivateProvider)
- .service('debounce', ['$timeout', DebounceProviderTimeout])
- .directive('fixedScroll', FixedScrollProvider);
+angular.module(testModuleName, []).directive('fixedScroll', FixedScrollProvider);
describe('FixedScroll directive', function () {
const sandbox = sinon.createSandbox();
@@ -127,7 +122,7 @@ describe('FixedScroll directive', function () {
return {
$container: $el,
$content: $content,
- $scroller: $parent.find('.fixed-scroll-scroller'),
+ $scroller: $parent.find('.dscTableFixedScroll__scroller'),
};
};
});
diff --git a/src/plugins/discover/public/application/angular/directives/no_results.js b/src/plugins/discover/public/application/angular/directives/no_results.js
index 965c1271c2f2c..d8a39d9178e93 100644
--- a/src/plugins/discover/public/application/angular/directives/no_results.js
+++ b/src/plugins/discover/public/application/angular/directives/no_results.js
@@ -24,7 +24,6 @@ import PropTypes from 'prop-types';
import {
EuiCallOut,
EuiCode,
- EuiCodeBlock,
EuiDescriptionList,
EuiFlexGroup,
EuiFlexItem,
@@ -37,72 +36,12 @@ import { getServices } from '../../../kibana_services';
// eslint-disable-next-line react/prefer-stateless-function
export class DiscoverNoResults extends Component {
static propTypes = {
- shardFailures: PropTypes.array,
timeFieldName: PropTypes.string,
queryLanguage: PropTypes.string,
};
render() {
- const { shardFailures, timeFieldName, queryLanguage } = this.props;
-
- let shardFailuresMessage;
-
- if (shardFailures && shardFailures.length) {
- const failures = shardFailures.map((failure, index) => (
-
-
-
-
-
- ),
- failureShard: `‘${failure.shard}’`,
- }}
- />
-
-
-
-
- {JSON.stringify(failure.reason)}
-
- {index < shardFailures.length - 1 ? : undefined}
-
- ));
-
- shardFailuresMessage = (
-
-
-
-
-
-
-
-
-
-
-
-
- {failures}
-
-
- );
- }
+ const { timeFieldName, queryLanguage } = this.props;
let timeFieldMessage;
@@ -264,8 +203,6 @@ export class DiscoverNoResults extends Component {
iconType="help"
data-test-subj="discoverNoResults"
/>
-
- {shardFailuresMessage}
{timeFieldMessage}
{luceneQueryMessage}
diff --git a/src/plugins/discover/public/application/angular/directives/no_results.test.js b/src/plugins/discover/public/application/angular/directives/no_results.test.js
index 7de792c612993..60c50048a39ef 100644
--- a/src/plugins/discover/public/application/angular/directives/no_results.test.js
+++ b/src/plugins/discover/public/application/angular/directives/no_results.test.js
@@ -42,35 +42,6 @@ beforeEach(() => {
describe('DiscoverNoResults', () => {
describe('props', () => {
- describe('shardFailures', () => {
- test('renders failures list when there are failures', () => {
- const shardFailures = [
- {
- index: 'A',
- shard: '1',
- reason: { reason: 'Awful error' },
- },
- {
- index: 'B',
- shard: '2',
- reason: { reason: 'Bad error' },
- },
- ];
-
- const component = renderWithIntl(
);
-
- expect(component).toMatchSnapshot();
- });
-
- test(`doesn't render failures list when there are no failures`, () => {
- const shardFailures = [];
-
- const component = renderWithIntl(
);
-
- expect(component).toMatchSnapshot();
- });
- });
-
describe('timeFieldName', () => {
test('renders time range feedback', () => {
const component = renderWithIntl(
);
diff --git a/src/plugins/discover/public/application/angular/discover.html b/src/plugins/discover/public/application/angular/discover.html
deleted file mode 100644
index e0e452aaa41c5..0000000000000
--- a/src/plugins/discover/public/application/angular/discover.html
+++ /dev/null
@@ -1,160 +0,0 @@
-
- {{screenTitle}}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/plugins/discover/public/application/angular/discover.js b/src/plugins/discover/public/application/angular/discover.js
index b75ac75e5f2ed..7871cc4b16464 100644
--- a/src/plugins/discover/public/application/angular/discover.js
+++ b/src/plugins/discover/public/application/angular/discover.js
@@ -29,12 +29,11 @@ import { getState, splitState } from './discover_state';
import { RequestAdapter } from '../../../../inspector/public';
import { SavedObjectSaveModal, showSaveModal } from '../../../../saved_objects/public';
import { getSortArray, getSortForSearchSource } from './doc_table';
+import { createFixedScroll } from './directives/fixed_scroll';
import * as columnActions from './doc_table/actions/columns';
-
-import indexTemplate from './discover.html';
+import indexTemplateLegacy from './discover_legacy.html';
import { showOpenSearchPanel } from '../components/top_nav/show_open_search_panel';
import { addHelpMenuToAppChrome } from '../components/help_menu/help_menu_util';
-import '../components/fetch_error';
import { getPainlessError } from './get_painless_error';
import { discoverResponseHandler } from './response_handler';
import {
@@ -71,7 +70,6 @@ import {
indexPatterns as indexPatternsUtils,
connectToQueryState,
syncQueryStateWithUrl,
- search,
} from '../../../../data/public';
import { getIndexPatternId } from '../helpers/get_index_pattern_id';
import { addFatalError } from '../../../../kibana_legacy/public';
@@ -115,7 +113,7 @@ app.config(($routeProvider) => {
};
const discoverRoute = {
...defaults,
- template: indexTemplate,
+ template: indexTemplateLegacy,
reloadOnSearch: false,
resolve: {
savedObjects: function ($route, Promise) {
@@ -308,18 +306,10 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
mode: 'absolute',
});
};
- $scope.intervalOptions = search.aggs.intervalOptions;
$scope.minimumVisibleRows = 50;
$scope.fetchStatus = fetchStatuses.UNINITIALIZED;
$scope.showSaveQuery = uiCapabilities.discover.saveQuery;
- $scope.$watch(
- () => uiCapabilities.discover.saveQuery,
- (newCapability) => {
- $scope.showSaveQuery = newCapability;
- }
- );
-
let abortController;
$scope.$on('$destroy', () => {
if (abortController) abortController.abort();
@@ -471,7 +461,6 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
];
};
$scope.topNavMenu = getTopNavLinks();
- $scope.setHeaderActionMenu = getHeaderActionMenuMounter();
$scope.searchSource
.setField('index', $scope.indexPattern)
@@ -515,8 +504,6 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
]);
}
- $scope.screenTitle = savedSearch.title;
-
const getFieldCounts = async () => {
// the field counts aren't set until we have the data back,
// so we wait for the fetch to be done before proceeding
@@ -612,6 +599,9 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
timefield: getTimeField(),
savedSearch: savedSearch,
indexPatternList: $route.current.locals.savedObjects.ip.list,
+ config: config,
+ fixedScroll: createFixedScroll($scope, $timeout),
+ setHeaderActionMenu: getHeaderActionMenuMounter(),
};
const shouldSearchOnPageLoad = () => {
@@ -771,6 +761,7 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
if (!init.complete) return;
$scope.fetchCounter++;
$scope.fetchError = undefined;
+ $scope.minimumVisibleRows = 50;
if (!validateTimeRange(timefilter.getTime(), toastNotifications)) {
$scope.resultState = 'none';
return;
@@ -868,9 +859,6 @@ function discoverController($element, $route, $scope, $timeout, $window, Promise
tabifiedData,
getDimensions($scope.vis.data.aggs.aggs, $scope.timeRange)
);
- if ($scope.vis.data.aggs.aggs[1]) {
- $scope.bucketInterval = $scope.vis.data.aggs.aggs[1].buckets.getInterval();
- }
$scope.updateTime();
}
diff --git a/src/plugins/discover/public/application/angular/discover_legacy.html b/src/plugins/discover/public/application/angular/discover_legacy.html
new file mode 100644
index 0000000000000..8582f71c0cb88
--- /dev/null
+++ b/src/plugins/discover/public/application/angular/discover_legacy.html
@@ -0,0 +1,36 @@
+
+
+
+
diff --git a/src/plugins/discover/public/application/angular/discover_state.ts b/src/plugins/discover/public/application/angular/discover_state.ts
index ac0dc054485f0..5ddb6a92b5fd4 100644
--- a/src/plugins/discover/public/application/angular/discover_state.ts
+++ b/src/plugins/discover/public/application/angular/discover_state.ts
@@ -55,6 +55,10 @@ export interface AppState {
* Array of the used sorting [[field,direction],...]
*/
sort?: string[][];
+ /**
+ * id of the used saved query
+ */
+ savedQuery?: string;
}
interface GetStateParams {
diff --git a/src/plugins/discover/public/application/angular/doc_table/create_doc_table_react.tsx b/src/plugins/discover/public/application/angular/doc_table/create_doc_table_react.tsx
new file mode 100644
index 0000000000000..ad2b674af014c
--- /dev/null
+++ b/src/plugins/discover/public/application/angular/doc_table/create_doc_table_react.tsx
@@ -0,0 +1,131 @@
+/*
+ * 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 angular, { auto, ICompileService, IScope } from 'angular';
+import { render } from 'react-dom';
+import React, { useRef, useEffect } from 'react';
+import { getServices, IIndexPattern } from '../../../kibana_services';
+import { IndexPatternField } from '../../../../../data/common/index_patterns';
+export type AngularScope = IScope;
+
+export interface AngularDirective {
+ template: string;
+}
+
+/**
+ * Compiles and injects the give angular template into the given dom node
+ * returns a function to cleanup the injected angular element
+ */
+export async function injectAngularElement(
+ domNode: Element,
+ template: string,
+ scopeProps: any,
+ getInjector: () => Promise
+): Promise<() => void> {
+ const $injector = await getInjector();
+ const rootScope: AngularScope = $injector.get('$rootScope');
+ const $compile: ICompileService = $injector.get('$compile');
+ const newScope = Object.assign(rootScope.$new(), scopeProps);
+
+ const $target = angular.element(domNode);
+ const $element = angular.element(template);
+
+ newScope.$apply(() => {
+ const linkFn = $compile($element);
+ $target.empty().append($element);
+ linkFn(newScope);
+ });
+
+ return () => {
+ newScope.$destroy();
+ };
+}
+
+/**
+ * Converts a given legacy angular directive to a render function
+ * for usage in a react component. Note that the rendering is async
+ */
+export function convertDirectiveToRenderFn(
+ directive: AngularDirective,
+ getInjector: () => Promise
+) {
+ return (domNode: Element, props: any) => {
+ let rejected = false;
+
+ const cleanupFnPromise = injectAngularElement(domNode, directive.template, props, getInjector);
+ cleanupFnPromise.catch(() => {
+ rejected = true;
+ render(error
, domNode);
+ });
+
+ return () => {
+ if (!rejected) {
+ // for cleanup
+ // http://roubenmeschian.com/rubo/?p=51
+ cleanupFnPromise.then((cleanup) => cleanup());
+ }
+ };
+ };
+}
+
+export interface DocTableLegacyProps {
+ columns: string[];
+ searchDescription?: string;
+ searchTitle?: string;
+ onFilter: (field: IndexPatternField | string, value: string, type: '+' | '-') => void;
+ rows: Array>;
+ indexPattern: IIndexPattern;
+ minimumVisibleRows: number;
+ onAddColumn: (column: string) => void;
+ onSort: (sort: string[][]) => void;
+ onMoveColumn: (columns: string, newIdx: number) => void;
+ onRemoveColumn: (column: string) => void;
+ sort?: string[][];
+}
+
+export function DocTableLegacy(renderProps: DocTableLegacyProps) {
+ const renderFn = convertDirectiveToRenderFn(
+ {
+ template: ``,
+ },
+ () => getServices().getEmbeddableInjector()
+ );
+ const ref = useRef(null);
+ useEffect(() => {
+ if (ref && ref.current) {
+ return renderFn(ref.current, renderProps);
+ }
+ }, [renderFn, renderProps]);
+ return ;
+}
diff --git a/src/plugins/discover/public/application/angular/doc_table/doc_table.ts b/src/plugins/discover/public/application/angular/doc_table/doc_table.ts
index f972c158ff3dd..735ee9f555740 100644
--- a/src/plugins/discover/public/application/angular/doc_table/doc_table.ts
+++ b/src/plugins/discover/public/application/angular/doc_table/doc_table.ts
@@ -50,10 +50,6 @@ export function createDocTableDirective(pagerFactory: any, $filter: any) {
inspectorAdapters: '=?',
},
link: ($scope: LazyScope, $el: JQuery) => {
- $scope.$watch('minimumVisibleRows', (minimumVisibleRows: number) => {
- $scope.limit = Math.max(minimumVisibleRows || 50, $scope.limit || 50);
- });
-
$scope.persist = {
sorting: $scope.sorting,
columns: $scope.columns,
@@ -77,7 +73,7 @@ export function createDocTableDirective(pagerFactory: any, $filter: any) {
if (!hits) return;
// Reset infinite scroll limit
- $scope.limit = 50;
+ $scope.limit = $scope.minimumVisibleRows || 50;
if (hits.length === 0) {
dispatchRenderComplete($el[0]);
diff --git a/src/plugins/discover/public/application/components/create_discover_legacy_directive.ts b/src/plugins/discover/public/application/components/create_discover_legacy_directive.ts
new file mode 100644
index 0000000000000..a3502cbb211fa
--- /dev/null
+++ b/src/plugins/discover/public/application/components/create_discover_legacy_directive.ts
@@ -0,0 +1,56 @@
+/*
+ * 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 { DiscoverLegacy } from './discover_legacy';
+
+export function createDiscoverLegacyDirective(reactDirective: any) {
+ return reactDirective(DiscoverLegacy, [
+ ['addColumn', { watchDepth: 'reference' }],
+ ['fetch', { watchDepth: 'reference' }],
+ ['fetchCounter', { watchDepth: 'reference' }],
+ ['fetchError', { watchDepth: 'reference' }],
+ ['fieldCounts', { watchDepth: 'reference' }],
+ ['histogramData', { watchDepth: 'reference' }],
+ ['hits', { watchDepth: 'reference' }],
+ ['indexPattern', { watchDepth: 'reference' }],
+ ['minimumVisibleRows', { watchDepth: 'reference' }],
+ ['onAddFilter', { watchDepth: 'reference' }],
+ ['onChangeInterval', { watchDepth: 'reference' }],
+ ['onMoveColumn', { watchDepth: 'reference' }],
+ ['onRemoveColumn', { watchDepth: 'reference' }],
+ ['onSetColumns', { watchDepth: 'reference' }],
+ ['onSkipBottomButtonClick', { watchDepth: 'reference' }],
+ ['onSort', { watchDepth: 'reference' }],
+ ['opts', { watchDepth: 'reference' }],
+ ['resetQuery', { watchDepth: 'reference' }],
+ ['resultState', { watchDepth: 'reference' }],
+ ['rows', { watchDepth: 'reference' }],
+ ['savedSearch', { watchDepth: 'reference' }],
+ ['searchSource', { watchDepth: 'reference' }],
+ ['setIndexPattern', { watchDepth: 'reference' }],
+ ['showSaveQuery', { watchDepth: 'reference' }],
+ ['state', { watchDepth: 'reference' }],
+ ['timefilterUpdateHandler', { watchDepth: 'reference' }],
+ ['timeRange', { watchDepth: 'reference' }],
+ ['topNavMenu', { watchDepth: 'reference' }],
+ ['updateQuery', { watchDepth: 'reference' }],
+ ['updateSavedQueryId', { watchDepth: 'reference' }],
+ ['vis', { watchDepth: 'reference' }],
+ ]);
+}
diff --git a/src/plugins/discover/public/application/components/discover_legacy.tsx b/src/plugins/discover/public/application/components/discover_legacy.tsx
new file mode 100644
index 0000000000000..1a98843649259
--- /dev/null
+++ b/src/plugins/discover/public/application/components/discover_legacy.tsx
@@ -0,0 +1,324 @@
+/*
+ * 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, { useState, useCallback, useEffect } from 'react';
+import classNames from 'classnames';
+import { EuiButtonEmpty, EuiButtonIcon } from '@elastic/eui';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
+import { IUiSettingsClient, MountPoint } from 'kibana/public';
+import { HitsCounter } from './hits_counter';
+import { TimechartHeader } from './timechart_header';
+import { DiscoverSidebar } from './sidebar';
+import { getServices, IIndexPattern } from '../../kibana_services';
+// @ts-ignore
+import { DiscoverNoResults } from '../angular/directives/no_results';
+import { DiscoverUninitialized } from '../angular/directives/uninitialized';
+import { DiscoverHistogram } from '../angular/directives/histogram';
+import { LoadingSpinner } from './loading_spinner/loading_spinner';
+import { DiscoverFetchError, FetchError } from './fetch_error/fetch_error';
+import { DocTableLegacy } from '../angular/doc_table/create_doc_table_react';
+import { SkipBottomButton } from './skip_bottom_button';
+import {
+ IndexPatternField,
+ search,
+ ISearchSource,
+ TimeRange,
+ Query,
+ IndexPatternAttributes,
+} from '../../../../data/public';
+import { Chart } from '../angular/helpers/point_series';
+import { AppState } from '../angular/discover_state';
+import { SavedSearch } from '../../saved_searches';
+
+import { SavedObject } from '../../../../../core/types';
+import { Vis } from '../../../../visualizations/public';
+import { TopNavMenuData } from '../../../../navigation/public';
+
+export interface DiscoverLegacyProps {
+ addColumn: (column: string) => void;
+ fetch: () => void;
+ fetchCounter: number;
+ fetchError: FetchError;
+ fieldCounts: Record;
+ histogramData: Chart;
+ hits: number;
+ indexPattern: IIndexPattern;
+ minimumVisibleRows: number;
+ onAddFilter: (field: IndexPatternField | string, value: string, type: '+' | '-') => void;
+ onChangeInterval: (interval: string) => void;
+ onMoveColumn: (columns: string, newIdx: number) => void;
+ onRemoveColumn: (column: string) => void;
+ onSetColumns: (columns: string[]) => void;
+ onSkipBottomButtonClick: () => void;
+ onSort: (sort: string[][]) => void;
+ opts: {
+ savedSearch: SavedSearch;
+ config: IUiSettingsClient;
+ indexPatternList: Array>;
+ timefield: string;
+ sampleSize: number;
+ fixedScroll: (el: HTMLElement) => void;
+ setHeaderActionMenu: (menuMount: MountPoint | undefined) => void;
+ };
+ resetQuery: () => void;
+ resultState: string;
+ rows: Array>;
+ searchSource: ISearchSource;
+ setIndexPattern: (id: string) => void;
+ showSaveQuery: boolean;
+ state: AppState;
+ timefilterUpdateHandler: (ranges: { from: number; to: number }) => void;
+ timeRange?: { from: string; to: string };
+ topNavMenu: TopNavMenuData[];
+ updateQuery: (payload: { dateRange: TimeRange; query?: Query }, isUpdate?: boolean) => void;
+ updateSavedQueryId: (savedQueryId?: string) => void;
+ vis?: Vis;
+}
+
+export function DiscoverLegacy({
+ addColumn,
+ fetch,
+ fetchCounter,
+ fetchError,
+ fieldCounts,
+ histogramData,
+ hits,
+ indexPattern,
+ minimumVisibleRows,
+ onAddFilter,
+ onChangeInterval,
+ onMoveColumn,
+ onRemoveColumn,
+ onSkipBottomButtonClick,
+ onSort,
+ opts,
+ resetQuery,
+ resultState,
+ rows,
+ searchSource,
+ setIndexPattern,
+ showSaveQuery,
+ state,
+ timefilterUpdateHandler,
+ timeRange,
+ topNavMenu,
+ updateQuery,
+ updateSavedQueryId,
+ vis,
+}: DiscoverLegacyProps) {
+ const [isSidebarClosed, setIsSidebarClosed] = useState(false);
+ const { TopNavMenu } = getServices().navigation.ui;
+ const { savedSearch, indexPatternList } = opts;
+ const bucketAggConfig = vis?.data?.aggs?.aggs[1];
+ const bucketInterval =
+ bucketAggConfig && search.aggs.isDateHistogramBucketAggConfig(bucketAggConfig)
+ ? bucketAggConfig.buckets?.getInterval()
+ : undefined;
+ const [fixedScrollEl, setFixedScrollEl] = useState();
+
+ useEffect(() => (fixedScrollEl ? opts.fixedScroll(fixedScrollEl) : undefined), [
+ fixedScrollEl,
+ opts,
+ ]);
+ const fixedScrollRef = useCallback(
+ (node: HTMLElement) => {
+ if (node !== null) {
+ setFixedScrollEl(node);
+ }
+ },
+ [setFixedScrollEl]
+ );
+ const sidebarClassName = classNames({
+ closed: isSidebarClosed,
+ });
+
+ const mainSectionClassName = classNames({
+ 'col-md-10': !isSidebarClosed,
+ 'col-md-12': isSidebarClosed,
+ });
+
+ return (
+
+
+
{savedSearch.title}
+
+
+
+
+
+ {resultState === 'none' && (
+
+ )}
+ {resultState === 'uninitialized' &&
}
+ {/* @TODO: Solved in the Angular way to satisfy functional test - should be improved*/}
+
+ {fetchError && }
+
+
+
+
+ {resultState === 'ready' && (
+
+
+
0 ? hits : 0}
+ showResetButton={!!(savedSearch && savedSearch.id)}
+ onResetQuery={resetQuery}
+ />
+ {opts.timefield && (
+
+ )}
+
+ {opts.timefield && (
+
+ {vis && rows.length !== 0 && (
+
+
+
+ )}
+
+ )}
+
+
+
+
+
+
+ {rows && rows.length && (
+
+
+
+
+
+ {rows.length === opts.sampleSize && (
+
+
+
+ window.scrollTo(0, 0)}>
+
+
+
+ )}
+
+ )}
+
+
+
+ )}
+
+
+
+
+
+ );
+}
diff --git a/src/plugins/discover/public/application/components/fetch_error/fetch_error.tsx b/src/plugins/discover/public/application/components/fetch_error/fetch_error.tsx
index 880a493983adf..dc8f1238eac6f 100644
--- a/src/plugins/discover/public/application/components/fetch_error/fetch_error.tsx
+++ b/src/plugins/discover/public/application/components/fetch_error/fetch_error.tsx
@@ -20,18 +20,20 @@ import './fetch_error.scss';
import React, { Fragment } from 'react';
import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
import { EuiFlexGroup, EuiFlexItem, EuiCallOut, EuiCodeBlock, EuiSpacer } from '@elastic/eui';
-import { getAngularModule, getServices } from '../../../kibana_services';
+import { getServices } from '../../../kibana_services';
+
+export interface FetchError {
+ lang: string;
+ script: string;
+ message: string;
+ error: string;
+}
interface Props {
- fetchError: {
- lang: string;
- script: string;
- message: string;
- error: string;
- };
+ fetchError: FetchError;
}
-const DiscoverFetchError = ({ fetchError }: Props) => {
+export const DiscoverFetchError = ({ fetchError }: Props) => {
if (!fetchError) {
return null;
}
@@ -92,9 +94,3 @@ const DiscoverFetchError = ({ fetchError }: Props) => {
);
};
-
-export function createFetchErrorDirective(reactDirective: any) {
- return reactDirective(DiscoverFetchError);
-}
-
-getAngularModule().directive('discoverFetchError', createFetchErrorDirective);
diff --git a/src/plugins/discover/public/application/components/fetch_error/index.js b/src/plugins/discover/public/application/components/fetch_error/index.ts
similarity index 100%
rename from src/plugins/discover/public/application/components/fetch_error/index.js
rename to src/plugins/discover/public/application/components/fetch_error/index.ts
diff --git a/src/plugins/discover/public/application/components/hits_counter/hits_counter_directive.ts b/src/plugins/discover/public/application/components/hits_counter/hits_counter_directive.ts
deleted file mode 100644
index 8d45e28370cad..0000000000000
--- a/src/plugins/discover/public/application/components/hits_counter/hits_counter_directive.ts
+++ /dev/null
@@ -1,27 +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 { HitsCounter } from './hits_counter';
-
-export function createHitsCounterDirective(reactDirective: any) {
- return reactDirective(HitsCounter, [
- ['hits', { watchDepth: 'reference' }],
- ['showResetButton', { watchDepth: 'reference' }],
- ['onResetQuery', { watchDepth: 'reference' }],
- ]);
-}
diff --git a/src/plugins/discover/public/application/components/hits_counter/index.ts b/src/plugins/discover/public/application/components/hits_counter/index.ts
index 58e7a9eda7f51..0ce95f061df17 100644
--- a/src/plugins/discover/public/application/components/hits_counter/index.ts
+++ b/src/plugins/discover/public/application/components/hits_counter/index.ts
@@ -18,4 +18,3 @@
*/
export { HitsCounter } from './hits_counter';
-export { createHitsCounterDirective } from './hits_counter_directive';
diff --git a/src/plugins/discover/public/application/components/loading_spinner/loading_spinner.tsx b/src/plugins/discover/public/application/components/loading_spinner/loading_spinner.tsx
index 44b922bf0f708..4e1754638d479 100644
--- a/src/plugins/discover/public/application/components/loading_spinner/loading_spinner.tsx
+++ b/src/plugins/discover/public/application/components/loading_spinner/loading_spinner.tsx
@@ -18,24 +18,18 @@
*/
import React from 'react';
import { EuiLoadingSpinner, EuiTitle, EuiSpacer } from '@elastic/eui';
-import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
+import { FormattedMessage } from '@kbn/i18n/react';
export function LoadingSpinner() {
return (
-
- <>
-
-
-
-
-
-
-
- >
-
+ <>
+
+
+
+
+
+
+
+ >
);
}
-
-export function createLoadingSpinnerDirective(reactDirective: any) {
- return reactDirective(LoadingSpinner);
-}
diff --git a/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx b/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx
index 850624888b24a..2407cff181901 100644
--- a/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx
+++ b/src/plugins/discover/public/application/components/sidebar/discover_sidebar.tsx
@@ -68,7 +68,7 @@ export interface DiscoverSidebarProps {
/**
* Currently selected index pattern
*/
- selectedIndexPattern: IndexPattern;
+ selectedIndexPattern?: IndexPattern;
/**
* Callback function to select another index pattern
*/
diff --git a/src/plugins/discover/public/application/components/sidebar/discover_sidebar_directive.ts b/src/plugins/discover/public/application/components/sidebar/discover_sidebar_directive.ts
deleted file mode 100644
index b271c920e5e01..0000000000000
--- a/src/plugins/discover/public/application/components/sidebar/discover_sidebar_directive.ts
+++ /dev/null
@@ -1,33 +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 { DiscoverSidebar } from './discover_sidebar';
-
-export function createDiscoverSidebarDirective(reactDirective: any) {
- return reactDirective(DiscoverSidebar, [
- ['columns', { watchDepth: 'reference' }],
- ['fieldCounts', { watchDepth: 'reference' }],
- ['hits', { watchDepth: 'reference' }],
- ['indexPatternList', { watchDepth: 'reference' }],
- ['onAddField', { watchDepth: 'reference' }],
- ['onAddFilter', { watchDepth: 'reference' }],
- ['onRemoveField', { watchDepth: 'reference' }],
- ['selectedIndexPattern', { watchDepth: 'reference' }],
- ['setIndexPattern', { watchDepth: 'reference' }],
- ]);
-}
diff --git a/src/plugins/discover/public/application/components/sidebar/index.ts b/src/plugins/discover/public/application/components/sidebar/index.ts
index 1b837840b52f6..aec8dfc86e817 100644
--- a/src/plugins/discover/public/application/components/sidebar/index.ts
+++ b/src/plugins/discover/public/application/components/sidebar/index.ts
@@ -18,4 +18,3 @@
*/
export { DiscoverSidebar } from './discover_sidebar';
-export { createDiscoverSidebarDirective } from './discover_sidebar_directive';
diff --git a/src/plugins/discover/public/application/components/sidebar/lib/get_details.ts b/src/plugins/discover/public/application/components/sidebar/lib/get_details.ts
index 13051f88c9591..22a6e7a628555 100644
--- a/src/plugins/discover/public/application/components/sidebar/lib/get_details.ts
+++ b/src/plugins/discover/public/application/components/sidebar/lib/get_details.ts
@@ -25,8 +25,11 @@ export function getDetails(
field: IndexPatternField,
hits: Array>,
columns: string[],
- indexPattern: IndexPattern
+ indexPattern?: IndexPattern
) {
+ if (!indexPattern) {
+ return {};
+ }
const details = {
...fieldCalculator.getFieldValueCounts({
hits,
diff --git a/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts b/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts
index c96a8f5ce17b9..eff7c2ec3c1c8 100644
--- a/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts
+++ b/src/plugins/discover/public/application/components/sidebar/lib/get_index_pattern_field_list.ts
@@ -20,8 +20,8 @@ import { difference } from 'lodash';
import { IndexPattern, IndexPatternField } from 'src/plugins/data/public';
export function getIndexPatternFieldList(
- indexPattern: IndexPattern,
- fieldCounts: Record
+ indexPattern?: IndexPattern,
+ fieldCounts?: Record
) {
if (!indexPattern || !fieldCounts) return [];
diff --git a/src/plugins/discover/public/application/components/skip_bottom_button/index.ts b/src/plugins/discover/public/application/components/skip_bottom_button/index.ts
index 2feaa35e0d61f..b3d93e40be0bd 100644
--- a/src/plugins/discover/public/application/components/skip_bottom_button/index.ts
+++ b/src/plugins/discover/public/application/components/skip_bottom_button/index.ts
@@ -18,4 +18,3 @@
*/
export { SkipBottomButton } from './skip_bottom_button';
-export { createSkipBottomButtonDirective } from './skip_bottom_button_directive';
diff --git a/src/plugins/discover/public/application/components/skip_bottom_button/skip_bottom_button_directive.ts b/src/plugins/discover/public/application/components/skip_bottom_button/skip_bottom_button_directive.ts
deleted file mode 100644
index 27f17b25fd447..0000000000000
--- a/src/plugins/discover/public/application/components/skip_bottom_button/skip_bottom_button_directive.ts
+++ /dev/null
@@ -1,23 +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 { SkipBottomButton } from './skip_bottom_button';
-
-export function createSkipBottomButtonDirective(reactDirective: any) {
- return reactDirective(SkipBottomButton, [['onClick', { watchDepth: 'reference' }]]);
-}
diff --git a/src/plugins/discover/public/application/components/timechart_header/index.ts b/src/plugins/discover/public/application/components/timechart_header/index.ts
index 43473319c318c..34bed2cd72a74 100644
--- a/src/plugins/discover/public/application/components/timechart_header/index.ts
+++ b/src/plugins/discover/public/application/components/timechart_header/index.ts
@@ -18,4 +18,3 @@
*/
export { TimechartHeader } from './timechart_header';
-export { createTimechartHeaderDirective } from './timechart_header_directive';
diff --git a/src/plugins/discover/public/application/components/timechart_header/timechart_header.test.tsx b/src/plugins/discover/public/application/components/timechart_header/timechart_header.test.tsx
index a4c10e749d868..7889b05a88415 100644
--- a/src/plugins/discover/public/application/components/timechart_header/timechart_header.test.tsx
+++ b/src/plugins/discover/public/application/components/timechart_header/timechart_header.test.tsx
@@ -29,8 +29,10 @@ describe('timechart header', function () {
beforeAll(() => {
props = {
- from: 'May 14, 2020 @ 11:05:13.590',
- to: 'May 14, 2020 @ 11:20:13.590',
+ timeRange: {
+ from: 'May 14, 2020 @ 11:05:13.590',
+ to: 'May 14, 2020 @ 11:20:13.590',
+ },
stateInterval: 's',
options: [
{
@@ -47,9 +49,11 @@ describe('timechart header', function () {
},
],
onChangeInterval: jest.fn(),
- showScaledInfo: undefined,
- bucketIntervalDescription: 'second',
- bucketIntervalScale: undefined,
+ bucketInterval: {
+ scaled: undefined,
+ description: 'second',
+ scale: undefined,
+ },
};
});
@@ -58,8 +62,8 @@ describe('timechart header', function () {
expect(component.find(EuiIconTip).length).toBe(0);
});
- it('TimechartHeader renders an info text by providing the showScaledInfo property', () => {
- props.showScaledInfo = true;
+ it('TimechartHeader renders an info when bucketInterval.scale is set to true', () => {
+ props.bucketInterval!.scaled = true;
component = mountWithIntl();
expect(component.find(EuiIconTip).length).toBe(1);
});
diff --git a/src/plugins/discover/public/application/components/timechart_header/timechart_header.tsx b/src/plugins/discover/public/application/components/timechart_header/timechart_header.tsx
index 8789847058aff..1451106827ee0 100644
--- a/src/plugins/discover/public/application/components/timechart_header/timechart_header.tsx
+++ b/src/plugins/discover/public/application/components/timechart_header/timechart_header.tsx
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-import React, { useState, useEffect } from 'react';
+import React, { useState, useEffect, useCallback } from 'react';
import {
EuiFlexGroup,
EuiFlexItem,
@@ -27,16 +27,28 @@ import {
} from '@elastic/eui';
import { I18nProvider } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
+import moment from 'moment';
export interface TimechartHeaderProps {
/**
- * the query from date string
+ * Format of date to be displayed
*/
- from: string;
+ dateFormat?: string;
/**
- * the query to date string
+ * Interval for the buckets of the recent request
*/
- to: string;
+ bucketInterval?: {
+ scaled?: boolean;
+ description?: string;
+ scale?: number;
+ };
+ /**
+ * Range of dates to be displayed
+ */
+ timeRange?: {
+ from: string;
+ to: string;
+ };
/**
* Interval Options
*/
@@ -49,31 +61,29 @@ export interface TimechartHeaderProps {
* selected interval
*/
stateInterval: string;
- /**
- * displays the scaled info of the interval
- */
- showScaledInfo: boolean | undefined;
- /**
- * scaled info description
- */
- bucketIntervalDescription: string;
- /**
- * bucket interval scale
- */
- bucketIntervalScale: number | undefined;
}
export function TimechartHeader({
- from,
- to,
+ bucketInterval,
+ dateFormat,
+ timeRange,
options,
onChangeInterval,
stateInterval,
- showScaledInfo,
- bucketIntervalDescription,
- bucketIntervalScale,
}: TimechartHeaderProps) {
const [interval, setInterval] = useState(stateInterval);
+ const toMoment = useCallback(
+ (datetime: string) => {
+ if (!datetime) {
+ return '';
+ }
+ if (!dateFormat) {
+ return datetime;
+ }
+ return moment(datetime).format(dateFormat);
+ },
+ [dateFormat]
+ );
useEffect(() => {
setInterval(stateInterval);
@@ -84,6 +94,10 @@ export function TimechartHeader({
onChangeInterval(e.target.value);
};
+ if (!timeRange || !bucketInterval) {
+ return null;
+ }
+
return (
@@ -95,7 +109,7 @@ export function TimechartHeader({
delay="long"
>
- {`${from} - ${to} ${
+ {`${toMoment(timeRange.from)} - ${toMoment(timeRange.to)} ${
interval !== 'auto'
? i18n.translate('discover.timechartHeader.timeIntervalSelect.per', {
defaultMessage: 'per',
@@ -125,7 +139,7 @@ export function TimechartHeader({
value={interval}
onChange={handleIntervalChange}
append={
- showScaledInfo ? (
+ bucketInterval.scaled ? (
1
+ bucketInterval!.scale && bucketInterval!.scale > 1
? i18n.translate('discover.bucketIntervalTooltip.tooLargeBucketsText', {
defaultMessage: 'buckets that are too large',
})
: i18n.translate('discover.bucketIntervalTooltip.tooManyBucketsText', {
defaultMessage: 'too many buckets',
}),
- bucketIntervalDescription,
+ bucketIntervalDescription: bucketInterval.description,
},
})}
color="warning"
diff --git a/src/plugins/discover/public/application/components/timechart_header/timechart_header_directive.ts b/src/plugins/discover/public/application/components/timechart_header/timechart_header_directive.ts
deleted file mode 100644
index 027236cd46521..0000000000000
--- a/src/plugins/discover/public/application/components/timechart_header/timechart_header_directive.ts
+++ /dev/null
@@ -1,32 +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 { TimechartHeader } from './timechart_header';
-
-export function createTimechartHeaderDirective(reactDirective: any) {
- return reactDirective(TimechartHeader, [
- ['from', { watchDepth: 'reference' }],
- ['to', { watchDepth: 'reference' }],
- ['options', { watchDepth: 'reference' }],
- ['onChangeInterval', { watchDepth: 'reference' }],
- ['stateInterval', { watchDepth: 'reference' }],
- ['showScaledInfo', { watchDepth: 'reference' }],
- ['bucketIntervalDescription', { watchDepth: 'reference' }],
- ['bucketIntervalScale', { watchDepth: 'reference' }],
- ]);
-}
diff --git a/src/plugins/discover/public/build_services.ts b/src/plugins/discover/public/build_services.ts
index 12562d8571a25..fdb14b3f1f63e 100644
--- a/src/plugins/discover/public/build_services.ts
+++ b/src/plugins/discover/public/build_services.ts
@@ -44,6 +44,7 @@ import { createSavedSearchesLoader, SavedSearch } from './saved_searches';
import { getHistory } from './kibana_services';
import { KibanaLegacyStart } from '../../kibana_legacy/public';
import { UrlForwardingStart } from '../../url_forwarding/public';
+import { NavigationPublicPluginStart } from '../../navigation/public';
export interface DiscoverServices {
addBasePath: (path: string) => string;
@@ -58,6 +59,7 @@ export interface DiscoverServices {
indexPatterns: IndexPatternsContract;
inspector: InspectorPublicPluginStart;
metadata: { branch: string };
+ navigation: NavigationPublicPluginStart;
share?: SharePluginStart;
kibanaLegacy: KibanaLegacyStart;
urlForwarding: UrlForwardingStart;
@@ -65,6 +67,7 @@ export interface DiscoverServices {
toastNotifications: ToastsStart;
getSavedSearchById: (id: string) => Promise;
getSavedSearchUrlById: (id: string) => Promise;
+ getEmbeddableInjector: any;
uiSettings: IUiSettingsClient;
visualizations: VisualizationsStart;
}
@@ -72,7 +75,8 @@ export interface DiscoverServices {
export async function buildServices(
core: CoreStart,
plugins: DiscoverStartPlugins,
- context: PluginInitializerContext
+ context: PluginInitializerContext,
+ getEmbeddableInjector: any
): Promise {
const services: SavedObjectKibanaServices = {
savedObjectsClient: core.savedObjects.client,
@@ -92,6 +96,7 @@ export async function buildServices(
docLinks: core.docLinks,
theme: plugins.charts.theme,
filterManager: plugins.data.query.filterManager,
+ getEmbeddableInjector,
getSavedSearchById: async (id: string) => savedObjectService.get(id),
getSavedSearchUrlById: async (id: string) => savedObjectService.urlFor(id),
history: getHistory,
@@ -100,6 +105,7 @@ export async function buildServices(
metadata: {
branch: context.env.packageInfo.branch,
},
+ navigation: plugins.navigation,
share: plugins.share,
kibanaLegacy: plugins.kibanaLegacy,
urlForwarding: plugins.urlForwarding,
diff --git a/src/plugins/discover/public/get_inner_angular.ts b/src/plugins/discover/public/get_inner_angular.ts
index 85b0752f13463..1ca0bb20e8723 100644
--- a/src/plugins/discover/public/get_inner_angular.ts
+++ b/src/plugins/discover/public/get_inner_angular.ts
@@ -40,16 +40,10 @@ import { createTableRowDirective } from './application/angular/doc_table/compone
import { createPagerFactory } from './application/angular/doc_table/lib/pager/pager_factory';
import { createInfiniteScrollDirective } from './application/angular/doc_table/infinite_scroll';
import { createDocViewerDirective } from './application/angular/doc_viewer';
-import { CollapsibleSidebarProvider } from './application/angular/directives/collapsible_sidebar/collapsible_sidebar';
-// @ts-ignore
-import { FixedScrollProvider } from './application/angular/directives/fixed_scroll';
-// @ts-ignore
-import { DebounceProviderTimeout } from './application/angular/directives/debounce/debounce';
import { createRenderCompleteDirective } from './application/angular/directives/render_complete';
import {
initAngularBootstrap,
configureAppAngularModule,
- KbnAccessibleClickProvider,
PrivateProvider,
PromiseServiceCreator,
registerListenEventListener,
@@ -57,14 +51,10 @@ import {
createTopNavDirective,
createTopNavHelper,
} from '../../kibana_legacy/public';
-import { createDiscoverSidebarDirective } from './application/components/sidebar';
-import { createHitsCounterDirective } from '././application/components/hits_counter';
-import { createLoadingSpinnerDirective } from '././application/components/loading_spinner/loading_spinner';
-import { createTimechartHeaderDirective } from './application/components/timechart_header';
import { createContextErrorMessageDirective } from './application/components/context_error_message';
import { DiscoverStartPlugins } from './plugin';
import { getScopedHistory } from './kibana_services';
-import { createSkipBottomButtonDirective } from './application/components/skip_bottom_button';
+import { createDiscoverLegacyDirective } from './application/components/create_discover_legacy_directive';
/**
* returns the main inner angular module, it contains all the parts of Angular Discover
@@ -88,11 +78,9 @@ export function getInnerAngularModule(
export function getInnerAngularModuleEmbeddable(
name: string,
core: CoreStart,
- deps: DiscoverStartPlugins,
- context: PluginInitializerContext
+ deps: DiscoverStartPlugins
) {
- const module = initializeInnerAngularModule(name, core, deps.navigation, deps.data, true);
- return module;
+ return initializeInnerAngularModule(name, core, deps.navigation, deps.data, true);
}
let initialized = false;
@@ -129,8 +117,7 @@ export function initializeInnerAngularModule(
])
.config(watchMultiDecorator)
.directive('icon', (reactDirective) => reactDirective(EuiIcon))
- .directive('renderComplete', createRenderCompleteDirective)
- .service('debounce', ['$timeout', DebounceProviderTimeout]);
+ .directive('renderComplete', createRenderCompleteDirective);
}
return angular
@@ -149,18 +136,9 @@ export function initializeInnerAngularModule(
])
.config(watchMultiDecorator)
.run(registerListenEventListener)
- .directive('icon', (reactDirective) => reactDirective(EuiIcon))
- .directive('kbnAccessibleClick', KbnAccessibleClickProvider)
- .directive('collapsibleSidebar', CollapsibleSidebarProvider)
- .directive('fixedScroll', FixedScrollProvider)
.directive('renderComplete', createRenderCompleteDirective)
- .directive('discoverSidebar', createDiscoverSidebarDirective)
- .directive('skipBottomButton', createSkipBottomButtonDirective)
- .directive('hitsCounter', createHitsCounterDirective)
- .directive('loadingSpinner', createLoadingSpinnerDirective)
- .directive('timechartHeader', createTimechartHeaderDirective)
- .directive('contextErrorMessage', createContextErrorMessageDirective)
- .service('debounce', ['$timeout', DebounceProviderTimeout]);
+ .directive('discoverLegacy', createDiscoverLegacyDirective)
+ .directive('contextErrorMessage', createContextErrorMessageDirective);
}
function createLocalPromiseModule() {
diff --git a/src/plugins/discover/public/plugin.ts b/src/plugins/discover/public/plugin.ts
index 0bdc5ad95b391..4296a0867fbe5 100644
--- a/src/plugins/discover/public/plugin.ts
+++ b/src/plugins/discover/public/plugin.ts
@@ -327,7 +327,12 @@ export class DiscoverPlugin
if (this.servicesInitialized) {
return { core, plugins };
}
- const services = await buildServices(core, plugins, this.initializerContext);
+ const services = await buildServices(
+ core,
+ plugins,
+ this.initializerContext,
+ this.getEmbeddableInjector
+ );
setServices(services);
this.servicesInitialized = true;
@@ -380,12 +385,7 @@ export class DiscoverPlugin
const { core, plugins } = await this.initializeServices();
getServices().kibanaLegacy.loadFontAwesome();
const { getInnerAngularModuleEmbeddable } = await import('./get_inner_angular');
- getInnerAngularModuleEmbeddable(
- embeddableAngularName,
- core,
- plugins,
- this.initializerContext
- );
+ getInnerAngularModuleEmbeddable(embeddableAngularName, core, plugins);
const mountpoint = document.createElement('div');
this.embeddableInjector = angular.bootstrap(mountpoint, [embeddableAngularName]);
}
diff --git a/src/plugins/discover/public/saved_searches/types.ts b/src/plugins/discover/public/saved_searches/types.ts
index d601d087afcee..13361cb647ddc 100644
--- a/src/plugins/discover/public/saved_searches/types.ts
+++ b/src/plugins/discover/public/saved_searches/types.ts
@@ -28,6 +28,7 @@ export interface SavedSearch {
columns: string[];
sort: SortOrder[];
destroy: () => void;
+ lastSavedTitle?: string;
}
export interface SavedSearchLoader {
get: (id: string) => Promise;
diff --git a/test/functional/page_objects/discover_page.ts b/test/functional/page_objects/discover_page.ts
index 5a224d930ee42..7a99509257bf7 100644
--- a/test/functional/page_objects/discover_page.ts
+++ b/test/functional/page_objects/discover_page.ts
@@ -254,7 +254,7 @@ export function DiscoverPageProvider({ getService, getPageObjects }: FtrProvider
}
public async getSidebarWidth() {
- const sidebar = await find.byCssSelector('.sidebar-list');
+ const sidebar = await testSubjects.find('discover-sidebar');
return await sidebar.getAttribute('clientWidth');
}
diff --git a/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.css b/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.css
index 12ac5b27c7a4a..35590df90fbb9 100644
--- a/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.css
+++ b/x-pack/plugins/reporting/server/lib/layouts/preserve_layout.css
@@ -36,7 +36,7 @@ filter-bar,
/* hide unusable controls */
discover-app .dscTimechart,
discover-app .dscSidebar__container,
-discover-app .kbnCollapsibleSidebar__collapseButton,
+discover-app .dscCollapsibleSidebar__collapseButton,
discover-app .discover-table-footer {
display: none;
}
diff --git a/x-pack/plugins/reporting/server/lib/layouts/print.css b/x-pack/plugins/reporting/server/lib/layouts/print.css
index 9b07e3c923138..3ff39974536d2 100644
--- a/x-pack/plugins/reporting/server/lib/layouts/print.css
+++ b/x-pack/plugins/reporting/server/lib/layouts/print.css
@@ -35,7 +35,7 @@ filter-bar,
/* hide unusable controls */
discover-app .dscTimechart,
discover-app .dscSidebar__container,
-discover-app .kbnCollapsibleSidebar__collapseButton,
+discover-app .dscCollapsibleSidebar__collapseButton,
discover-app .discover-table-footer {
display: none;
}
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index ad74a35b4f9e0..6c684932582ba 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -1435,10 +1435,7 @@
"discover.localMenu.saveTitle": "保存",
"discover.localMenu.shareSearchDescription": "検索を共有します",
"discover.localMenu.shareTitle": "共有",
- "discover.noResults.addressShardFailuresTitle": "シャードエラーの解決",
"discover.noResults.expandYourTimeRangeTitle": "時間範囲を拡大",
- "discover.noResults.indexFailureIndexText": "インデックス {failureIndex}",
- "discover.noResults.indexFailureShardText": "{index}、シャード {failureShard}",
"discover.noResults.queryMayNotMatchTitle": "1つ以上の表示されているインデックスに日付フィールドが含まれています。クエリが現在の時間範囲のデータと一致しないか、現在選択された時間範囲にデータが全く存在しない可能性があります。データが存在する時間範囲に変えることができます。",
"discover.noResults.searchExamples.400to499StatusCodeExampleTitle": "400-499のすべてのステータスコードを検索",
"discover.noResults.searchExamples.400to499StatusCodeWithPhpExtensionExampleTitle": "400-499のphp拡張子のステータスコードを検索",
@@ -1449,7 +1446,6 @@
"discover.noResults.searchExamples.queryStringSyntaxLinkText": "クエリ文字列の構文",
"discover.noResults.searchExamples.refineYourQueryTitle": "クエリの調整",
"discover.noResults.searchExamples.statusField200StatusCodeExampleTitle": "ステータスフィールドの200を検索",
- "discover.noResults.shardFailuresDescription": "次のシャードエラーが発生しました。",
"discover.notifications.invalidTimeRangeText": "指定された時間範囲が無効です。(開始:'{from}'、終了:'{to}')",
"discover.notifications.invalidTimeRangeTitle": "無効な時間範囲",
"discover.notifications.notSavedSearchTitle": "検索「{savedSearchTitle}」は保存されませんでした。",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 164d83aa85948..10dbc2ab2eed6 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -1436,10 +1436,7 @@
"discover.localMenu.saveTitle": "保存",
"discover.localMenu.shareSearchDescription": "共享搜索",
"discover.localMenu.shareTitle": "共享",
- "discover.noResults.addressShardFailuresTitle": "解决分片错误",
"discover.noResults.expandYourTimeRangeTitle": "展开时间范围",
- "discover.noResults.indexFailureIndexText": "索引 {failureIndex}",
- "discover.noResults.indexFailureShardText": "{index},分片 {failureShard}",
"discover.noResults.queryMayNotMatchTitle": "您正在查看的一个或多个索引包含日期字段。您的查询在当前时间范围内可能不匹配任何数据,也可能在当前选定的时间范围内没有任何数据。您可以尝试将时间范围更改为包含数据的时间范围。",
"discover.noResults.searchExamples.400to499StatusCodeExampleTitle": "查找所有介于 400-499 之间的状态代码",
"discover.noResults.searchExamples.400to499StatusCodeWithPhpExtensionExampleTitle": "查找状态代码 400-499 以及扩展名 php",
@@ -1450,7 +1447,6 @@
"discover.noResults.searchExamples.queryStringSyntaxLinkText": "查询字符串语法",
"discover.noResults.searchExamples.refineYourQueryTitle": "优化您的查询",
"discover.noResults.searchExamples.statusField200StatusCodeExampleTitle": "在状态字段中查找 200",
- "discover.noResults.shardFailuresDescription": "发生了以下分片错误:",
"discover.notifications.invalidTimeRangeText": "提供的时间范围无效。(起始:“{from}”,结束:“{to}”)",
"discover.notifications.invalidTimeRangeTitle": "时间范围无效",
"discover.notifications.notSavedSearchTitle": "搜索“{savedSearchTitle}”未保存。",