From 4967f2fbc14b00ec7158fae7d9fc017d1f0b1a8b Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Fri, 14 Dec 2018 16:12:52 -0500 Subject: [PATCH 1/8] Convert all pages to use the base controlller, then add logic in there to stop a new request when one is inflight --- .../components/elasticsearch/index/index.js | 4 +- .../components/kibana/detail_status/index.js | 4 + .../logstash/detail_status/index.js | 3 + .../monitoring/public/directives/all.js | 1 - .../directives/cluster/overview/index.js | 40 ----- .../public/directives/main/index.js | 2 + .../public/views/base_controller.js | 14 +- .../public/views/cluster/overview/index.html | 2 +- .../public/views/cluster/overview/index.js | 58 ++++--- .../elasticsearch/index/advanced/index.html | 4 +- .../elasticsearch/index/advanced/index.js | 80 ++++------ .../views/elasticsearch/index/index.html | 4 +- .../public/views/elasticsearch/index/index.js | 104 ++++++------- .../elasticsearch/node/advanced/index.js | 80 ++++------ .../views/elasticsearch/node/index.html | 8 +- .../public/views/elasticsearch/node/index.js | 121 +++++++------- .../public/views/kibana/instance/index.js | 147 ++++++++---------- .../public/views/kibana/overview/index.js | 98 +++++------- .../views/logstash/node/advanced/index.html | 19 +-- .../views/logstash/node/advanced/index.js | 81 +++++++--- .../public/views/logstash/node/index.html | 12 +- .../public/views/logstash/node/index.js | 82 +++++++--- .../views/logstash/node/pipelines/index.html | 8 +- .../views/logstash/node/pipelines/index.js | 70 +++++---- .../public/views/logstash/overview/index.js | 55 +++---- .../public/views/logstash/pipeline/index.js | 44 ++---- 26 files changed, 535 insertions(+), 610 deletions(-) delete mode 100644 x-pack/plugins/monitoring/public/directives/cluster/overview/index.js diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/index/index.js b/x-pack/plugins/monitoring/public/components/elasticsearch/index/index.js index 8caf0d0b48b430..395fd3084e5ec8 100644 --- a/x-pack/plugins/monitoring/public/components/elasticsearch/index/index.js +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/index/index.js @@ -18,9 +18,9 @@ import { MonitoringTimeseriesContainer } from '../../chart'; import { ShardAllocation } from '../shard_allocation/shard_allocation'; export const Index = ({ + scope, indexSummary, metrics, - scope, kbnUrl, ...props }) => { @@ -51,7 +51,7 @@ export const Index = ({ ))} - + diff --git a/x-pack/plugins/monitoring/public/components/kibana/detail_status/index.js b/x-pack/plugins/monitoring/public/components/kibana/detail_status/index.js index 0322f625912828..2bc90e9ff9b876 100644 --- a/x-pack/plugins/monitoring/public/components/kibana/detail_status/index.js +++ b/x-pack/plugins/monitoring/public/components/kibana/detail_status/index.js @@ -21,6 +21,10 @@ function DetailStatusUI({ stats, intl }) { const metrics = [ { + label: intl.formatMessage({ + id: 'xpack.monitoring.kibana.detailStatus.transportAddressLabel', + defaultMessage: 'Transport Address' + }), value: transportAddress, 'data-test-subj': 'transportAddress' }, diff --git a/x-pack/plugins/monitoring/public/components/logstash/detail_status/index.js b/x-pack/plugins/monitoring/public/components/logstash/detail_status/index.js index ce95eac5a39ba2..4d96a42e2259a1 100644 --- a/x-pack/plugins/monitoring/public/components/logstash/detail_status/index.js +++ b/x-pack/plugins/monitoring/public/components/logstash/detail_status/index.js @@ -22,6 +22,9 @@ function DetailStatusUi({ stats, intl }) { const firstMetrics = [ { + label: intl.formatMessage({ + id: 'xpack.monitoring.logstash.detailStatus.transportAddressLabel', defaultMessage: 'Transport Address' + }), value: httpAddress, 'data-test-subj': 'httpAddress' }, diff --git a/x-pack/plugins/monitoring/public/directives/all.js b/x-pack/plugins/monitoring/public/directives/all.js index 4aca3c22fd8afa..60d8f88c759cd8 100644 --- a/x-pack/plugins/monitoring/public/directives/all.js +++ b/x-pack/plugins/monitoring/public/directives/all.js @@ -7,7 +7,6 @@ import './main'; import './chart'; import './sparkline'; -import './cluster/overview'; import './cluster/listing'; import './elasticsearch/cluster_status'; import './elasticsearch/index_summary'; diff --git a/x-pack/plugins/monitoring/public/directives/cluster/overview/index.js b/x-pack/plugins/monitoring/public/directives/cluster/overview/index.js deleted file mode 100644 index 17439f890886ea..00000000000000 --- a/x-pack/plugins/monitoring/public/directives/cluster/overview/index.js +++ /dev/null @@ -1,40 +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 React from 'react'; -import ReactDOM from 'react-dom'; -import { Overview } from 'plugins/monitoring/components/cluster/overview'; -import { uiModules } from 'ui/modules'; -import { I18nProvider } from '@kbn/i18n/react'; - -const uiModule = uiModules.get('monitoring/directives', []); -uiModule.directive('monitoringClusterOverview', (kbnUrl, showLicenseExpiration) => { - return { - restrict: 'E', - scope: { cluster: '=' }, - link(scope, $el) { - - const changeUrl = target => { - scope.$evalAsync(() => { - kbnUrl.changePath(target); - }); - }; - - scope.$watch('cluster', cluster => { - ReactDOM.render(( - - - - ), $el[0]); - }); - - } - }; -}); diff --git a/x-pack/plugins/monitoring/public/directives/main/index.js b/x-pack/plugins/monitoring/public/directives/main/index.js index 6e255a8bef9773..1d7bf72ac2422a 100644 --- a/x-pack/plugins/monitoring/public/directives/main/index.js +++ b/x-pack/plugins/monitoring/public/directives/main/index.js @@ -101,6 +101,8 @@ uiModule.directive('monitoringMain', (breadcrumbs, license, kbnUrl, config) => { clusterName: get(scope, 'cluster.cluster_name') }); + attributes.$observe('instance', instance => controller.instance = instance); + attributes.$observe('resolver', resolver => controller.resolver = resolver); } }; }); diff --git a/x-pack/plugins/monitoring/public/views/base_controller.js b/x-pack/plugins/monitoring/public/views/base_controller.js index 635fb328b2b205..87ce5b1c3bdb80 100644 --- a/x-pack/plugins/monitoring/public/views/base_controller.js +++ b/x-pack/plugins/monitoring/public/views/base_controller.js @@ -75,7 +75,7 @@ export class MonitoringViewBaseController { titleService($scope.cluster, title); - this.data = { ...defaultData }; + $scope.pageData = this.data = { ...defaultData }; this._isDataInitialized = false; this.reactNodeId = reactNodeId; @@ -96,12 +96,20 @@ export class MonitoringViewBaseController { timefilter.enableAutoRefreshSelector(); } + this.updatingData = false; this.updateData = () => { + if (this.updatingData) { + // Do not sent another request if one is inflight + // See https://github.com/elastic/kibana/issues/24082 + return; + } const _api = apiUrlFn ? apiUrlFn() : api; + this.updatingData = true; return _getPageData($injector, _api) .then(pageData => { this._isDataInitialized = true; // render will replace loading screen with the react component - this.data = pageData; // update the view's data with the fetch result + $scope.pageData = this.data = pageData; // update the view's data with the fetch result + this.updatingData = false; }); }; this.updateData(); @@ -126,6 +134,8 @@ export class MonitoringViewBaseController { mode: 'absolute' }); }; + + this.setTitle = title => titleService($scope.cluster, title); } renderReact(component) { diff --git a/x-pack/plugins/monitoring/public/views/cluster/overview/index.html b/x-pack/plugins/monitoring/public/views/cluster/overview/index.html index f0a1c57089c3d2..7ea786510bf198 100644 --- a/x-pack/plugins/monitoring/public/views/cluster/overview/index.html +++ b/x-pack/plugins/monitoring/public/views/cluster/overview/index.html @@ -1,3 +1,3 @@ - +
diff --git a/x-pack/plugins/monitoring/public/views/cluster/overview/index.js b/x-pack/plugins/monitoring/public/views/cluster/overview/index.js index 51f7c5e7034a59..bdfe0d4ec3b41f 100644 --- a/x-pack/plugins/monitoring/public/views/cluster/overview/index.js +++ b/x-pack/plugins/monitoring/public/views/cluster/overview/index.js @@ -3,11 +3,13 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +import React from 'react'; import uiRoutes from 'ui/routes'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import template from './index.html'; -import { timefilter } from 'ui/timefilter'; +import { MonitoringViewBaseController } from '../../'; +import { Overview } from 'plugins/monitoring/components/cluster/overview'; +import { I18nProvider } from '@kbn/i18n/react'; uiRoutes.when('/overview', { template, @@ -21,28 +23,40 @@ uiRoutes.when('/overview', { return monitoringClusters(globalState.cluster_uuid, globalState.ccs); } }, - controller($injector, $scope, i18n) { - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); - - const $route = $injector.get('$route'); - $scope.cluster = $route.current.locals.cluster; + controller: class extends MonitoringViewBaseController { + constructor($injector, $scope, i18n) { + const kbnUrl = $injector.get('kbnUrl'); + const monitoringClusters = $injector.get('monitoringClusters'); + const globalState = $injector.get('globalState'); - const title = $injector.get('title'); - title($scope.cluster, i18n('xpack.monitoring.cluster.overviewTitle', { defaultMessage: 'Overview' })); + super({ + title: i18n('xpack.monitoring.cluster.overviewTitle', { + defaultMessage: 'Overview' + }), + defaultData: {}, + getPageData: () => monitoringClusters(globalState.cluster_uuid, globalState.ccs), + reactNodeId: 'monitoringClusterOverviewApp', + $scope, + $injector + }); - const $executor = $injector.get('$executor'); - const monitoringClusters = $injector.get('monitoringClusters'); - const globalState = $injector.get('globalState'); - $executor.register({ - execute: () => monitoringClusters(globalState.cluster_uuid, globalState.ccs), - handleResponse(cluster) { - $scope.cluster = cluster; - } - }); + const changeUrl = target => { + $scope.$evalAsync(() => { + kbnUrl.changePath(target); + }); + }; - $executor.start($scope); - - $scope.$on('$destroy', $executor.destroy); + $scope.$watch(() => this.data, data => { + this.renderReact( + + + + ); + }); + } } }); diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/index/advanced/index.html b/x-pack/plugins/monitoring/public/views/elasticsearch/index/advanced/index.html index 2abb73d52adb68..159376148d1734 100644 --- a/x-pack/plugins/monitoring/public/views/elasticsearch/index/advanced/index.html +++ b/x-pack/plugins/monitoring/public/views/elasticsearch/index/advanced/index.html @@ -1,7 +1,7 @@
diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/index/advanced/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/index/advanced/index.js index 8f575b7809e732..1a51154beb624b 100644 --- a/x-pack/plugins/monitoring/public/views/elasticsearch/index/advanced/index.js +++ b/x-pack/plugins/monitoring/public/views/elasticsearch/index/advanced/index.js @@ -8,8 +8,6 @@ * Controller for Advanced Index Detail */ import React from 'react'; -import { render } from 'react-dom'; -import { find } from 'lodash'; import uiRoutes from 'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; @@ -17,7 +15,7 @@ import template from './index.html'; import { timefilter } from 'ui/timefilter'; import { AdvancedIndex } from '../../../../components/elasticsearch/index/advanced'; import { I18nProvider } from '@kbn/i18n/react'; -import moment from 'moment'; +import { MonitoringViewBaseController } from '../../../base_controller'; function getPageData($injector) { const globalState = $injector.get('globalState'); @@ -51,57 +49,39 @@ uiRoutes.when('/elasticsearch/indices/:index/advanced', { }, pageData: getPageData }, - controller($injector, $scope, i18n) { - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); + controllerAs: 'monitoringElasticsearchAdvancedIndexApp', + controller: class extends MonitoringViewBaseController { + constructor($injector, $scope, i18n) { + const $route = $injector.get('$route'); + const indexName = $route.current.params.index; - const $route = $injector.get('$route'); - const globalState = $injector.get('globalState'); - $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.indexName = $route.current.params.index; - $scope.pageData = $route.current.locals.pageData; - - const title = $injector.get('title'); - const routeTitle = i18n('xpack.monitoring.elasticsearch.indices.advanced.routeTitle', { - defaultMessage: 'Elasticsearch - Indices - {indexName} - Advanced', - values: { - indexName: $scope.indexName - } - }); - - title($scope.cluster, routeTitle); - - const $executor = $injector.get('$executor'); - $executor.register({ - execute: () => getPageData($injector), - handleResponse: (response) => $scope.pageData = response - }); - - $executor.start($scope); + super({ + title: i18n('xpack.monitoring.elasticsearch.indices.advanced.routeTitle', { + defaultMessage: 'Elasticsearch - Indices - {indexName} - Advanced', + values: { + indexName, + } + }), + defaultData: {}, + getPageData, + reactNodeId: 'monitoringElasticsearchAdvancedIndexApp', + $scope, + $injector + }); - $scope.$on('$destroy', $executor.destroy); + this.indexName = indexName; - function onBrush({ xaxis }) { - timefilter.setTime({ - from: moment(xaxis.from), - to: moment(xaxis.to), - mode: 'absolute', + $scope.$watch(() => this.data, data => { + this.renderReact( + + + + ); }); } - - this.renderReact = () => { - render( - - - , - document.getElementById('monitoringElasticsearchAdvancedIndexApp') - ); - }; - - $scope.$watch('pageData', this.renderReact); } }); diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.html b/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.html index 87bdcd5c160374..84d90f184358d8 100644 --- a/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.html +++ b/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.html @@ -1,8 +1,8 @@
diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.js index 7727239906af06..ff93c25ce89e14 100644 --- a/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.js +++ b/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.js @@ -8,9 +8,6 @@ * Controller for single index detail */ import React from 'react'; -import { render } from 'react-dom'; -import { find } from 'lodash'; -import moment from 'moment'; import uiRoutes from 'ui/routes'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; @@ -20,6 +17,7 @@ import { I18nProvider } from '@kbn/i18n/react'; import { labels } from '../../../components/elasticsearch/shard_allocation/lib/labels'; import { indicesByNodes } from '../../../components/elasticsearch/shard_allocation/transformers/indices_by_nodes'; import { Index } from '../../../components/elasticsearch/index/index'; +import { MonitoringViewBaseController } from '../../base_controller'; function getPageData($injector) { const $http = $injector.get('$http'); @@ -53,69 +51,55 @@ uiRoutes.when('/elasticsearch/indices/:index', { }, pageData: getPageData }, - controller($injector, $scope, i18n) { - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); + controllerAs: 'monitoringElasticsearchIndexApp', + controller: class extends MonitoringViewBaseController { + constructor($injector, $scope, i18n) { + const $route = $injector.get('$route'); + const kbnUrl = $injector.get('kbnUrl'); + const indexName = $route.current.params.index; - const $route = $injector.get('$route'); - const kbnUrl = $injector.get('kbnUrl'); - const globalState = $injector.get('globalState'); - $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.pageData = $route.current.locals.pageData; - $scope.indexName = $route.current.params.index; - - const title = $injector.get('title'); - const routeTitle = i18n('xpack.monitoring.elasticsearch.indices.overview.routeTitle', { - defaultMessage: 'Elasticsearch - Indices - {indexName} - Overview', - values: { - indexName: $scope.indexName - } - }); - - title($scope.cluster, routeTitle); + super({ + title: i18n('xpack.monitoring.elasticsearch.indices.overview.routeTitle', { + defaultMessage: 'Elasticsearch - Indices - {indexName} - Overview', + values: { + indexName, + } + }), + defaultData: {}, + getPageData, + reactNodeId: 'monitoringElasticsearchIndexApp', + $scope, + $injector + }); - const $executor = $injector.get('$executor'); - $executor.register({ - execute: () => getPageData($injector), - handleResponse: (response) => $scope.pageData = response - }); + this.indexName = indexName; + const transformer = indicesByNodes(); - $executor.start($scope); + $scope.$watch(() => this.data, data => { + if (!data || !data.shards) { + return; + } - $scope.$on('$destroy', $executor.destroy); + const shards = data.shards; + data.totalCount = shards.length; + data.showing = transformer(shards, data.nodes); + if (shards.some((shard) => shard.state === 'UNASSIGNED')) { + data.labels = labels.indexWithUnassigned; + } else { + data.labels = labels.index; + } - function onBrush({ xaxis }) { - timefilter.setTime({ - from: moment(xaxis.from), - to: moment(xaxis.to), - mode: 'absolute', + this.renderReact( + + + + ); }); } - - const transformer = indicesByNodes(); - this.renderReact = () => { - const shards = $scope.pageData.shards; - $scope.totalCount = shards.length; - $scope.showing = transformer(shards, $scope.pageData.nodes); - if (shards.some((shard) => shard.state === 'UNASSIGNED')) { - $scope.labels = labels.indexWithUnassigned; - } else { - $scope.labels = labels.index; - } - - render( - - - , - document.getElementById('monitoringElasticsearchIndexApp') - ); - }; - - $scope.$watch('pageData', this.renderReact); } }); diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js index e48c12e06aefa5..676ea670c67c0a 100644 --- a/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js +++ b/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js @@ -8,8 +8,6 @@ * Controller for Advanced Node Detail */ import React from 'react'; -import { render } from 'react-dom'; -import { find } from 'lodash'; import uiRoutes from 'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; @@ -17,7 +15,7 @@ import template from './index.html'; import { timefilter } from 'ui/timefilter'; import { I18nProvider } from '@kbn/i18n/react'; import { AdvancedNode } from '../../../../components/elasticsearch/node/advanced'; -import moment from 'moment'; +import { MonitoringViewBaseController } from '../../../base_controller'; function getPageData($injector) { const $http = $injector.get('$http'); @@ -51,58 +49,38 @@ uiRoutes.when('/elasticsearch/nodes/:node/advanced', { }, pageData: getPageData }, - controller($injector, $scope, i18n) { - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); - - const $route = $injector.get('$route'); - const globalState = $injector.get('globalState'); - $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.pageData = $route.current.locals.pageData; - - const title = $injector.get('title'); - const routeTitle = i18n('xpack.monitoring.elasticsearch.node.advanced.routeTitle', { - defaultMessage: 'Elasticsearch - Nodes - {nodeSummaryName} - Advanced', - values: { - nodeSummaryName: $scope.pageData.nodeSummary.name - } - }); - - title($scope.cluster, routeTitle); - - const $executor = $injector.get('$executor'); - $executor.register({ - execute: () => getPageData($injector), - handleResponse: (response) => { - $scope.pageData = response; - } - }); + controller: class extends MonitoringViewBaseController { + constructor($injector, $scope, i18n) { + super({ + defaultData: {}, + getPageData, + reactNodeId: 'monitoringElasticsearchAdvancedNodeApp', + $scope, + $injector + }); - $executor.start($scope); + $scope.$watch(() => this.data, data => { + if (!data || !data.nodeSummary) { + return; + } - $scope.$on('$destroy', $executor.destroy); + this.setTitle(i18n('xpack.monitoring.elasticsearch.node.advanced.routeTitle', { + defaultMessage: 'Elasticsearch - Nodes - {nodeSummaryName} - Advanced', + values: { + nodeSummaryName: data.nodeSummary.name + } + })); - function onBrush({ xaxis }) { - timefilter.setTime({ - from: moment(xaxis.from), - to: moment(xaxis.to), - mode: 'absolute', + this.renderReact( + + + + ); }); } - - this.renderReact = () => { - render( - - - , - document.getElementById('monitoringElasticsearchAdvancedNodeApp') - ); - }; - - $scope.$watch('pageData', this.renderReact); } }); diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.html b/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.html index ce43bed5310110..9c35d613f6e49a 100644 --- a/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.html +++ b/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.html @@ -1,11 +1,11 @@
diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js index 52c3e310a656d3..9c92a525e2a2b4 100644 --- a/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js +++ b/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js @@ -8,18 +8,16 @@ * Controller for Node Detail */ import React from 'react'; -import { render } from 'react-dom'; -import { find, partial } from 'lodash'; +import { partial } from 'lodash'; import uiRoutes from 'ui/routes'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import { getPageData } from './get_page_data'; import template from './index.html'; -import { timefilter } from 'ui/timefilter'; import { Node } from '../../../components/elasticsearch/node/node'; import { I18nProvider } from '@kbn/i18n/react'; import { labels } from '../../../components/elasticsearch/shard_allocation/lib/labels'; import { nodesByIndices } from '../../../components/elasticsearch/shard_allocation/transformers/nodes_by_indices'; -import moment from 'moment'; +import { MonitoringViewBaseController } from '../../base_controller'; uiRoutes.when('/elasticsearch/nodes/:node', { template, @@ -30,78 +28,63 @@ uiRoutes.when('/elasticsearch/nodes/:node', { }, pageData: getPageData }, - controller($injector, $scope, i18n) { - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); + controllerAs: 'monitoringElasticsearchNodeApp', + controller: class extends MonitoringViewBaseController { + constructor($injector, $scope, i18n) { + const $route = $injector.get('$route'); + const kbnUrl = $injector.get('kbnUrl'); + const nodeName = $route.current.params.node; - const $route = $injector.get('$route'); - const kbnUrl = $injector.get('kbnUrl'); - const globalState = $injector.get('globalState'); - $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.pageData = $route.current.locals.pageData; - - const title = $injector.get('title'); - const routeTitle = i18n('xpack.monitoring.elasticsearch.node.overview.routeTitle', { - defaultMessage: 'Elasticsearch - Nodes - {nodeSummaryName} - Overview', - values: { - nodeSummaryName: $scope.pageData.nodeSummary.name - } - }); - - title($scope.cluster, routeTitle); + super({ + title: i18n('xpack.monitoring.elasticsearch.node.overview.routeTitle', { + defaultMessage: 'Elasticsearch - Nodes - {nodeName} - Overview', + values: { + nodeName, + } + }), + defaultData: {}, + getPageData, + reactNodeId: 'monitoringElasticsearchNodeApp', + $scope, + $injector + }); - const features = $injector.get('features'); - const callPageData = partial(getPageData, $injector); - // show/hide system indices in shard allocation view - $scope.showSystemIndices = features.isEnabled('showSystemIndices', false); - $scope.toggleShowSystemIndices = (isChecked) => { - $scope.showSystemIndices = isChecked; - // preserve setting in localStorage - features.update('showSystemIndices', isChecked); - // update the page - callPageData().then((pageData) => $scope.pageData = pageData); - }; + this.nodeName = nodeName; - const $executor = $injector.get('$executor'); - $executor.register({ - execute: () => callPageData(), - handleResponse: (response) => { - $scope.pageData = response; - } - }); + const features = $injector.get('features'); + const callPageData = partial(getPageData, $injector); + // show/hide system indices in shard allocation view + $scope.showSystemIndices = features.isEnabled('showSystemIndices', false); + $scope.toggleShowSystemIndices = (isChecked) => { + $scope.showSystemIndices = isChecked; + // preserve setting in localStorage + features.update('showSystemIndices', isChecked); + // update the page + callPageData().then(data => this.data = data); + }; - $executor.start($scope); + const transformer = nodesByIndices(); + $scope.$watch(() => this.data, data => { + if (!data || !data.shards) { + return; + } - $scope.$on('$destroy', $executor.destroy); + const shards = data.shards; + $scope.totalCount = shards.length; + $scope.showing = transformer(shards, data.nodes); + $scope.labels = labels.node; - function onBrush({ xaxis }) { - timefilter.setTime({ - from: moment(xaxis.from), - to: moment(xaxis.to), - mode: 'absolute', + this.renderReact( + + + + ); }); } - - const transformer = nodesByIndices(); - this.renderReact = () => { - const shards = $scope.pageData.shards; - $scope.totalCount = shards.length; - $scope.showing = transformer(shards, $scope.pageData.nodes); - $scope.labels = labels.node; - - render( - - - , - document.getElementById('monitoringElasticsearchNodeApp') - ); - }; - - $scope.$watch('pageData', this.renderReact); } }); diff --git a/x-pack/plugins/monitoring/public/views/kibana/instance/index.js b/x-pack/plugins/monitoring/public/views/kibana/instance/index.js index 12989568f146c8..5de24f69ee04ab 100644 --- a/x-pack/plugins/monitoring/public/views/kibana/instance/index.js +++ b/x-pack/plugins/monitoring/public/views/kibana/instance/index.js @@ -8,8 +8,7 @@ * Kibana Instance */ import React from 'react'; -import { render } from 'react-dom'; -import { get, find } from 'lodash'; +import { get } from 'lodash'; import uiRoutes from'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; @@ -19,6 +18,7 @@ import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiFlexGroup, EuiFlexI import { MonitoringTimeseriesContainer } from '../../../components/chart'; import { DetailStatus } from 'plugins/monitoring/components/kibana/detail_status'; import { I18nProvider } from '@kbn/i18n/react'; +import { MonitoringViewBaseController } from '../../base_controller'; function getPageData($injector) { const $http = $injector.get('$http'); @@ -51,87 +51,74 @@ uiRoutes.when('/kibana/instances/:uuid', { }, pageData: getPageData }, - controller($injector, $scope) { - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); + controllerAs: 'monitoringKibanaInstanceApp', + controller: class extends MonitoringViewBaseController { + constructor($injector, $scope) { + super({ + title: `Kibana - ${get($scope.pageData, 'kibanaSummary.name')}`, + defaultData: {}, + getPageData, + reactNodeId: 'monitoringKibanaInstanceApp', + $scope, + $injector + }); - const $route = $injector.get('$route'); - const globalState = $injector.get('globalState'); - $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.pageData = $route.current.locals.pageData; + $scope.$watch(() => this.data, data => { + if (!data || !data.metrics) { + return; + } - const title = $injector.get('title'); - title($scope.cluster, `Kibana - ${get($scope.pageData, 'kibanaSummary.name')}`); + this.setTitle(`Kibana - ${get(data, 'kibanaSummary.name')}`); - const $executor = $injector.get('$executor'); - $executor.register({ - execute: () => getPageData($injector), - handleResponse: (response) => $scope.pageData = response - }); - - $executor.start($scope); - - $scope.$on('$destroy', $executor.destroy); - - $scope.$watch('pageData', renderReact); - renderReact(); - - function renderReact() { - const app = document.getElementById('monitoringKibanaInstanceApp'); - if (!app) { - return; - } - - const overviewPage = ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ); - - render(overviewPage, app); + this.renderReact( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); + }); } } }); diff --git a/x-pack/plugins/monitoring/public/views/kibana/overview/index.js b/x-pack/plugins/monitoring/public/views/kibana/overview/index.js index 442822ad04836a..94d7da85046cbe 100644 --- a/x-pack/plugins/monitoring/public/views/kibana/overview/index.js +++ b/x-pack/plugins/monitoring/public/views/kibana/overview/index.js @@ -8,8 +8,6 @@ * Kibana Overview */ import React from 'react'; -import { render } from 'react-dom'; -import { find } from 'lodash'; import uiRoutes from'ui/routes'; import { MonitoringTimeseriesContainer } from '../../../components/chart'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; @@ -19,6 +17,7 @@ import { timefilter } from 'ui/timefilter'; import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { ClusterStatus } from '../../../components/kibana/cluster_status'; import { I18nProvider } from '@kbn/i18n/react'; +import { MonitoringViewBaseController } from '../../base_controller'; function getPageData($injector) { const $http = $injector.get('$http'); @@ -50,64 +49,49 @@ uiRoutes.when('/kibana', { }, pageData: getPageData }, - controller($injector, $scope) { - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); + controllerAs: 'monitoringKibanaOverviewApp', + controller: class extends MonitoringViewBaseController { + constructor($injector, $scope) { + super({ + title: `Kibana`, + defaultData: {}, + getPageData, + reactNodeId: 'monitoringKibanaOverviewApp', + $scope, + $injector + }); - const $route = $injector.get('$route'); - const globalState = $injector.get('globalState'); - $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.pageData = $route.current.locals.pageData; + $scope.$watch(() => this.data, data => { + if (!data || !data.clusterStatus) { + return; + } - const title = $injector.get('title'); - title($scope.cluster, 'Kibana'); + this.renderReact( + + + + + + + + + + + + + + - const $executor = $injector.get('$executor'); - $executor.register({ - execute: () => getPageData($injector), - handleResponse: (response) => $scope.pageData = response - }); - - $executor.start($scope); - - $scope.$on('$destroy', $executor.destroy); - - $scope.$watch('pageData', renderReact); - renderReact(); - - function renderReact() { - const app = document.getElementById('monitoringKibanaOverviewApp'); - if (!app) { - return; - } - - const overviewPage = ( - - - - - - - - - - - - - - - - - - - - ); - - render(overviewPage, app); + + + + + ); + }); } } }); diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.html b/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.html index 089a55db9102c7..63f51809fd7e70 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.html +++ b/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.html @@ -1,12 +1,9 @@ - - -
-
-
-
-
-
-
-
-
+ +
diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.js b/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.js index 97484bdfe0eaee..60a63ee91f0396 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.js @@ -7,12 +7,17 @@ /* * Logstash Node Advanced View */ -import { find } from 'lodash'; +import React from 'react'; import uiRoutes from'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import template from './index.html'; import { timefilter } from 'ui/timefilter'; +import { MonitoringViewBaseController } from '../../../base_controller'; +import { DetailStatus } from 'plugins/monitoring/components/logstash/detail_status'; +import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiFlexGrid, EuiFlexItem } from '@elastic/eui'; +import { MonitoringTimeseriesContainer } from '../../../../components/chart'; +import { I18nProvider } from '@kbn/i18n/react'; function getPageData($injector) { const $http = $injector.get('$http'); @@ -46,32 +51,60 @@ uiRoutes.when('/logstash/node/:uuid/advanced', { }, pageData: getPageData }, - controller($injector, $scope, i18n) { - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); + controller: class extends MonitoringViewBaseController { + constructor($injector, $scope, i18n) { + super({ + defaultData: {}, + getPageData, + reactNodeId: 'monitoringLogstashNodeAdvancedApp', + $scope, + $injector + }); - const $route = $injector.get('$route'); - const globalState = $injector.get('globalState'); - $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.pageData = $route.current.locals.pageData; + $scope.$watch(() => this.data, data => { + if (!data || !data.nodeSummary) { + return; + } - const title = $injector.get('title'); - const routeTitle = i18n('xpack.monitoring.logstash.node.advanced.routeTitle', { - defaultMessage: 'Logstash - {nodeName} - Advanced', - values: { - nodeName: $scope.pageData.nodeSummary.name - } - }); - title($scope.cluster, routeTitle); - - const $executor = $injector.get('$executor'); - $executor.register({ - execute: () => getPageData($injector), - handleResponse: (response) => $scope.pageData = response - }); + this.setTitle(i18n('xpack.monitoring.logstash.node.advanced.routeTitle', { + defaultMessage: 'Logstash - {nodeName} - Advanced', + values: { + nodeName: data.nodeSummary.name + } + })); - $executor.start($scope); + const metricsToShow = [ + data.metrics.logstash_node_cpu_utilization, + data.metrics.logstash_queue_events_count, + data.metrics.logstash_node_cgroup_cpu, + data.metrics.logstash_pipeline_queue_size, + data.metrics.logstash_node_cgroup_stats, + ]; - $scope.$on('$destroy', $executor.destroy); + this.renderReact( + + + + + + + + {metricsToShow.map((metric, index) => ( + + + + + ))} + + + + + + ); + }); + } } }); diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/index.html b/x-pack/plugins/monitoring/public/views/logstash/node/index.html index 8ee62416df70b0..062c830dd8b7ae 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/index.html +++ b/x-pack/plugins/monitoring/public/views/logstash/node/index.html @@ -5,15 +5,5 @@ resolver="{{ pageData.nodeSummary.uuid }}" page="overview" > - -
-
-
-
-
-
-
-
-
-
+
diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/index.js b/x-pack/plugins/monitoring/public/views/logstash/node/index.js index f316740d83c118..f1dc6e04f9eba1 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/node/index.js @@ -7,12 +7,17 @@ /* * Logstash Node */ -import { find } from 'lodash'; +import React from 'react'; import uiRoutes from'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import template from './index.html'; import { timefilter } from 'ui/timefilter'; +import { DetailStatus } from 'plugins/monitoring/components/logstash/detail_status'; +import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiFlexGrid, EuiFlexItem } from '@elastic/eui'; +import { MonitoringTimeseriesContainer } from '../../../components/chart'; +import { I18nProvider } from '@kbn/i18n/react'; +import { MonitoringViewBaseController } from '../../base_controller'; function getPageData($injector) { const $http = $injector.get('$http'); @@ -46,32 +51,61 @@ uiRoutes.when('/logstash/node/:uuid', { }, pageData: getPageData }, - controller($injector, $scope, i18n) { - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); + controller: class extends MonitoringViewBaseController { + constructor($injector, $scope, i18n) { + super({ + defaultData: {}, + getPageData, + reactNodeId: 'monitoringLogstashNodeApp', + $scope, + $injector + }); - const $route = $injector.get('$route'); - const globalState = $injector.get('globalState'); - $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.pageData = $route.current.locals.pageData; + $scope.$watch(() => this.data, data => { + if (!data || !data.nodeSummary) { + return; + } - const title = $injector.get('title'); - const routeTitle = i18n('xpack.monitoring.logstash.node.routeTitle', { - defaultMessage: 'Logstash - {nodeName}', - values: { - nodeName: $scope.pageData.nodeSummary.name - } - }); - title($scope.cluster, routeTitle); - - const $executor = $injector.get('$executor'); - $executor.register({ - execute: () => getPageData($injector), - handleResponse: (response) => $scope.pageData = response - }); + this.setTitle(i18n('xpack.monitoring.logstash.node.routeTitle', { + defaultMessage: 'Logstash - {nodeName}', + values: { + nodeName: data.nodeSummary.name + } + })); - $executor.start($scope); + const metricsToShow = [ + data.metrics.logstash_events_input_rate, + data.metrics.logstash_jvm_usage, + data.metrics.logstash_events_output_rate, + data.metrics.logstash_node_cpu_metric, + data.metrics.logstash_events_latency, + data.metrics.logstash_os_load, + ]; - $scope.$on('$destroy', $executor.destroy); + this.renderReact( + + + + + + + + {metricsToShow.map((metric, index) => ( + + + + + ))} + + + + + + ); + }); + } } }); diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.html b/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.html index c484aad0718ea1..cae3a169bfd5ac 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.html +++ b/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.html @@ -4,11 +4,5 @@ resolver="{{ pageData.nodeSummary.uuid }}" page="pipelines" > - -
- -
+
diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js b/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js index e8d59fe9b8b67c..d4ee0517728993 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js @@ -8,7 +8,7 @@ * Logstash Node Pipelines Listing */ -import { find } from 'lodash'; +import React from 'react'; import uiRoutes from 'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; @@ -17,6 +17,9 @@ import { } from 'plugins/monitoring/lib/logstash/pipelines'; import template from './index.html'; import { timefilter } from 'ui/timefilter'; +import { MonitoringViewBaseEuiTableController } from '../../../'; +import { I18nProvider } from '@kbn/i18n/react'; +import { PipelineListing } from '../../../../components/logstash/pipeline_listing/pipeline_listing'; const getPageData = ($injector) => { const $route = $injector.get('$route'); @@ -66,34 +69,49 @@ uiRoutes }, pageData: getPageData }, - controller($injector, $scope, i18n) { - const $route = $injector.get('$route'); - const globalState = $injector.get('globalState'); - const title = $injector.get('title'); - const $executor = $injector.get('$executor'); + controller: class extends MonitoringViewBaseEuiTableController { + constructor($injector, $scope, i18n) { + const kbnUrl = $injector.get('kbnUrl'); - $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.pageData = $route.current.locals.pageData; + super({ + defaultData: {}, + getPageData, + reactNodeId: 'monitoringLogstashNodePipelinesApp', + $scope, + $injector + }); - $scope.upgradeMessage = makeUpgradeMessage($scope.pageData.nodeSummary.version, i18n); - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); + $scope.$watch(() => this.data, data => { + if (!data || !data.nodeSummary) { + return; + } - const routeTitle = i18n('xpack.monitoring.logstash.node.pipelines.routeTitle', { - defaultMessage: 'Logstash - {nodeName} - Pipelines', - values: { - nodeName: $scope.pageData.nodeSummary.name - } - }); - title($scope.cluster, routeTitle); + this.setTitle(i18n('xpack.monitoring.logstash.node.pipelines.routeTitle', { + defaultMessage: 'Logstash - {nodeName} - Pipelines', + values: { + nodeName: data.nodeSummary.name + } + })); - $executor.register({ - execute: () => getPageData($injector), - handleResponse: (response) => $scope.pageData = response - }); - - $executor.start($scope); - - $scope.$on('$destroy', $executor.destroy); + this.renderReact( + + + + ); + }); + } } }); diff --git a/x-pack/plugins/monitoring/public/views/logstash/overview/index.js b/x-pack/plugins/monitoring/public/views/logstash/overview/index.js index 749f0da9155e8a..4cf79b34854031 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/overview/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/overview/index.js @@ -8,8 +8,6 @@ * Logstash Overview */ import React from 'react'; -import { render } from 'react-dom'; -import { find } from 'lodash'; import uiRoutes from'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; @@ -17,6 +15,7 @@ import template from './index.html'; import { timefilter } from 'ui/timefilter'; import { I18nProvider } from '@kbn/i18n/react'; import { Overview } from '../../../components/logstash/overview'; +import { MonitoringViewBaseController } from '../../base_controller'; function getPageData($injector) { const $http = $injector.get('$http'); @@ -48,40 +47,26 @@ uiRoutes.when('/logstash', { }, pageData: getPageData }, - controller($injector, $scope) { - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); + controller: class extends MonitoringViewBaseController { + constructor($injector, $scope) { + super({ + title: 'Logstash', + getPageData, + reactNodeId: 'monitoringLogstashOverviewApp', + $scope, + $injector + }); - const $route = $injector.get('$route'); - const globalState = $injector.get('globalState'); - $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.pageData = $route.current.locals.pageData; - - const title = $injector.get('title'); - title($scope.cluster, 'Logstash'); - - const $executor = $injector.get('$executor'); - $executor.register({ - execute: () => getPageData($injector), - handleResponse: (response) => $scope.pageData = response - }); - $executor.start($scope); - $scope.$on('$destroy', $executor.destroy); - - function renderReact(pageData) { - render( - - - , - document.getElementById('monitoringLogstashOverviewApp') - ); + $scope.$watch(() => this.data, data => { + this.renderReact( + + + + ); + }); } - - $scope.$watch('pageData', pageData => { - renderReact(pageData); - }); } }); diff --git a/x-pack/plugins/monitoring/public/views/logstash/pipeline/index.js b/x-pack/plugins/monitoring/public/views/logstash/pipeline/index.js index 404245ef266a47..600bc60e8d3930 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/pipeline/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/pipeline/index.js @@ -7,15 +7,14 @@ /* * Logstash Node Pipeline View */ -import { find } from 'lodash'; import uiRoutes from'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import { CALCULATE_DURATION_SINCE } from '../../../../common/constants'; import { formatTimestampToDuration } from '../../../../common/format_timestamp_to_duration'; import template from './index.html'; -import { timefilter } from 'ui/timefilter'; import { i18n } from '@kbn/i18n'; +import { MonitoringViewBaseController } from '../../base_controller'; function getPageData($injector) { const $route = $injector.get('$route'); @@ -27,7 +26,9 @@ function getPageData($injector) { const { ccs, cluster_uuid: clusterUuid } = globalState; const pipelineId = $route.current.params.id; const pipelineHash = $route.current.params.hash || ''; - const url = `../api/monitoring/v1/clusters/${clusterUuid}/logstash/pipeline/${pipelineId}/${pipelineHash}`; + const url = pipelineHash + ? `../api/monitoring/v1/clusters/${clusterUuid}/logstash/pipeline/${pipelineId}/${pipelineHash}` + : `../api/monitoring/v1/clusters/${clusterUuid}/logstash/pipeline/${pipelineId}`; return $http.post(url, { ccs }) @@ -72,32 +73,17 @@ uiRoutes.when('/logstash/pipelines/:id/:hash?', { }, pageData: getPageData }, - controller($injector, $scope, i18n) { - const $route = $injector.get('$route'); - const $executor = $injector.get('$executor'); - const globalState = $injector.get('globalState'); - const title = $injector.get('title'); - - timefilter.disableTimeRangeSelector(); // Do not display time picker in UI - timefilter.enableAutoRefreshSelector(); - - function setClusters(clusters) { - $scope.clusters = clusters; - $scope.cluster = find($scope.clusters, { cluster_uuid: globalState.cluster_uuid }); + controller: class extends MonitoringViewBaseController { + constructor($injector, $scope, i18n) { + super({ + title: i18n('xpack.monitoring.logstash.pipeline.routeTitle', { + defaultMessage: 'Logstash - Pipeline' + }), + storageKey: 'logstash.pipelines', + getPageData, + $scope, + $injector + }); } - setClusters($route.current.locals.clusters); - $scope.pageData = $route.current.locals.pageData; - title($scope.cluster, i18n('xpack.monitoring.logstash.pipeline.routeTitle', { - defaultMessage: 'Logstash - Pipeline' - })); - - $executor.register({ - execute: () => getPageData($injector), - handleResponse: (response) => { - $scope.pageData = response; - } - }); - $executor.start($scope); - $scope.$on('$destroy', $executor.destroy); } }); From 3aefdd0bb52c59a03a4d9b5212b413528ff602ff Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Fri, 14 Dec 2018 16:28:20 -0500 Subject: [PATCH 2/8] Reuse the promise --- x-pack/plugins/monitoring/public/views/base_controller.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/monitoring/public/views/base_controller.js b/x-pack/plugins/monitoring/public/views/base_controller.js index 87ce5b1c3bdb80..135e5152776f63 100644 --- a/x-pack/plugins/monitoring/public/views/base_controller.js +++ b/x-pack/plugins/monitoring/public/views/base_controller.js @@ -96,20 +96,21 @@ export class MonitoringViewBaseController { timefilter.enableAutoRefreshSelector(); } + this.updateDataPromise = null; this.updatingData = false; this.updateData = () => { if (this.updatingData) { // Do not sent another request if one is inflight // See https://github.com/elastic/kibana/issues/24082 - return; + return this.updateDataPromise; } const _api = apiUrlFn ? apiUrlFn() : api; this.updatingData = true; - return _getPageData($injector, _api) + return this.updateDataPromise = _getPageData($injector, _api) .then(pageData => { this._isDataInitialized = true; // render will replace loading screen with the react component $scope.pageData = this.data = pageData; // update the view's data with the fetch result - this.updatingData = false; + // this.updatingData = false; }); }; this.updateData(); From f35080848883ef319c588a363c945f4c5be082c5 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Fri, 14 Dec 2018 17:11:50 -0500 Subject: [PATCH 3/8] Undo logstash changes --- .../views/logstash/node/advanced/index.html | 19 +++-- .../views/logstash/node/advanced/index.js | 81 ++++++------------ .../public/views/logstash/node/index.html | 12 ++- .../public/views/logstash/node/index.js | 82 ++++++------------- .../views/logstash/node/pipelines/index.html | 8 +- .../views/logstash/node/pipelines/index.js | 70 ++++++---------- .../public/views/logstash/overview/index.js | 55 ++++++++----- .../public/views/logstash/pipeline/index.js | 44 ++++++---- 8 files changed, 167 insertions(+), 204 deletions(-) diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.html b/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.html index 63f51809fd7e70..089a55db9102c7 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.html +++ b/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.html @@ -1,9 +1,12 @@ - -
+ + +
+
+
+
+
+
+
+
+
diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.js b/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.js index 60a63ee91f0396..97484bdfe0eaee 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/node/advanced/index.js @@ -7,17 +7,12 @@ /* * Logstash Node Advanced View */ -import React from 'react'; +import { find } from 'lodash'; import uiRoutes from'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import template from './index.html'; import { timefilter } from 'ui/timefilter'; -import { MonitoringViewBaseController } from '../../../base_controller'; -import { DetailStatus } from 'plugins/monitoring/components/logstash/detail_status'; -import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiFlexGrid, EuiFlexItem } from '@elastic/eui'; -import { MonitoringTimeseriesContainer } from '../../../../components/chart'; -import { I18nProvider } from '@kbn/i18n/react'; function getPageData($injector) { const $http = $injector.get('$http'); @@ -51,60 +46,32 @@ uiRoutes.when('/logstash/node/:uuid/advanced', { }, pageData: getPageData }, - controller: class extends MonitoringViewBaseController { - constructor($injector, $scope, i18n) { - super({ - defaultData: {}, - getPageData, - reactNodeId: 'monitoringLogstashNodeAdvancedApp', - $scope, - $injector - }); + controller($injector, $scope, i18n) { + timefilter.enableTimeRangeSelector(); + timefilter.enableAutoRefreshSelector(); - $scope.$watch(() => this.data, data => { - if (!data || !data.nodeSummary) { - return; - } + const $route = $injector.get('$route'); + const globalState = $injector.get('globalState'); + $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); + $scope.pageData = $route.current.locals.pageData; - this.setTitle(i18n('xpack.monitoring.logstash.node.advanced.routeTitle', { - defaultMessage: 'Logstash - {nodeName} - Advanced', - values: { - nodeName: data.nodeSummary.name - } - })); + const title = $injector.get('title'); + const routeTitle = i18n('xpack.monitoring.logstash.node.advanced.routeTitle', { + defaultMessage: 'Logstash - {nodeName} - Advanced', + values: { + nodeName: $scope.pageData.nodeSummary.name + } + }); + title($scope.cluster, routeTitle); + + const $executor = $injector.get('$executor'); + $executor.register({ + execute: () => getPageData($injector), + handleResponse: (response) => $scope.pageData = response + }); - const metricsToShow = [ - data.metrics.logstash_node_cpu_utilization, - data.metrics.logstash_queue_events_count, - data.metrics.logstash_node_cgroup_cpu, - data.metrics.logstash_pipeline_queue_size, - data.metrics.logstash_node_cgroup_stats, - ]; + $executor.start($scope); - this.renderReact( - - - - - - - - {metricsToShow.map((metric, index) => ( - - - - - ))} - - - - - - ); - }); - } + $scope.$on('$destroy', $executor.destroy); } }); diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/index.html b/x-pack/plugins/monitoring/public/views/logstash/node/index.html index 062c830dd8b7ae..8ee62416df70b0 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/index.html +++ b/x-pack/plugins/monitoring/public/views/logstash/node/index.html @@ -5,5 +5,15 @@ resolver="{{ pageData.nodeSummary.uuid }}" page="overview" > -
+ +
+
+
+
+
+
+
+
+
+
diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/index.js b/x-pack/plugins/monitoring/public/views/logstash/node/index.js index f1dc6e04f9eba1..f316740d83c118 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/node/index.js @@ -7,17 +7,12 @@ /* * Logstash Node */ -import React from 'react'; +import { find } from 'lodash'; import uiRoutes from'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import template from './index.html'; import { timefilter } from 'ui/timefilter'; -import { DetailStatus } from 'plugins/monitoring/components/logstash/detail_status'; -import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiFlexGrid, EuiFlexItem } from '@elastic/eui'; -import { MonitoringTimeseriesContainer } from '../../../components/chart'; -import { I18nProvider } from '@kbn/i18n/react'; -import { MonitoringViewBaseController } from '../../base_controller'; function getPageData($injector) { const $http = $injector.get('$http'); @@ -51,61 +46,32 @@ uiRoutes.when('/logstash/node/:uuid', { }, pageData: getPageData }, - controller: class extends MonitoringViewBaseController { - constructor($injector, $scope, i18n) { - super({ - defaultData: {}, - getPageData, - reactNodeId: 'monitoringLogstashNodeApp', - $scope, - $injector - }); + controller($injector, $scope, i18n) { + timefilter.enableTimeRangeSelector(); + timefilter.enableAutoRefreshSelector(); - $scope.$watch(() => this.data, data => { - if (!data || !data.nodeSummary) { - return; - } + const $route = $injector.get('$route'); + const globalState = $injector.get('globalState'); + $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); + $scope.pageData = $route.current.locals.pageData; - this.setTitle(i18n('xpack.monitoring.logstash.node.routeTitle', { - defaultMessage: 'Logstash - {nodeName}', - values: { - nodeName: data.nodeSummary.name - } - })); + const title = $injector.get('title'); + const routeTitle = i18n('xpack.monitoring.logstash.node.routeTitle', { + defaultMessage: 'Logstash - {nodeName}', + values: { + nodeName: $scope.pageData.nodeSummary.name + } + }); + title($scope.cluster, routeTitle); + + const $executor = $injector.get('$executor'); + $executor.register({ + execute: () => getPageData($injector), + handleResponse: (response) => $scope.pageData = response + }); - const metricsToShow = [ - data.metrics.logstash_events_input_rate, - data.metrics.logstash_jvm_usage, - data.metrics.logstash_events_output_rate, - data.metrics.logstash_node_cpu_metric, - data.metrics.logstash_events_latency, - data.metrics.logstash_os_load, - ]; + $executor.start($scope); - this.renderReact( - - - - - - - - {metricsToShow.map((metric, index) => ( - - - - - ))} - - - - - - ); - }); - } + $scope.$on('$destroy', $executor.destroy); } }); diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.html b/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.html index cae3a169bfd5ac..c484aad0718ea1 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.html +++ b/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.html @@ -4,5 +4,11 @@ resolver="{{ pageData.nodeSummary.uuid }}" page="pipelines" > -
+ +
+ +
diff --git a/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js b/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js index d4ee0517728993..e8d59fe9b8b67c 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/node/pipelines/index.js @@ -8,7 +8,7 @@ * Logstash Node Pipelines Listing */ -import React from 'react'; +import { find } from 'lodash'; import uiRoutes from 'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; @@ -17,9 +17,6 @@ import { } from 'plugins/monitoring/lib/logstash/pipelines'; import template from './index.html'; import { timefilter } from 'ui/timefilter'; -import { MonitoringViewBaseEuiTableController } from '../../../'; -import { I18nProvider } from '@kbn/i18n/react'; -import { PipelineListing } from '../../../../components/logstash/pipeline_listing/pipeline_listing'; const getPageData = ($injector) => { const $route = $injector.get('$route'); @@ -69,49 +66,34 @@ uiRoutes }, pageData: getPageData }, - controller: class extends MonitoringViewBaseEuiTableController { - constructor($injector, $scope, i18n) { - const kbnUrl = $injector.get('kbnUrl'); + controller($injector, $scope, i18n) { + const $route = $injector.get('$route'); + const globalState = $injector.get('globalState'); + const title = $injector.get('title'); + const $executor = $injector.get('$executor'); - super({ - defaultData: {}, - getPageData, - reactNodeId: 'monitoringLogstashNodePipelinesApp', - $scope, - $injector - }); + $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); + $scope.pageData = $route.current.locals.pageData; - $scope.$watch(() => this.data, data => { - if (!data || !data.nodeSummary) { - return; - } + $scope.upgradeMessage = makeUpgradeMessage($scope.pageData.nodeSummary.version, i18n); + timefilter.enableTimeRangeSelector(); + timefilter.enableAutoRefreshSelector(); - this.setTitle(i18n('xpack.monitoring.logstash.node.pipelines.routeTitle', { - defaultMessage: 'Logstash - {nodeName} - Pipelines', - values: { - nodeName: data.nodeSummary.name - } - })); + const routeTitle = i18n('xpack.monitoring.logstash.node.pipelines.routeTitle', { + defaultMessage: 'Logstash - {nodeName} - Pipelines', + values: { + nodeName: $scope.pageData.nodeSummary.name + } + }); + title($scope.cluster, routeTitle); - this.renderReact( - - - - ); - }); - } + $executor.register({ + execute: () => getPageData($injector), + handleResponse: (response) => $scope.pageData = response + }); + + $executor.start($scope); + + $scope.$on('$destroy', $executor.destroy); } }); diff --git a/x-pack/plugins/monitoring/public/views/logstash/overview/index.js b/x-pack/plugins/monitoring/public/views/logstash/overview/index.js index 4cf79b34854031..749f0da9155e8a 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/overview/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/overview/index.js @@ -8,6 +8,8 @@ * Logstash Overview */ import React from 'react'; +import { render } from 'react-dom'; +import { find } from 'lodash'; import uiRoutes from'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; @@ -15,7 +17,6 @@ import template from './index.html'; import { timefilter } from 'ui/timefilter'; import { I18nProvider } from '@kbn/i18n/react'; import { Overview } from '../../../components/logstash/overview'; -import { MonitoringViewBaseController } from '../../base_controller'; function getPageData($injector) { const $http = $injector.get('$http'); @@ -47,26 +48,40 @@ uiRoutes.when('/logstash', { }, pageData: getPageData }, - controller: class extends MonitoringViewBaseController { - constructor($injector, $scope) { - super({ - title: 'Logstash', - getPageData, - reactNodeId: 'monitoringLogstashOverviewApp', - $scope, - $injector - }); + controller($injector, $scope) { + timefilter.enableTimeRangeSelector(); + timefilter.enableAutoRefreshSelector(); - $scope.$watch(() => this.data, data => { - this.renderReact( - - - - ); - }); + const $route = $injector.get('$route'); + const globalState = $injector.get('globalState'); + $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); + $scope.pageData = $route.current.locals.pageData; + + const title = $injector.get('title'); + title($scope.cluster, 'Logstash'); + + const $executor = $injector.get('$executor'); + $executor.register({ + execute: () => getPageData($injector), + handleResponse: (response) => $scope.pageData = response + }); + $executor.start($scope); + $scope.$on('$destroy', $executor.destroy); + + function renderReact(pageData) { + render( + + + , + document.getElementById('monitoringLogstashOverviewApp') + ); } + + $scope.$watch('pageData', pageData => { + renderReact(pageData); + }); } }); diff --git a/x-pack/plugins/monitoring/public/views/logstash/pipeline/index.js b/x-pack/plugins/monitoring/public/views/logstash/pipeline/index.js index 600bc60e8d3930..404245ef266a47 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/pipeline/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/pipeline/index.js @@ -7,14 +7,15 @@ /* * Logstash Node Pipeline View */ +import { find } from 'lodash'; import uiRoutes from'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import { CALCULATE_DURATION_SINCE } from '../../../../common/constants'; import { formatTimestampToDuration } from '../../../../common/format_timestamp_to_duration'; import template from './index.html'; +import { timefilter } from 'ui/timefilter'; import { i18n } from '@kbn/i18n'; -import { MonitoringViewBaseController } from '../../base_controller'; function getPageData($injector) { const $route = $injector.get('$route'); @@ -26,9 +27,7 @@ function getPageData($injector) { const { ccs, cluster_uuid: clusterUuid } = globalState; const pipelineId = $route.current.params.id; const pipelineHash = $route.current.params.hash || ''; - const url = pipelineHash - ? `../api/monitoring/v1/clusters/${clusterUuid}/logstash/pipeline/${pipelineId}/${pipelineHash}` - : `../api/monitoring/v1/clusters/${clusterUuid}/logstash/pipeline/${pipelineId}`; + const url = `../api/monitoring/v1/clusters/${clusterUuid}/logstash/pipeline/${pipelineId}/${pipelineHash}`; return $http.post(url, { ccs }) @@ -73,17 +72,32 @@ uiRoutes.when('/logstash/pipelines/:id/:hash?', { }, pageData: getPageData }, - controller: class extends MonitoringViewBaseController { - constructor($injector, $scope, i18n) { - super({ - title: i18n('xpack.monitoring.logstash.pipeline.routeTitle', { - defaultMessage: 'Logstash - Pipeline' - }), - storageKey: 'logstash.pipelines', - getPageData, - $scope, - $injector - }); + controller($injector, $scope, i18n) { + const $route = $injector.get('$route'); + const $executor = $injector.get('$executor'); + const globalState = $injector.get('globalState'); + const title = $injector.get('title'); + + timefilter.disableTimeRangeSelector(); // Do not display time picker in UI + timefilter.enableAutoRefreshSelector(); + + function setClusters(clusters) { + $scope.clusters = clusters; + $scope.cluster = find($scope.clusters, { cluster_uuid: globalState.cluster_uuid }); } + setClusters($route.current.locals.clusters); + $scope.pageData = $route.current.locals.pageData; + title($scope.cluster, i18n('xpack.monitoring.logstash.pipeline.routeTitle', { + defaultMessage: 'Logstash - Pipeline' + })); + + $executor.register({ + execute: () => getPageData($injector), + handleResponse: (response) => { + $scope.pageData = response; + } + }); + $executor.start($scope); + $scope.$on('$destroy', $executor.destroy); } }); From f9abd083d15b00879896e9995bff3919a62f11f1 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Fri, 14 Dec 2018 17:12:59 -0500 Subject: [PATCH 4/8] Update in catch too --- x-pack/plugins/monitoring/public/views/base_controller.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/monitoring/public/views/base_controller.js b/x-pack/plugins/monitoring/public/views/base_controller.js index 135e5152776f63..c37ddbaa6a5f2b 100644 --- a/x-pack/plugins/monitoring/public/views/base_controller.js +++ b/x-pack/plugins/monitoring/public/views/base_controller.js @@ -110,7 +110,10 @@ export class MonitoringViewBaseController { .then(pageData => { this._isDataInitialized = true; // render will replace loading screen with the react component $scope.pageData = this.data = pageData; // update the view's data with the fetch result - // this.updatingData = false; + this.updatingData = false; + }) + .catch(() => { + this.updatingData = false; }); }; this.updateData(); From 449da0c16c3e5a863f4ca66f25300eca74e2d059 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Sat, 15 Dec 2018 07:24:10 -0500 Subject: [PATCH 5/8] Add unit test --- .../public/views/__tests__/base_controller.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/x-pack/plugins/monitoring/public/views/__tests__/base_controller.js b/x-pack/plugins/monitoring/public/views/__tests__/base_controller.js index 6c6567da8f9b43..b10e2787287941 100644 --- a/x-pack/plugins/monitoring/public/views/__tests__/base_controller.js +++ b/x-pack/plugins/monitoring/public/views/__tests__/base_controller.js @@ -69,6 +69,25 @@ describe('MonitoringViewBaseController', function () { expect(executorService.start.calledOnce).to.be(true); }); + it('does not allow for a new request if one is inflight', done => { + let counter = 0; + const opts = { + title: 'testo', + getPageData: () => Promise.resolve(++counter), + $injector, + $scope + }; + + const ctrl = new MonitoringViewBaseController(opts); + Promise.all([ + ctrl.updateData(), + ctrl.updateData(), + ]).then(() => { + expect(counter).to.be(1); + done(); + }); + }); + describe('time filter', () => { it('enables timepicker and auto refresh #1', () => { expect(timefilter.isTimeRangeSelectorEnabled).to.be(true); From d870ac83fe7ff64b78e51347e9c3c3f64af1d13a Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Mon, 17 Dec 2018 10:46:17 -0500 Subject: [PATCH 6/8] Fix cluster name showing up --- x-pack/plugins/monitoring/public/directives/main/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/monitoring/public/directives/main/index.html b/x-pack/plugins/monitoring/public/directives/main/index.html index d21c9cfba59a2b..83b45939ce4924 100644 --- a/x-pack/plugins/monitoring/public/directives/main/index.html +++ b/x-pack/plugins/monitoring/public/directives/main/index.html @@ -253,7 +253,7 @@

{{ monitoringMain.pipelineId }}