`;
diff --git a/x-pack/plugins/monitoring/public/components/summary_status/summary_status.js b/x-pack/plugins/monitoring/public/components/summary_status/summary_status.js
index 268500cb3fa5e..6aa649457c5cc 100644
--- a/x-pack/plugins/monitoring/public/components/summary_status/summary_status.js
+++ b/x-pack/plugins/monitoring/public/components/summary_status/summary_status.js
@@ -7,47 +7,29 @@
import React, { Fragment } from 'react';
import PropTypes from 'prop-types';
import { isEmpty, capitalize } from 'lodash';
-import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { EuiFlexGroup, EuiFlexItem, EuiStat, EuiHorizontalRule } from '@elastic/eui';
import { StatusIcon } from '../status_icon/index.js';
-import { FormattedMessage } from '@kbn/i18n/react';
-import { i18n } from '@kbn/i18n';
-const wrapChild = ({ label, value, dataTestSubj }, index) => (
+const wrapChild = ({ label, value, ...props }, index) => (
);
@@ -57,33 +39,34 @@ const StatusIndicator = ({ status, isOnline, IconComponent }) => {
}
return (
-
);
};
-// eslint-disable-next-line no-unused-vars
-export function SummaryStatus({ metrics, status, isOnline, IconComponent = DefaultIconComponent, intl, ...props }) {
+export function SummaryStatus({ metrics, status, isOnline, IconComponent = DefaultIconComponent, ...props }) {
return (
-
-
-
-
-
- {metrics.map(wrapChild)}
-
-
-
-
-
-
-
+
+
+
+ {metrics.map(wrapChild)}
+
+
);
}
diff --git a/x-pack/plugins/monitoring/public/components/summary_status/summary_status.test.js b/x-pack/plugins/monitoring/public/components/summary_status/summary_status.test.js
index d66c1dd54619c..e48921d4e16f1 100644
--- a/x-pack/plugins/monitoring/public/components/summary_status/summary_status.test.js
+++ b/x-pack/plugins/monitoring/public/components/summary_status/summary_status.test.js
@@ -15,12 +15,12 @@ describe('Summary Status Component', () => {
{
label: 'Free Disk Space',
value: '173.9 GB',
- dataTestSubj: 'freeDiskSpace'
+ 'data-test-subj': 'freeDiskSpace'
},
{
label: 'Documents',
value: '24.8k',
- dataTestSubj: 'documentCount'
+ 'data-test-subj': 'documentCount'
},
],
status: 'green'
@@ -34,12 +34,12 @@ describe('Summary Status Component', () => {
metrics: [
{
value: '127.0.0.1:9300',
- dataTestSubj: 'transportAddress'
+ 'data-test-subj': 'transportAddress'
},
{
label: 'Documents',
value: '24.8k',
- dataTestSubj: 'documentCount'
+ 'data-test-subj': 'documentCount'
},
],
status: 'yellow'
@@ -54,12 +54,12 @@ describe('Summary Status Component', () => {
{
label: 'Free Disk Space',
value: '173.9 GB',
- dataTestSubj: 'freeDiskSpace'
+ 'data-test-subj': 'freeDiskSpace'
},
{
label: 'Documents',
value: '24.8k',
- dataTestSubj: 'documentCount'
+ 'data-test-subj': 'documentCount'
},
]
};
diff --git a/x-pack/plugins/monitoring/public/components/table/eui_table.js b/x-pack/plugins/monitoring/public/components/table/eui_table.js
new file mode 100644
index 0000000000000..2cc7154a85c9a
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/components/table/eui_table.js
@@ -0,0 +1,43 @@
+/*
+ * 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 {
+ EuiInMemoryTable
+} from '@elastic/eui';
+
+export class EuiMonitoringTable extends React.PureComponent {
+ render() {
+ const {
+ rows: items,
+ search = {},
+ columns: _columns,
+ ...props
+ } = this.props;
+
+ if (search.box && !search.box['data-test-subj']) {
+ search.box['data-test-subj'] = 'monitoringTableToolBar';
+ }
+
+ const columns = _columns.map(column => {
+ if (!column['data-test-subj']) {
+ column['data-test-subj'] = 'monitoringTableHasData';
+ }
+ return column;
+ });
+
+ return (
+
+
+
+ );
+ }
+}
diff --git a/x-pack/plugins/monitoring/public/components/table/index.js b/x-pack/plugins/monitoring/public/components/table/index.js
index 38b972c1b0245..85900144cd57f 100644
--- a/x-pack/plugins/monitoring/public/components/table/index.js
+++ b/x-pack/plugins/monitoring/public/components/table/index.js
@@ -5,4 +5,5 @@
*/
export { MonitoringTable } from './table';
-export { tableStorageGetter, tableStorageSetter } from './storage';
+export { EuiMonitoringTable } from './eui_table';
+export { tableStorageGetter, tableStorageSetter, euiTableStorageGetter, euiTableStorageSetter } from './storage';
diff --git a/x-pack/plugins/monitoring/public/components/table/storage.js b/x-pack/plugins/monitoring/public/components/table/storage.js
index 576dddbee8098..9ddb611331cd0 100644
--- a/x-pack/plugins/monitoring/public/components/table/storage.js
+++ b/x-pack/plugins/monitoring/public/components/table/storage.js
@@ -33,3 +33,26 @@ export const tableStorageSetter = keyPrefix => {
return localStorageData;
};
};
+
+export const euiTableStorageGetter = keyPrefix => {
+ return storage => {
+ const localStorageData = storage.get(STORAGE_KEY) || {};
+ const sort = get(localStorageData, [ keyPrefix, 'sort' ]);
+ const page = get(localStorageData, [ keyPrefix, 'page' ]);
+
+ return { page, sort };
+ };
+};
+
+export const euiTableStorageSetter = keyPrefix => {
+ return (storage, { sort, page }) => {
+ const localStorageData = storage.get(STORAGE_KEY) || {};
+
+ set(localStorageData, [ keyPrefix, 'sort' ], sort || undefined); // don`t store empty data
+ set(localStorageData, [ keyPrefix, 'page' ], page || undefined);
+
+ storage.set(STORAGE_KEY, localStorageData);
+
+ return localStorageData;
+ };
+};
diff --git a/x-pack/plugins/monitoring/public/directives/alerts/index.js b/x-pack/plugins/monitoring/public/directives/alerts/index.js
deleted file mode 100644
index d125b0f1c074b..0000000000000
--- a/x-pack/plugins/monitoring/public/directives/alerts/index.js
+++ /dev/null
@@ -1,173 +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 { capitalize } from 'lodash';
-import React from 'react';
-import { render } from 'react-dom';
-import { EuiIcon, EuiHealth } from '@elastic/eui';
-import { uiModules } from 'ui/modules';
-import { KuiTableRowCell, KuiTableRow } from '@kbn/ui-framework/components';
-import { MonitoringTable } from 'plugins/monitoring/components/table';
-import { CALCULATE_DURATION_SINCE, SORT_DESCENDING } from '../../../common/constants';
-import { Tooltip } from 'plugins/monitoring/components/tooltip';
-import { FormattedAlert } from 'plugins/monitoring/components/alerts/formatted_alert';
-import { mapSeverity } from 'plugins/monitoring/components/alerts/map_severity';
-import { formatTimestampToDuration } from '../../../common/format_timestamp_to_duration';
-import { formatDateTimeLocal } from '../../../common/formatting';
-import { i18n } from '@kbn/i18n';
-import { injectI18n, I18nProvider, FormattedMessage } from '@kbn/i18n/react';
-
-const linkToCategories = {
- 'elasticsearch/nodes': i18n.translate('xpack.monitoring.alerts.esNodesCategoryLabel', {
- defaultMessage: 'Elasticsearch Nodes',
- }),
- 'elasticsearch/indices': i18n.translate('xpack.monitoring.alerts.esIndicesCategoryLabel', {
- defaultMessage: 'Elasticsearch Indices',
- }),
- 'kibana/instances': i18n.translate('xpack.monitoring.alerts.kibanaInstancesCategoryLabel', {
- defaultMessage: 'Kibana Instances',
- }),
- 'logstash/instances': i18n.translate('xpack.monitoring.alerts.logstashNodesCategoryLabel', {
- defaultMessage: 'Logstash Nodes',
- }),
-};
-const filterFields = [ 'message', 'severity_group', 'prefix', 'suffix', 'metadata.link', 'since', 'timestamp', 'update_timestamp' ];
-const columns = [
- {
- title: i18n.translate('xpack.monitoring.alerts.statusColumnTitle', {
- defaultMessage: 'Status',
- }),
- sortKey: 'metadata.severity',
- sortOrder: SORT_DESCENDING
- },
- {
- title: i18n.translate('xpack.monitoring.alerts.resolvedColumnTitle', {
- defaultMessage: 'Resolved',
- }),
- sortKey: 'resolved_timestamp'
- },
- {
- title: i18n.translate('xpack.monitoring.alerts.messageColumnTitle', {
- defaultMessage: 'Message',
- }),
- sortKey: 'message'
- },
- {
- title: i18n.translate('xpack.monitoring.alerts.categoryColumnTitle', {
- defaultMessage: 'Category',
- }),
- sortKey: 'metadata.link'
- },
- {
- title: i18n.translate('xpack.monitoring.alerts.lastCheckedColumnTitle', {
- defaultMessage: 'Last Checked',
- }),
- sortKey: 'update_timestamp'
- },
- {
- title: i18n.translate('xpack.monitoring.alerts.triggeredColumnTitle', {
- defaultMessage: 'Triggered',
- }),
- sortKey: 'timestamp'
- },
-];
-const alertRowFactory = (scope, kbnUrl) => {
- return injectI18n(props => {
- const changeUrl = target => {
- scope.$evalAsync(() => {
- kbnUrl.changePath(target);
- });
- };
- const severityIcon = mapSeverity(props.metadata.severity);
- const resolution = {
- icon: null,
- text: props.intl.formatMessage({ id: 'xpack.monitoring.alerts.notResolvedDescription',
- defaultMessage: 'Not Resolved',
- })
- };
-
- if (props.resolved_timestamp) {
- resolution.text = props.intl.formatMessage({ id: 'xpack.monitoring.alerts.resolvedAgoDescription',
- defaultMessage: '{duration} ago',
- }, { duration: formatTimestampToDuration(props.resolved_timestamp, CALCULATE_DURATION_SINCE) }
- );
- } else {
- resolution.icon = (
-
- );
- }
-
- return (
-
-
-
-
- { capitalize(severityIcon.value) }
-
-
-
-
- { resolution.icon } { resolution.text }
-
-
-
-
-
- { linkToCategories[props.metadata.link] ? linkToCategories[props.metadata.link] :
- props.intl.formatMessage({ id: 'xpack.monitoring.alerts.generalCategoryLabel', defaultMessage: 'General', }) }
-
-
- { formatDateTimeLocal(props.update_timestamp) }
-
-
-
-
-
- );
- });
-};
-
-const uiModule = uiModules.get('monitoring/directives', []);
-uiModule.directive('monitoringClusterAlertsListing', (kbnUrl, i18n) => {
- return {
- restrict: 'E',
- scope: { alerts: '=' },
- link(scope, $el) {
- const filterAlertsPlaceholder = i18n('xpack.monitoring.alerts.filterAlertsPlaceholder', { defaultMessage: 'Filter Alerts…' });
-
- scope.$watch('alerts', (alerts = []) => {
- const alertsTable = (
-
-
-
- );
- render(alertsTable, $el[0]);
- });
-
- }
- };
-});
diff --git a/x-pack/plugins/monitoring/public/directives/all.js b/x-pack/plugins/monitoring/public/directives/all.js
index 98b3a10237ba2..4aca3c22fd8af 100644
--- a/x-pack/plugins/monitoring/public/directives/all.js
+++ b/x-pack/plugins/monitoring/public/directives/all.js
@@ -7,15 +7,12 @@
import './main';
import './chart';
import './sparkline';
-import './alerts';
import './cluster/overview';
import './cluster/listing';
import './elasticsearch/cluster_status';
import './elasticsearch/index_summary';
import './elasticsearch/node_summary';
import './elasticsearch/ml_job_listing';
-import './elasticsearch/shard_allocation';
-import './elasticsearch/shard_allocation/directives/clusterView';
import './logstash/cluster_status';
import './logstash/listing';
import './logstash/node_summary';
diff --git a/x-pack/plugins/monitoring/public/directives/beats/listing/index.js b/x-pack/plugins/monitoring/public/directives/beats/listing/index.js
index 779dffaf2309a..b2964a28574f9 100644
--- a/x-pack/plugins/monitoring/public/directives/beats/listing/index.js
+++ b/x-pack/plugins/monitoring/public/directives/beats/listing/index.js
@@ -7,160 +7,40 @@
import React from 'react';
import { render } from 'react-dom';
import { uiModules } from 'ui/modules';
-import { Stats } from 'plugins/monitoring/components/beats';
-import { formatMetric } from 'plugins/monitoring/lib/format_number';
import { I18nProvider } from '@kbn/i18n/react';
-import { i18n } from '@kbn/i18n';
-import {
- SORT_ASCENDING,
- SORT_DESCENDING,
- TABLE_ACTION_UPDATE_FILTER,
-} from '../../../../common/constants';
-import {
- KuiTableRowCell,
- KuiTableRow
-} from '@kbn/ui-framework/components';
-import { MonitoringTable } from 'plugins/monitoring/components/table';
-
-import {
- EuiLink,
-} from '@elastic/eui';
-
-const filterFields = [ 'name', 'type', 'version', 'output' ];
-const columns = [
- {
- title: i18n.translate('xpack.monitoring.beats.instances.nameTitle', { defaultMessage: 'Name' }),
- sortKey: 'name',
- sortOrder: SORT_ASCENDING
- },
- {
- title: i18n.translate('xpack.monitoring.beats.instances.typeTitle', { defaultMessage: 'Type' }),
- sortKey: 'type'
- },
- {
- title: i18n.translate('xpack.monitoring.beats.instances.outputEnabledTitle', { defaultMessage: 'Output Enabled' }),
- sortKey: 'output'
- },
- {
- title: i18n.translate('xpack.monitoring.beats.instances.totalEventsRateTitle', { defaultMessage: 'Total Events Rate' }),
- sortKey: 'total_events_rate',
- secondarySortOrder: SORT_DESCENDING
- },
- {
- title: i18n.translate('xpack.monitoring.beats.instances.bytesSentRateTitle', { defaultMessage: 'Bytes Sent Rate' }),
- sortKey: 'bytes_sent_rate'
- },
- {
- title: i18n.translate('xpack.monitoring.beats.instances.outputErrorsTitle', { defaultMessage: 'Output Errors' }),
- sortKey: 'errors'
- },
- {
- title: i18n.translate('xpack.monitoring.beats.instances.allocatedMemoryTitle', { defaultMessage: 'Allocated Memory' }),
- sortKey: 'memory'
- },
- {
- title: i18n.translate('xpack.monitoring.beats.instances.versionTitle', { defaultMessage: 'Version' }),
- sortKey: 'version'
- },
-];
-const beatRowFactory = (scope, kbnUrl) => {
- return props => {
- const goToBeat = uuid => () => {
- scope.$evalAsync(() => {
- kbnUrl.changePath(`/beats/beat/${uuid}`);
- });
- };
- const applyFiltering = filterText => () => {
- props.dispatchTableAction(TABLE_ACTION_UPDATE_FILTER, filterText);
- };
-
- return (
-
-
-
-
- {props.name}
-
-
-
-
-
- {props.type}
-
-
-
- {props.output}
-
-
- {formatMetric(props.total_events_rate, '', '/s')}
-
-
- {formatMetric(props.bytes_sent_rate, 'byte', '/s')}
-
-
- {formatMetric(props.errors, '0')}
-
-
- {formatMetric(props.memory, 'byte')}
-
-
-
- {props.version}
-
-
-
- );
- };
-};
+import { Listing } from '../../../components/beats/listing/listing';
const uiModule = uiModules.get('monitoring/directives', []);
-uiModule.directive('monitoringBeatsListing', (kbnUrl, i18n) => {
+uiModule.directive('monitoringBeatsListing', (kbnUrl) => {
return {
restrict: 'E',
scope: {
data: '=',
- pageIndex: '=',
- filterText: '=',
- sortKey: '=',
- sortOrder: '=',
- onNewState: '=',
+ sorting: '=',
+ pagination: '=paginationSettings',
+ onTableChange: '=',
},
link(scope, $el) {
-
- scope.$watch('data', (data = {}) => {
- const filterBeatsPlaceholder = i18n('xpack.monitoring.beats.filterBeatsPlaceholder', { defaultMessage: 'Filter Beats…' });
-
+ function renderReact(data) {
render((
-
+
), $el[0]);
+ }
+ scope.$watch('data', (data = {}) => {
+ renderReact(data);
});
-
}
};
});
diff --git a/x-pack/plugins/monitoring/public/directives/cluster/listing/index.js b/x-pack/plugins/monitoring/public/directives/cluster/listing/index.js
index c4d2e0bf46d62..f7ce4592a78a7 100644
--- a/x-pack/plugins/monitoring/public/directives/cluster/listing/index.js
+++ b/x-pack/plugins/monitoring/public/directives/cluster/listing/index.js
@@ -6,408 +6,403 @@
import React, { Fragment } from 'react';
import { render } from 'react-dom';
-import { capitalize, get } from 'lodash';
+import { capitalize, partial } from 'lodash';
import moment from 'moment';
import numeral from '@elastic/numeral';
import { uiModules } from 'ui/modules';
import chrome from 'ui/chrome';
-import {
- KuiTableRowCell,
- KuiTableRow
-} from '@kbn/ui-framework/components';
import {
EuiHealth,
EuiLink,
+ EuiPage,
+ EuiPageBody,
+ EuiPageContent,
} from '@elastic/eui';
import { toastNotifications } from 'ui/notify';
-import { MonitoringTable } from 'plugins/monitoring/components/table';
+import { EuiMonitoringTable } from 'plugins/monitoring/components/table';
import { Tooltip } from 'plugins/monitoring/components/tooltip';
import { AlertsIndicator } from 'plugins/monitoring/components/cluster/listing/alerts_indicator';
-import { SORT_ASCENDING } from '../../../../common/constants';
import { I18nProvider, FormattedMessage } from '@kbn/i18n/react';
import { i18n } from '@kbn/i18n';
-const filterFields = [ 'cluster_name', 'status', 'license.type' ];
-const columns = [
- {
- title: i18n.translate('xpack.monitoring.cluster.listing.nameColumnTitle', {
- defaultMessage: 'Name',
- }),
- sortKey: 'cluster_name', sortOrder: SORT_ASCENDING
- },
- {
- title: i18n.translate('xpack.monitoring.cluster.listing.statusColumnTitle', {
- defaultMessage: 'Status',
- }),
- sortKey: 'status'
- },
- {
- title: i18n.translate('xpack.monitoring.cluster.listing.nodesColumnTitle', {
- defaultMessage: 'Nodes',
- }),
- sortKey: 'elasticsearch.cluster_stats.nodes.count.total'
- },
- {
- title: i18n.translate('xpack.monitoring.cluster.listing.indicesColumnTitle', {
- defaultMessage: 'Indices',
- }),
- sortKey: 'elasticsearch.cluster_stats.indices.count'
- },
- {
- title: i18n.translate('xpack.monitoring.cluster.listing.dataColumnTitle', {
- defaultMessage: 'Data',
- }),
- sortKey: 'elasticsearch.cluster_stats.indices.store.size_in_bytes'
- },
- {
- title: i18n.translate('xpack.monitoring.cluster.listing.logstashColumnTitle', {
- defaultMessage: 'Logstash',
- }),
- sortKey: 'logstash.node_count'
- },
- {
- title: i18n.translate('xpack.monitoring.cluster.listing.kibanaColumnTitle', {
- defaultMessage: 'Kibana',
- }),
- sortKey: 'kibana.count'
- },
- {
- title: i18n.translate('xpack.monitoring.cluster.listing.licenseColumnTitle', {
- defaultMessage: 'License',
- }),
- sortKey: 'license.type'
- }
-];
-
-const clusterRowFactory = (scope, globalState, kbnUrl, showLicenseExpiration) => {
- return class ClusterRow extends React.Component {
- constructor(props) {
- super(props);
- }
-
- changeCluster() {
- scope.$evalAsync(() => {
- globalState.cluster_uuid = this.props.cluster_uuid;
- globalState.ccs = this.props.ccs;
- globalState.save();
- kbnUrl.changePath('/overview');
- });
- }
-
- licenseWarning({ title, text }) {
- scope.$evalAsync(() => {
- toastNotifications.addWarning({ title, text, 'data-test-subj': 'monitoringLicenseWarning' });
- });
- }
+const IsClusterSupported = ({ isSupported, children }) => {
+ return isSupported ? children : '-';
+};
- handleClickIncompatibleLicense() {
- this.licenseWarning({
- title: (
-
- ),
- text: (
-
-
-
-
-
-
-
-
- )
- }}
- />
-
-
- ),
- });
- }
+/*
+ * This checks if alerts feature is supported via monitoring cluster
+ * license. If the alerts feature is not supported because the prod cluster
+ * license is basic, IsClusterSupported makes the status col hidden
+ * completely
+ */
+const IsAlertsSupported = (props) => {
+ const {
+ alertsMeta = { enabled: true },
+ clusterMeta = { enabled: true }
+ } = props.cluster.alerts;
+ if (alertsMeta.enabled && clusterMeta.enabled) {
+ return
{ props.children };
+ }
- handleClickInvalidLicense() {
- const licensingPath = `${chrome.getBasePath()}/app/kibana#/management/elasticsearch/license_management/home`;
+ const message = alertsMeta.message || clusterMeta.message;
+ return (
+
+
+ N/A
+
+
+ );
+};
- this.licenseWarning({
- title: (
-
- ),
- text: (
-
-
-
-
-
-
-
-
- ),
- getLicenseInfoLink: (
-
-
-
- )
- }}
- />
-
-
- ),
- });
- }
+const getColumns = (
+ showLicenseExpiration,
+ changeCluster,
+ handleClickIncompatibleLicense,
+ handleClickInvalidLicense
+) => {
+ return [
+ {
+ name: i18n.translate('xpack.monitoring.cluster.listing.nameColumnTitle', {
+ defaultMessage: 'Name',
+ }),
+ field: 'cluster_name',
+ sortable: true,
+ render: (value, cluster) => {
+ if (cluster.isSupported) {
+ return (
+
changeCluster(cluster.cluster_uuid, cluster.ccs)}
+ data-test-subj="clusterLink"
+ >
+ { value }
+
+ );
+ }
- getClusterAction() {
- if (this.props.isSupported) {
- return (
-
- { this.props.cluster_name }
-
- );
- }
+ // not supported because license is basic/not compatible with multi-cluster
+ if (cluster.license) {
+ return (
+
handleClickIncompatibleLicense(cluster.cluster_name)}
+ data-test-subj="clusterLink"
+ >
+ { value }
+
+ );
+ }
- // not supported because license is basic/not compatible with multi-cluster
- if (this.props.license) {
+ // not supported because license is invalid
return (
handleClickInvalidLicense(cluster.cluster_name)}
data-test-subj="clusterLink"
>
- { this.props.cluster_name }
+ { value }
);
}
+ },
+ {
+ name: i18n.translate('xpack.monitoring.cluster.listing.statusColumnTitle', {
+ defaultMessage: 'Status',
+ }),
+ field: 'status',
+ 'data-test-subj': 'alertsStatus',
+ sortable: true,
+ render: (_status, cluster) => (
+
+
+
+
+
+ )
+ },
+ {
+ name: i18n.translate('xpack.monitoring.cluster.listing.nodesColumnTitle', {
+ defaultMessage: 'Nodes',
+ }),
+ field: 'elasticsearch.cluster_stats.nodes.count.total',
+ 'data-test-subj': 'nodesCount',
+ sortable: true,
+ render: (total, cluster) => (
+
+ { numeral(total).format('0,0') }
+
+ )
+ },
+ {
+ name: i18n.translate('xpack.monitoring.cluster.listing.indicesColumnTitle', {
+ defaultMessage: 'Indices',
+ }),
+ field: 'elasticsearch.cluster_stats.indices.count',
+ 'data-test-subj': 'indicesCount',
+ sortable: true,
+ render: (count, cluster) => (
+
+ { numeral(count).format('0,0') }
+
+ )
+ },
+ {
+ name: i18n.translate('xpack.monitoring.cluster.listing.dataColumnTitle', {
+ defaultMessage: 'Data',
+ }),
+ field: 'elasticsearch.cluster_stats.indices.store.size_in_bytes',
+ 'data-test-subj': 'dataSize',
+ sortable: true,
+ render: (size, cluster) => (
+
+ { numeral(size).format('0,0[.]0 b')}
+
+ )
+ },
+ {
+ name: i18n.translate('xpack.monitoring.cluster.listing.logstashColumnTitle', {
+ defaultMessage: 'Logstash',
+ }),
+ field: 'logstash.node_count',
+ 'data-test-subj': 'logstashCount',
+ sortable: true,
+ render: (count, cluster) => (
+
+ { numeral(count).format('0,0') }
+
+ )
+ },
+ {
+ name: i18n.translate('xpack.monitoring.cluster.listing.kibanaColumnTitle', {
+ defaultMessage: 'Kibana',
+ }),
+ field: 'kibana.count',
+ 'data-test-subj': 'kibanaCount',
+ sortable: true,
+ render: (count, cluster) => (
+
+ { numeral(count).format('0,0') }
+
+ )
+ },
+ {
+ name: i18n.translate('xpack.monitoring.cluster.listing.licenseColumnTitle', {
+ defaultMessage: 'License',
+ }),
+ field: 'license.type',
+ 'data-test-subj': 'clusterLicense',
+ sortable: true,
+ render: (licenseType, cluster) => {
+ const license = cluster.license;
+ if (license) {
+ const licenseExpiry = () => {
+ if (license.expiry_date_in_millis < moment().valueOf()) {
+ // license is expired
+ return (
+
+ Expired
+
+ );
+ }
- // not supported because license is invalid
- return (
-
- { this.props.cluster_name }
-
- );
- }
-
- getLicenseInfo() {
- if (this.props.license) {
- const licenseExpiry = () => {
- if (this.props.license.expiry_date_in_millis < moment().valueOf()) {
- // license is expired
+ // license is fine
return (
-
-
+
+ Expires { moment(license.expiry_date_in_millis).format('D MMM YY') }
);
- }
+ };
- // license is fine
return (
-
-
-
+
+
+ { capitalize(licenseType) }
+
+
+ { showLicenseExpiration ? licenseExpiry() : null }
+
+
);
- };
+ }
+ // there is no license!
return (
-
-
- { capitalize(this.props.license.type) }
-
-
- { showLicenseExpiration ? licenseExpiry() : null }
-
-
+ handleClickInvalidLicense(cluster.cluster_name)}
+ >
+
+ N/A
+
+
);
}
-
- // there is no license!
- return (
-
-
-
-
-
- );
}
+ ];
+};
- render() {
- const isSupported = this.props.isSupported;
- const isClusterSupportedFactory = () => {
- return (props) => {
- if (isSupported) {
- return { props.children };
- }
- return -;
- };
- };
- const IsClusterSupported = isClusterSupportedFactory(isSupported);
- const classes = [];
- if (!isSupported) {
- classes.push('basic');
- }
+const changeCluster = (scope, globalState, kbnUrl, clusterUuid, ccs) => {
+ scope.$evalAsync(() => {
+ globalState.cluster_uuid = clusterUuid;
+ globalState.ccs = ccs;
+ globalState.save();
+ kbnUrl.changePath('/overview');
+ });
+};
- /*
- * This checks if alerts feature is supported via monitoring cluster
- * license. If the alerts feature is not supported because the prod cluster
- * license is basic, IsClusterSupported makes the status col hidden
- * completely
- */
- const IsAlertsSupported = (props) => {
- const {
- alertsMeta = { enabled: true },
- clusterMeta = { enabled: true }
- } = props.cluster.alerts;
- if (alertsMeta.enabled && clusterMeta.enabled) {
- return { props.children };
- }
+const licenseWarning = (scope, { title, text }) => {
+ scope.$evalAsync(() => {
+ toastNotifications.addWarning({ title, text, 'data-test-subj': 'monitoringLicenseWarning' });
+ });
+};
- const message = alertsMeta.message || clusterMeta.message;
- return (
-
-
-
-
-
- );
- };
+const handleClickIncompatibleLicense = (scope, clusterName) => {
+ licenseWarning(scope, {
+ title: (
+
+ ),
+ text: (
+
+
+
+
+
+
+
+
+ )
+ }}
+ />
+
+
+ ),
+ });
+};
- return (
-
-
-
- { this.getClusterAction() }
-
-
-
-
-
-
-
-
-
-
-
- { numeral(get(this.props, 'elasticsearch.cluster_stats.nodes.count.total')).format('0,0') }
-
-
-
-
- { numeral(get(this.props, 'elasticsearch.cluster_stats.indices.count')).format('0,0') }
-
-
-
-
- { numeral(get(this.props, 'elasticsearch.cluster_stats.indices.store.size_in_bytes')).format('0,0[.]0 b') }
-
-
-
-
- { numeral(get(this.props, 'logstash.node_count')).format('0,0') }
-
-
-
-
- { numeral(get(this.props, 'kibana.count')).format('0,0') }
-
-
-
- { this.getLicenseInfo() }
-
-
- );
- }
+const handleClickInvalidLicense = (scope, clusterName) => {
+ const licensingPath = `${chrome.getBasePath()}/app/kibana#/management/elasticsearch/license_management/home`;
- };
+ licenseWarning(scope, {
+ title: (
+
+ ),
+ text: (
+
+
+
+
+
+
+
+
+ ),
+ getLicenseInfoLink: (
+
+
+
+ )
+ }}
+ />
+
+
+ ),
+ });
};
const uiModule = uiModules.get('monitoring/directives', []);
-uiModule.directive('monitoringClusterListing', ($injector, i18n) => {
+uiModule.directive('monitoringClusterListing', ($injector) => {
return {
restrict: 'E',
scope: {
clusters: '=',
- pageIndex: '=',
+ sorting: '=',
filterText: '=',
- sortKey: '=',
- sortOrder: '=',
- onNewState: '=',
+ paginationSettings: '=pagination',
+ onTableChange: '=',
},
link(scope, $el) {
const globalState = $injector.get('globalState');
const kbnUrl = $injector.get('kbnUrl');
const showLicenseExpiration = $injector.get('showLicenseExpiration');
- const filterClustersPlaceholder = i18n('xpack.monitoring.cluster.listing.filterClustersPlaceholder',
- { defaultMessage: 'Filter Clusters…' }
- );
+
+ const _changeCluster = partial(changeCluster, scope, globalState, kbnUrl);
+ const _handleClickIncompatibleLicense = partial(handleClickIncompatibleLicense, scope);
+ const _handleClickInvalidLicense = partial(handleClickInvalidLicense, scope);
+
+ const { sorting, pagination, onTableChange } = scope;
scope.$watch('clusters', (clusters = []) => {
const clusterTable = (
-
+
+
+
+ {
+ return {
+ 'data-test-subj': `clusterRow_${item.cluster_uuid}`
+ };
+ }}
+ sorting={{
+ ...sorting,
+ sort: {
+ ...sorting.sort,
+ field: 'cluster_name'
+ }
+ }}
+ pagination={pagination}
+ search={{
+ box: {
+ incremental: true,
+ placeholder: scope.filterText
+ },
+ }}
+ onTableChange={onTableChange}
+ />
+
+
+
);
render(clusterTable, $el[0]);
diff --git a/x-pack/plugins/monitoring/public/directives/elasticsearch/ml_job_listing/index.js b/x-pack/plugins/monitoring/public/directives/elasticsearch/ml_job_listing/index.js
index 2fac710fef7f4..bb63dc321627d 100644
--- a/x-pack/plugins/monitoring/public/directives/elasticsearch/ml_job_listing/index.js
+++ b/x-pack/plugins/monitoring/public/directives/elasticsearch/ml_job_listing/index.js
@@ -9,150 +9,156 @@ import numeral from '@elastic/numeral';
import React from 'react';
import { render } from 'react-dom';
import { uiModules } from 'ui/modules';
-import {
- KuiTableRowCell,
- KuiTableRow
-} from '@kbn/ui-framework/components';
-import { MonitoringTable } from 'plugins/monitoring/components/table';
+import { EuiMonitoringTable } from 'plugins/monitoring/components/table';
import { MachineLearningJobStatusIcon } from 'plugins/monitoring/components/elasticsearch/ml_job_listing/status_icon';
-import { SORT_ASCENDING } from '../../../../common/constants';
import { LARGE_ABBREVIATED, LARGE_BYTES } from '../../../../common/formatting';
import {
EuiLink,
+ EuiPage,
+ EuiPageContent,
+ EuiPageBody,
} from '@elastic/eui';
+import { ClusterStatus } from '../../../components/elasticsearch/cluster_status';
import { i18n } from '@kbn/i18n';
-import { I18nProvider } from '@kbn/i18n/react';
+import { I18nProvider, FormattedMessage } from '@kbn/i18n/react';
-const filterFields = [ 'job_id', 'state', 'node.name' ];
-const columns = [
+const getColumns = (kbnUrl, scope) => ([
{
- title: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.jobIdTitle', {
+ name: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.jobIdTitle', {
defaultMessage: 'Job ID'
}),
- sortKey: 'job_id',
- sortOrder: SORT_ASCENDING
+ field: 'job_id',
+ sortable: true
},
{
- title: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.stateTitle', {
+ name: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.stateTitle', {
defaultMessage: 'State'
}),
- sortKey: 'state'
+ field: 'state',
+ sortable: true,
+ render: state => (
+
+
+ { capitalize(state) }
+
+ )
},
{
- title: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.processedRecordsTitle', {
+ name: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.processedRecordsTitle', {
defaultMessage: 'Processed Records'
}),
- sortKey: 'data_counts.processed_record_count'
+ field: 'data_counts.processed_record_count',
+ sortable: true,
+ render: value => (
+
+ {numeral(value).format(LARGE_ABBREVIATED)}
+
+ )
},
{
- title: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.modelSizeTitle', {
+ name: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.modelSizeTitle', {
defaultMessage: 'Model Size'
}),
- sortKey: 'model_size_stats.model_bytes'
+ field: 'model_size_stats.model_bytes',
+ sortable: true,
+ render: value => (
+
+ {numeral(value).format(LARGE_BYTES)}
+
+ )
},
{
- title: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.forecastsTitle', {
+ name: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.forecastsTitle', {
defaultMessage: 'Forecasts'
}),
- sortKey: 'forecasts_stats.total'
+ field: 'forecasts_stats.total',
+ sortable: true,
+ render: value => (
+
+ {numeral(value).format(LARGE_ABBREVIATED)}
+
+ )
},
{
- title: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.nodeTitle', {
+ name: i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.nodeTitle', {
defaultMessage: 'Node'
}),
- sortKey: 'node.name'
- }
-];
-const jobRowFactory = (scope, kbnUrl) => {
- const goToNode = nodeId => {
- scope.$evalAsync(() => kbnUrl.changePath(`/elasticsearch/nodes/${nodeId}`));
- };
- const getNode = node => {
- if (node) {
+ field: 'node.name',
+ sortable: true,
+ render: (name, node) => {
+ if (node) {
+ return (
+ {
+ scope.$evalAsync(() => kbnUrl.changePath(`/elasticsearch/nodes/${node.id}`));
+ }}
+ >
+ { name }
+
+ );
+ }
+
return (
-
- { node.name }
-
+
);
}
- return i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.noDataLabel', {
- defaultMessage: 'N/A'
- });
- };
-
- return function JobRow(props) {
- return (
-
- { props.job_id }
-
-
- { capitalize(props.state) }
-
- { numeral(props.data_counts.processed_record_count).format(LARGE_ABBREVIATED) }
- { numeral(props.model_size_stats.model_bytes).format(LARGE_BYTES) }
- { numeral(props.forecasts_stats.total).format(LARGE_ABBREVIATED) }
-
- { getNode(props.node) }
-
-
- );
- };
-};
+ }
+]);
const uiModule = uiModules.get('monitoring/directives', []);
-uiModule.directive('monitoringMlListing', (kbnUrl, i18n) => {
+uiModule.directive('monitoringMlListing', kbnUrl => {
return {
restrict: 'E',
scope: {
jobs: '=',
- pageIndex: '=',
- filterText: '=',
- sortKey: '=',
- sortOrder: '=',
- onNewState: '=',
+ paginationSettings: '=',
+ sorting: '=',
+ onTableChange: '=',
+ status: '=',
},
link(scope, $el) {
+ const columns = getColumns(kbnUrl, scope);
- const getNoDataMessage = filterText => {
- if (filterText) {
- return (
- i18n('xpack.monitoring.elasticsearch.mlJobListing.noFilteredJobsDescription', {
- // eslint-disable-next-line max-len
- defaultMessage: 'There are no Machine Learning Jobs that match the filter [{filterText}] or the time range. Try changing the filter or time range.',
- values: {
- filterText: filterText.trim()
- }
- })
- );
- }
- return i18n('xpack.monitoring.elasticsearch.mlJobListing.noJobsDescription', {
- defaultMessage: 'There are no Machine Learning Jobs that match your query. Try changing the time range selection.'
- });
- };
-
- const filterJobsPlaceholder = i18n('xpack.monitoring.elasticsearch.mlJobListing.filterJobsPlaceholder', {
+ const filterJobsPlaceholder = i18n.translate('xpack.monitoring.elasticsearch.mlJobListing.filterJobsPlaceholder', {
defaultMessage: 'Filter Jobs…'
});
scope.$watch('jobs', (jobs = []) => {
const mlTable = (
-
+
+
+
+
+
+
+
+
);
render(mlTable, $el[0]);
diff --git a/x-pack/plugins/monitoring/public/directives/elasticsearch/shard_allocation/directives/clusterView.js b/x-pack/plugins/monitoring/public/directives/elasticsearch/shard_allocation/directives/clusterView.js
deleted file mode 100644
index 83e052c3f5b52..0000000000000
--- a/x-pack/plugins/monitoring/public/directives/elasticsearch/shard_allocation/directives/clusterView.js
+++ /dev/null
@@ -1,42 +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 { ClusterView } from '../components/clusterView';
-import { uiModules } from 'ui/modules';
-import { I18nProvider } from '@kbn/i18n/react';
-
-const uiModule = uiModules.get('monitoring/directives', []);
-uiModule.directive('clusterView', kbnUrl => {
- return {
- restrict: 'E',
- scope: {
- totalCount: '=',
- filter: '=',
- showing: '=',
- labels: '=',
- shardStats: '=',
- showSystemIndices: '=',
- toggleShowSystemIndices: '='
- },
- link: function (scope, element) {
- ReactDOM.render(
-
-
- ,
- element[0]
- );
- }
- };
-});
diff --git a/x-pack/plugins/monitoring/public/directives/elasticsearch/shard_allocation/index.html b/x-pack/plugins/monitoring/public/directives/elasticsearch/shard_allocation/index.html
deleted file mode 100644
index f62b70882e90f..0000000000000
--- a/x-pack/plugins/monitoring/public/directives/elasticsearch/shard_allocation/index.html
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/x-pack/plugins/monitoring/public/directives/elasticsearch/shard_allocation/index.js b/x-pack/plugins/monitoring/public/directives/elasticsearch/shard_allocation/index.js
deleted file mode 100644
index 665c19eb1c391..0000000000000
--- a/x-pack/plugins/monitoring/public/directives/elasticsearch/shard_allocation/index.js
+++ /dev/null
@@ -1,45 +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 { uiModules } from 'ui/modules';
-import { labels } from './lib/labels';
-import { indicesByNodes } from './transformers/indices_by_nodes';
-import { nodesByIndices } from './transformers/nodes_by_indices';
-import template from './index.html';
-
-const uiModule = uiModules.get('monitoring/directives', []);
-uiModule.directive('monitoringShardAllocation', () => {
- return {
- restrict: 'E',
- template,
- scope: {
- view: '@',
- shards: '=',
- nodes: '=',
- shardStats: '=',
- showSystemIndices: '=',
- toggleShowSystemIndices: '='
- },
- link: (scope) => {
-
- const isIndexView = scope.view === 'index';
- const transformer = (isIndexView) ? indicesByNodes() : nodesByIndices();
-
- scope.isIndexView = isIndexView;
-
- scope.$watch('shards', (shards) => {
- let view = scope.view;
- scope.totalCount = shards.length;
- scope.showing = transformer(shards, scope.nodes);
- if (isIndexView && shards.some((shard) => shard.state === 'UNASSIGNED')) {
- view = 'indexWithUnassigned';
- }
- scope.labels = labels[view];
- });
-
- }
- };
-});
diff --git a/x-pack/plugins/monitoring/public/index.scss b/x-pack/plugins/monitoring/public/index.scss
index 67974b71cd72f..24a577aa0901d 100644
--- a/x-pack/plugins/monitoring/public/index.scss
+++ b/x-pack/plugins/monitoring/public/index.scss
@@ -20,4 +20,4 @@
@import 'components/table/index';
@import 'components/logstash/pipeline_viewer/views/index';
@import 'directives/chart/index';
-@import 'directives/elasticsearch/shard_allocation/index';
+@import 'components/elasticsearch/shard_allocation/index';
diff --git a/x-pack/plugins/monitoring/public/views/alerts/index.html b/x-pack/plugins/monitoring/public/views/alerts/index.html
index 5ef9cc2b03473..4a764634d86fa 100644
--- a/x-pack/plugins/monitoring/public/views/alerts/index.html
+++ b/x-pack/plugins/monitoring/public/views/alerts/index.html
@@ -1,28 +1,3 @@
-
-
- {{ alerts.data.message }}
-
-
-
-
-
-
-
-
-
-
+
diff --git a/x-pack/plugins/monitoring/public/views/alerts/index.js b/x-pack/plugins/monitoring/public/views/alerts/index.js
index 7b85d19bc8be0..ab8b57bff0723 100644
--- a/x-pack/plugins/monitoring/public/views/alerts/index.js
+++ b/x-pack/plugins/monitoring/public/views/alerts/index.js
@@ -4,13 +4,18 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import React from 'react';
+import { render } from 'react-dom';
import { find, get } from 'lodash';
import uiRoutes from 'ui/routes';
import template from './index.html';
-import { MonitoringViewBaseController } from 'plugins/monitoring/views';
import { routeInitProvider } from 'plugins/monitoring/lib/route_init';
import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler';
import { timefilter } from 'ui/timefilter';
+import { Alerts } from '../../components/alerts';
+import { MonitoringViewBaseEuiTableController } from '../base_eui_table_controller';
+import { I18nProvider, FormattedMessage } from '@kbn/i18n/react';
+import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiLink } from '@elastic/eui';
function getPageData($injector) {
const globalState = $injector.get('globalState');
@@ -44,10 +49,11 @@ uiRoutes.when('/alerts', {
alerts: getPageData
},
controllerAs: 'alerts',
- controller: class AlertsView extends MonitoringViewBaseController {
+ controller: class AlertsView extends MonitoringViewBaseEuiTableController {
constructor($injector, $scope, i18n) {
const $route = $injector.get('$route');
const globalState = $injector.get('globalState');
+ const kbnUrl = $injector.get('kbnUrl');
// breadcrumbs + page title
$scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid });
@@ -60,6 +66,41 @@ uiRoutes.when('/alerts', {
});
this.data = $route.current.locals.alerts;
+
+ const renderReact = data => {
+ const app = data.message
+ ? ({data.message}
)
+ : ();
+
+ render(
+
+
+
+
+ {app}
+
+
+
+
+
+
+
+ ,
+ document.getElementById('monitoringAlertsApp')
+ );
+ };
+ $scope.$watch(() => this.data, data => renderReact(data));
}
}
});
diff --git a/x-pack/plugins/monitoring/public/views/apm/instances/index.js b/x-pack/plugins/monitoring/public/views/apm/instances/index.js
index a49aad8ca912b..4c6c7ef784f0d 100644
--- a/x-pack/plugins/monitoring/public/views/apm/instances/index.js
+++ b/x-pack/plugins/monitoring/public/views/apm/instances/index.js
@@ -10,7 +10,7 @@ import uiRoutes from'ui/routes';
import { routeInitProvider } from 'plugins/monitoring/lib/route_init';
import template from './index.html';
import { ApmServerInstances } from '../../../components/apm/instances';
-import { MonitoringViewBaseTableController } from '../../base_table_controller';
+import { MonitoringViewBaseEuiTableController } from '../..';
import { I18nProvider } from '@kbn/i18n/react';
uiRoutes.when('/apm/instances', {
@@ -21,7 +21,7 @@ uiRoutes.when('/apm/instances', {
return routeInit();
},
},
- controller: class extends MonitoringViewBaseTableController {
+ controller: class extends MonitoringViewBaseEuiTableController {
constructor($injector, $scope, i18n) {
const $route = $injector.get('$route');
const globalState = $injector.get('globalState');
@@ -51,22 +51,18 @@ uiRoutes.when('/apm/instances', {
renderReact(data) {
const {
- pageIndex,
- filterText,
- sortKey,
- sortOrder,
- onNewState,
+ pagination,
+ sorting,
+ onTableChange,
} = this;
const component = (
diff --git a/x-pack/plugins/monitoring/public/views/base_eui_table_controller.js b/x-pack/plugins/monitoring/public/views/base_eui_table_controller.js
new file mode 100644
index 0000000000000..dfc548aeb97f2
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/views/base_eui_table_controller.js
@@ -0,0 +1,66 @@
+/*
+ * 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 { MonitoringViewBaseController } from './';
+import { euiTableStorageGetter, euiTableStorageSetter } from 'plugins/monitoring/components/table';
+import { EUI_SORT_ASCENDING } from '../../common/constants';
+
+/**
+ * Class to manage common instantiation behaviors in a view controller
+ * And add persistent state to a table:
+ * - page index: in table pagination, which page are we looking at
+ * - filter text: what filter was entered in the table's filter bar
+ * - sortKey: which column field of table data is used for sorting
+ * - sortOrder: is sorting ordered ascending or descending
+ *
+ * This is expected to be extended, and behavior enabled using super();
+ */
+export class MonitoringViewBaseEuiTableController extends MonitoringViewBaseController {
+
+ /**
+ * Create a table view controller
+ * - used by parent class:
+ * @param {String} title - Title of the page
+ * @param {Function} getPageData - Function to fetch page data
+ * @param {Service} $injector - Angular dependency injection service
+ * @param {Service} $scope - Angular view data binding service
+ * @param {Boolean} options.enableTimeFilter - Whether to show the time filter
+ * @param {Boolean} options.enableAutoRefresh - Whether to show the auto refresh control
+ * - specific to this class:
+ * @param {String} storageKey - the namespace that will be used to keep the state data in the Monitoring localStorage object
+ *
+ */
+ constructor(args) {
+ super(args);
+ const { storageKey, $injector } = args;
+ const storage = $injector.get('localStorage');
+
+ const getLocalStorageData = euiTableStorageGetter(storageKey);
+ const setLocalStorageData = euiTableStorageSetter(storageKey);
+ const { page, sort } = getLocalStorageData(storage);
+
+ this.pagination = page || {
+ initialPageSize: 20,
+ pageSizeOptions: [5, 10, 20, 50]
+ };
+
+ this.sorting = sort || {
+ sort: {
+ field: 'name',
+ direction: EUI_SORT_ASCENDING
+ }
+ };
+
+ this.onTableChange = ({ page, sort }) => {
+ setLocalStorageData(storage, {
+ page,
+ sort: {
+ sort
+ }
+ });
+ };
+ }
+}
diff --git a/x-pack/plugins/monitoring/public/views/base_table_controller.js b/x-pack/plugins/monitoring/public/views/base_table_controller.js
index 175a06aa92722..ad0a9678a36a6 100644
--- a/x-pack/plugins/monitoring/public/views/base_table_controller.js
+++ b/x-pack/plugins/monitoring/public/views/base_table_controller.js
@@ -50,5 +50,4 @@ export class MonitoringViewBaseTableController extends MonitoringViewBaseControl
setLocalStorageData(storage, newState);
};
}
-
}
diff --git a/x-pack/plugins/monitoring/public/views/cluster/listing/index.html b/x-pack/plugins/monitoring/public/views/cluster/listing/index.html
index 5030a67fe3ec5..4335a2fa282cf 100644
--- a/x-pack/plugins/monitoring/public/views/cluster/listing/index.html
+++ b/x-pack/plugins/monitoring/public/views/cluster/listing/index.html
@@ -1,18 +1,8 @@
-
-
-
-
-
+
diff --git a/x-pack/plugins/monitoring/public/views/cluster/listing/index.js b/x-pack/plugins/monitoring/public/views/cluster/listing/index.js
index 1ac9c633937d8..36bdb06da9fc0 100644
--- a/x-pack/plugins/monitoring/public/views/cluster/listing/index.js
+++ b/x-pack/plugins/monitoring/public/views/cluster/listing/index.js
@@ -6,7 +6,7 @@
import uiRoutes from 'ui/routes';
import { routeInitProvider } from 'plugins/monitoring/lib/route_init';
-import { MonitoringViewBaseTableController } from '../../';
+import { MonitoringViewBaseEuiTableController } from '../../';
import template from './index.html';
const getPageData = $injector => {
@@ -35,7 +35,7 @@ uiRoutes.when('/home', {
}
},
controllerAs: 'clusters',
- controller: class ClustersList extends MonitoringViewBaseTableController {
+ controller: class ClustersList extends MonitoringViewBaseEuiTableController {
constructor($injector, $scope) {
super({
diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/ccr/shard/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/ccr/shard/index.js
index 554aaaea31969..54164b06ce09b 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/ccr/shard/index.js
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/ccr/shard/index.js
@@ -50,7 +50,9 @@ uiRoutes.when('/elasticsearch/ccr/:index/shard/:shardId', {
this.renderReact = (props) => {
super.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 72c1b450dd640..2abb73d52adb6 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
@@ -4,21 +4,5 @@
resolver="{{ indexName }}"
page="advanced"
>
-
-
-
+
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 c011e8540c5f1..8f575b7809e73 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
@@ -7,12 +7,17 @@
/**
* 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';
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';
function getPageData($injector) {
const globalState = $injector.get('globalState');
@@ -75,5 +80,28 @@ uiRoutes.when('/elasticsearch/indices/:index/advanced', {
$executor.start($scope);
$scope.$on('$destroy', $executor.destroy);
+
+ function onBrush({ xaxis }) {
+ timefilter.setTime({
+ from: moment(xaxis.from),
+ to: moment(xaxis.to),
+ mode: 'absolute',
+ });
+ }
+
+ 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 d7c201da9d0dd..87bdcd5c16037 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.html
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.html
@@ -5,24 +5,5 @@
resolver="{{ indexName }}"
page="overview"
>
-
-
-
-
-
+
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 12b2e961ceea9..7727239906af0 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.js
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/index/index.js
@@ -7,12 +7,19 @@
/**
* 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';
import template from './index.html';
import { timefilter } from 'ui/timefilter';
+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';
function getPageData($injector) {
const $http = $injector.get('$http');
@@ -51,6 +58,7 @@ uiRoutes.when('/elasticsearch/indices/:index', {
timefilter.enableAutoRefreshSelector();
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;
@@ -75,5 +83,39 @@ uiRoutes.when('/elasticsearch/indices/:index', {
$executor.start($scope);
$scope.$on('$destroy', $executor.destroy);
+
+ function onBrush({ xaxis }) {
+ timefilter.setTime({
+ from: moment(xaxis.from),
+ to: moment(xaxis.to),
+ mode: 'absolute',
+ });
+ }
+
+ 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/indices/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/indices/index.js
index f8615657500d8..e91cb07169d33 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/indices/index.js
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/indices/index.js
@@ -8,7 +8,7 @@ import React from 'react';
import { find } from 'lodash';
import uiRoutes from 'ui/routes';
import { routeInitProvider } from 'plugins/monitoring/lib/route_init';
-import { MonitoringViewBaseTableController } from '../../';
+import { MonitoringViewBaseEuiTableController } from '../../';
import { ElasticsearchIndices } from '../../../components';
import template from './index.html';
import { I18nProvider } from '@kbn/i18n/react';
@@ -22,7 +22,7 @@ uiRoutes.when('/elasticsearch/indices', {
}
},
controllerAs: 'elasticsearchIndices',
- controller: class ElasticsearchIndicesController extends MonitoringViewBaseTableController {
+ controller: class ElasticsearchIndicesController extends MonitoringViewBaseEuiTableController {
constructor($injector, $scope, i18n) {
const $route = $injector.get('$route');
const globalState = $injector.get('globalState');
@@ -69,6 +69,9 @@ uiRoutes.when('/elasticsearch/indices', {
indices={indices}
showSystemIndices={showSystemIndices}
toggleShowSystemIndices={toggleShowSystemIndices}
+ sorting={this.sorting}
+ pagination={this.pagination}
+ onTableChange={this.onTableChange}
/>
);
diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/ml_jobs/index.html b/x-pack/plugins/monitoring/public/views/elasticsearch/ml_jobs/index.html
index 61aa9e49317da..b20c927841d4f 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/ml_jobs/index.html
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/ml_jobs/index.html
@@ -1,18 +1,9 @@
-
-
-
-
-
+
diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/ml_jobs/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/ml_jobs/index.js
index 579b84081c369..d8b3a7bc7a604 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/ml_jobs/index.js
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/ml_jobs/index.js
@@ -7,7 +7,7 @@
import { find } from 'lodash';
import uiRoutes from 'ui/routes';
import { routeInitProvider } from 'plugins/monitoring/lib/route_init';
-import { MonitoringViewBaseTableController } from '../../';
+import { MonitoringViewBaseEuiTableController } from '../../';
import { getPageData } from './get_page_data';
import template from './index.html';
@@ -21,7 +21,7 @@ uiRoutes.when('/elasticsearch/ml_jobs', {
pageData: getPageData
},
controllerAs: 'mlJobs',
- controller: class MlJobsList extends MonitoringViewBaseTableController {
+ controller: class MlJobsList extends MonitoringViewBaseEuiTableController {
constructor($injector, $scope, i18n) {
super({
diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.html b/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.html
index 4256c5bb5377b..c79c4eed46bb7 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.html
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.html
@@ -7,25 +7,5 @@
tab-icon-class="{{ pageData.nodeSummary.nodeTypeClass }}"
tab-icon-class="{{ pageData.nodeSummary.nodeTypeLabel }}"
>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
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 9a323cd8e5564..e48c12e06aefa 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
@@ -7,12 +7,17 @@
/**
* 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';
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';
function getPageData($injector) {
const $http = $injector.get('$http');
@@ -76,5 +81,28 @@ uiRoutes.when('/elasticsearch/nodes/:node/advanced', {
$executor.start($scope);
$scope.$on('$destroy', $executor.destroy);
+
+ function onBrush({ xaxis }) {
+ timefilter.setTime({
+ from: moment(xaxis.from),
+ to: moment(xaxis.to),
+ mode: 'absolute',
+ });
+ }
+
+ 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 5aca1c9625a15..ce43bed531011 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.html
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.html
@@ -7,25 +7,5 @@
tab-icon-class="{{ pageData.nodeSummary.nodeTypeClass }}"
tab-icon-class="{{ pageData.nodeSummary.nodeTypeLabel }}"
>
-
-
-
-
-
+
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 0e6825fefe002..52c3e310a656d 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js
@@ -7,12 +7,19 @@
/**
* Controller for Node Detail
*/
+import React from 'react';
+import { render } from 'react-dom';
import { find, 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';
uiRoutes.when('/elasticsearch/nodes/:node', {
template,
@@ -28,6 +35,7 @@ uiRoutes.when('/elasticsearch/nodes/:node', {
timefilter.enableAutoRefreshSelector();
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;
@@ -65,5 +73,35 @@ uiRoutes.when('/elasticsearch/nodes/:node', {
$executor.start($scope);
$scope.$on('$destroy', $executor.destroy);
+
+ function onBrush({ xaxis }) {
+ timefilter.setTime({
+ from: moment(xaxis.from),
+ to: moment(xaxis.to),
+ mode: 'absolute',
+ });
+ }
+
+ 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/elasticsearch/nodes/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/nodes/index.js
index ba36c490a737c..472be27a00cbf 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/nodes/index.js
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/nodes/index.js
@@ -9,7 +9,7 @@ import { find } from 'lodash';
import uiRoutes from 'ui/routes';
import template from './index.html';
import { routeInitProvider } from 'plugins/monitoring/lib/route_init';
-import { MonitoringViewBaseTableController } from '../../';
+import { MonitoringViewBaseEuiTableController } from '../../';
import { ElasticsearchNodes } from '../../../components';
import { I18nProvider } from '@kbn/i18n/react';
@@ -22,7 +22,7 @@ uiRoutes.when('/elasticsearch/nodes', {
}
},
controllerAs: 'elasticsearchNodes',
- controller: class ElasticsearchNodesController extends MonitoringViewBaseTableController {
+ controller: class ElasticsearchNodesController extends MonitoringViewBaseEuiTableController {
constructor($injector, $scope, i18n) {
const $route = $injector.get('$route');
const globalState = $injector.get('globalState');
@@ -55,6 +55,9 @@ uiRoutes.when('/elasticsearch/nodes', {
clusterStatus={clusterStatus}
nodes={nodes}
showCgroupMetricsElasticsearch={showCgroupMetricsElasticsearch}
+ sorting={this.sorting}
+ pagination={this.pagination}
+ onTableChange={this.onTableChange}
/>
);
diff --git a/x-pack/plugins/monitoring/public/views/index.js b/x-pack/plugins/monitoring/public/views/index.js
index 0e0d9b9a03852..f696ba42b262f 100644
--- a/x-pack/plugins/monitoring/public/views/index.js
+++ b/x-pack/plugins/monitoring/public/views/index.js
@@ -6,3 +6,4 @@
export { MonitoringViewBaseController } from './base_controller';
export { MonitoringViewBaseTableController } from './base_table_controller';
+export { MonitoringViewBaseEuiTableController } from './base_eui_table_controller';
diff --git a/x-pack/plugins/monitoring/public/views/kibana/instance/index.html b/x-pack/plugins/monitoring/public/views/kibana/instance/index.html
index 411868ee8a56c..8bb17839683a8 100644
--- a/x-pack/plugins/monitoring/public/views/kibana/instance/index.html
+++ b/x-pack/plugins/monitoring/public/views/kibana/instance/index.html
@@ -4,15 +4,5 @@
instance="{{ pageData.kibanaSummary.name }}"
data-test-subj="kibanaInstancePage"
>
-
-
+
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 86199bf510515..12989568f146c 100644
--- a/x-pack/plugins/monitoring/public/views/kibana/instance/index.js
+++ b/x-pack/plugins/monitoring/public/views/kibana/instance/index.js
@@ -7,12 +7,18 @@
/*
* Kibana Instance
*/
+import React from 'react';
+import { render } from 'react-dom';
import { get, 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 { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
+import { MonitoringTimeseriesContainer } from '../../../components/chart';
+import { DetailStatus } from 'plugins/monitoring/components/kibana/detail_status';
+import { I18nProvider } from '@kbn/i18n/react';
function getPageData($injector) {
const $http = $injector.get('$http');
@@ -45,7 +51,7 @@ uiRoutes.when('/kibana/instances/:uuid', {
},
pageData: getPageData
},
- controller($injector, $scope, i18n) {
+ controller($injector, $scope) {
timefilter.enableTimeRangeSelector();
timefilter.enableAutoRefreshSelector();
@@ -55,14 +61,7 @@ uiRoutes.when('/kibana/instances/:uuid', {
$scope.pageData = $route.current.locals.pageData;
const title = $injector.get('title');
- const routeTitle = i18n('xpack.monitoring.kibana.instance.routeTitle', {
- defaultMessage: 'Kibana - {kibanaSummaryName}',
- values: {
- kibanaSummaryName: get($scope.pageData, 'kibanaSummary.name')
- }
- });
-
- title($scope.cluster, routeTitle);
+ title($scope.cluster, `Kibana - ${get($scope.pageData, 'kibanaSummary.name')}`);
const $executor = $injector.get('$executor');
$executor.register({
@@ -73,5 +72,66 @@ uiRoutes.when('/kibana/instances/:uuid', {
$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);
+ }
}
});
diff --git a/x-pack/plugins/monitoring/public/views/kibana/instances/index.html b/x-pack/plugins/monitoring/public/views/kibana/instances/index.html
index dee4f1741ab47..8e1639a2323a5 100644
--- a/x-pack/plugins/monitoring/public/views/kibana/instances/index.html
+++ b/x-pack/plugins/monitoring/public/views/kibana/instances/index.html
@@ -3,19 +3,5 @@
name="kibanas"
data-test-subj="kibanaInstancesPage"
>
-
-
-
-
-
+
diff --git a/x-pack/plugins/monitoring/public/views/kibana/instances/index.js b/x-pack/plugins/monitoring/public/views/kibana/instances/index.js
index 21e03a37b9be1..2ace7b3b4f999 100644
--- a/x-pack/plugins/monitoring/public/views/kibana/instances/index.js
+++ b/x-pack/plugins/monitoring/public/views/kibana/instances/index.js
@@ -4,12 +4,111 @@
* you may not use this file except in compliance with the Elastic License.
*/
-import { find } from 'lodash';
+import React from 'react';
+import { render } from 'react-dom';
+import { find, capitalize } from 'lodash';
import uiRoutes from'ui/routes';
import { routeInitProvider } from 'plugins/monitoring/lib/route_init';
-import { MonitoringViewBaseTableController } from '../../';
+import { MonitoringViewBaseEuiTableController } from '../../';
import { getPageData } from './get_page_data';
import template from './index.html';
+import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiLink } from '@elastic/eui';
+import { ClusterStatus } from '../../../components/kibana/cluster_status';
+import { EuiMonitoringTable } from '../../../components/table';
+import { KibanaStatusIcon } from '../../../components/kibana/status_icon';
+import { formatMetric, formatNumber } from '../../../lib/format_number';
+import { i18n } from '@kbn/i18n';
+import { FormattedMessage, I18nProvider } from '@kbn/i18n/react';
+
+const getColumns = (kbnUrl, scope) => ([
+ {
+ name: i18n.translate('xpack.monitoring.kibana.listing.nameColumnTitle', {
+ defaultMessage: 'Name'
+ }),
+ field: 'kibana.name',
+ render: (name, kibana) => (
+ {
+ scope.$evalAsync(() => {
+ kbnUrl.changePath(`/kibana/instances/${kibana.kibana.uuid}`);
+ });
+ }}
+ data-test-subj={`kibanaLink-${name}`}
+ >
+ { name }
+
+ )
+ },
+ {
+ name: i18n.translate('xpack.monitoring.kibana.listing.statusColumnTitle', {
+ defaultMessage: 'Status'
+ }),
+ field: 'kibana.status',
+ render: (status, kibana) => (
+
+
+ { !kibana.availability ? (
+
+ ) : capitalize(status) }
+
+ )
+ },
+ {
+ name: i18n.translate('xpack.monitoring.kibana.listing.loadAverageColumnTitle', {
+ defaultMessage: 'Load Average'
+ }),
+ field: 'os.load.1m',
+ render: value => (
+
+ {formatMetric(value, '0.00')}
+
+ )
+ },
+ {
+ name: i18n.translate('xpack.monitoring.kibana.listing.memorySizeColumnTitle', {
+ defaultMessage: 'Memory Size'
+ }),
+ field: 'process.memory.resident_set_size_in_bytes',
+ render: value => (
+
+ {formatNumber(value, 'byte')}
+
+ )
+ },
+ {
+ name: i18n.translate('xpack.monitoring.kibana.listing.requestsColumnTitle', {
+ defaultMessage: 'Requests'
+ }),
+ field: 'requests.total',
+ render: value => (
+
+ {formatNumber(value, 'int_commas')}
+
+ )
+ },
+ {
+ name: i18n.translate('xpack.monitoring.kibana.listing.responseTimeColumnTitle', {
+ defaultMessage: 'Response Times'
+ }),
+ field: 'response_times.average',
+ render: (value, kibana) => (
+
+
+ { value && (formatNumber(value, 'int_commas') + ' ms avg') }
+
+
+ { formatNumber(kibana.response_times.max, 'int_commas') } ms max
+
+
+ )
+ }
+]);
uiRoutes.when('/kibana/instances', {
template,
@@ -21,13 +120,11 @@ uiRoutes.when('/kibana/instances', {
pageData: getPageData,
},
controllerAs: 'kibanas',
- controller: class KibanaInstancesList extends MonitoringViewBaseTableController {
+ controller: class KibanaInstancesList extends MonitoringViewBaseEuiTableController {
- constructor($injector, $scope, i18n) {
+ constructor($injector, $scope) {
super({
- title: i18n('xpack.monitoring.kibana.instances.routeTitle', {
- defaultMessage: 'Kibana Instances'
- }),
+ title: 'Kibana Instances',
storageKey: 'kibana.instances',
getPageData,
$scope,
@@ -39,6 +136,56 @@ uiRoutes.when('/kibana/instances', {
const globalState = $injector.get('globalState');
$scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid });
$scope.pageData = $route.current.locals.pageData;
+
+ const kbnUrl = $injector.get('kbnUrl');
+
+ const renderReact = () => {
+ const app = document.getElementById('monitoringKibanaInstancesApp');
+ if (!app) {
+ return;
+ }
+
+ const page = (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+
+ render(page, app);
+ };
+
+ $scope.$watch('data', () => renderReact());
+ renderReact();
}
}
});
diff --git a/x-pack/plugins/monitoring/public/views/kibana/overview/index.html b/x-pack/plugins/monitoring/public/views/kibana/overview/index.html
index 46f7174ffd67f..5b131e113dfa4 100644
--- a/x-pack/plugins/monitoring/public/views/kibana/overview/index.html
+++ b/x-pack/plugins/monitoring/public/views/kibana/overview/index.html
@@ -3,11 +3,5 @@
name="overview"
data-test-subj="kibanaOverviewPage"
>
-
-
+
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 e9e22d1510fb5..442822ad04836 100644
--- a/x-pack/plugins/monitoring/public/views/kibana/overview/index.js
+++ b/x-pack/plugins/monitoring/public/views/kibana/overview/index.js
@@ -7,12 +7,18 @@
/**
* 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';
import { routeInitProvider } from 'plugins/monitoring/lib/route_init';
import template from './index.html';
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';
function getPageData($injector) {
const $http = $injector.get('$http');
@@ -44,7 +50,7 @@ uiRoutes.when('/kibana', {
},
pageData: getPageData
},
- controller($injector, $scope, i18n) {
+ controller($injector, $scope) {
timefilter.enableTimeRangeSelector();
timefilter.enableAutoRefreshSelector();
@@ -54,11 +60,7 @@ uiRoutes.when('/kibana', {
$scope.pageData = $route.current.locals.pageData;
const title = $injector.get('title');
- const routeTitle = i18n('xpack.monitoring.kibana.overview.routeTitle', {
- defaultMessage: 'Kibana'
- });
-
- title($scope.cluster, routeTitle);
+ title($scope.cluster, 'Kibana');
const $executor = $injector.get('$executor');
$executor.register({
@@ -69,5 +71,43 @@ uiRoutes.when('/kibana', {
$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/nodes/index.html b/x-pack/plugins/monitoring/public/views/logstash/nodes/index.html
index 8385a12a92e83..6da00b1c771b8 100644
--- a/x-pack/plugins/monitoring/public/views/logstash/nodes/index.html
+++ b/x-pack/plugins/monitoring/public/views/logstash/nodes/index.html
@@ -1,19 +1,3 @@
-
-
-
-
-
-
+
diff --git a/x-pack/plugins/monitoring/public/views/logstash/nodes/index.js b/x-pack/plugins/monitoring/public/views/logstash/nodes/index.js
index 7f614ab22572e..c86320491c916 100644
--- a/x-pack/plugins/monitoring/public/views/logstash/nodes/index.js
+++ b/x-pack/plugins/monitoring/public/views/logstash/nodes/index.js
@@ -3,13 +3,16 @@
* 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 { render } from 'react-dom';
import { find } from 'lodash';
import uiRoutes from'ui/routes';
import { routeInitProvider } from 'plugins/monitoring/lib/route_init';
-import { MonitoringViewBaseTableController } from '../../';
+import { MonitoringViewBaseEuiTableController } from '../../';
import { getPageData } from './get_page_data';
import template from './index.html';
+import { I18nProvider } from '@kbn/i18n/react';
+import { Listing } from '../../../components/logstash/listing';
uiRoutes.when('/logstash/nodes', {
template,
@@ -21,13 +24,11 @@ uiRoutes.when('/logstash/nodes', {
pageData: getPageData
},
controllerAs: 'lsNodes',
- controller: class LsNodesList extends MonitoringViewBaseTableController {
+ controller: class LsNodesList extends MonitoringViewBaseEuiTableController {
- constructor($injector, $scope, i18n) {
+ constructor($injector, $scope) {
super({
- title: i18n('xpack.monitoring.logstash.nodes.routeTitle', {
- defaultMessage: 'Logstash - Nodes'
- }),
+ title: 'Logstash - Nodes',
storageKey: 'logstash.nodes',
getPageData,
$scope,
@@ -35,9 +36,34 @@ uiRoutes.when('/logstash/nodes', {
});
const $route = $injector.get('$route');
+ const kbnUrl = $injector.get('kbnUrl');
this.data = $route.current.locals.pageData;
const globalState = $injector.get('globalState');
$scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid });
+
+ const renderReact = (data) => {
+ if (!data) {
+ return;
+ }
+
+ render(
+
+
+ ,
+ document.getElementById('monitoringLogstashNodesApp')
+ );
+ };
+
+ $scope.$watch(() => this.data, data => {
+ renderReact(data);
+ });
}
}
});
diff --git a/x-pack/plugins/monitoring/public/views/logstash/overview/index.html b/x-pack/plugins/monitoring/public/views/logstash/overview/index.html
index 6c8f53ac5f96b..088aa35892bbe 100644
--- a/x-pack/plugins/monitoring/public/views/logstash/overview/index.html
+++ b/x-pack/plugins/monitoring/public/views/logstash/overview/index.html
@@ -1,10 +1,3 @@
-
-
+
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 19ad7fe50c0a8..749f0da9155e8 100644
--- a/x-pack/plugins/monitoring/public/views/logstash/overview/index.js
+++ b/x-pack/plugins/monitoring/public/views/logstash/overview/index.js
@@ -7,12 +7,16 @@
/**
* 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';
import template from './index.html';
import { timefilter } from 'ui/timefilter';
+import { I18nProvider } from '@kbn/i18n/react';
+import { Overview } from '../../../components/logstash/overview';
function getPageData($injector) {
const $http = $injector.get('$http');
@@ -44,7 +48,7 @@ uiRoutes.when('/logstash', {
},
pageData: getPageData
},
- controller($injector, $scope, i18n) {
+ controller($injector, $scope) {
timefilter.enableTimeRangeSelector();
timefilter.enableAutoRefreshSelector();
@@ -54,9 +58,7 @@ uiRoutes.when('/logstash', {
$scope.pageData = $route.current.locals.pageData;
const title = $injector.get('title');
- title($scope.cluster, i18n('xpack.monitoring.logstash.overview.routeTitle', {
- defaultMessage: 'Logstash'
- }));
+ title($scope.cluster, 'Logstash');
const $executor = $injector.get('$executor');
$executor.register({
@@ -65,5 +67,21 @@ uiRoutes.when('/logstash', {
});
$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/pipelines/index.html b/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.html
index 070c7b04cfb73..bef8a7a4737f3 100644
--- a/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.html
+++ b/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.html
@@ -3,11 +3,5 @@
name="pipelines"
data-test-subj="logstashPipelinesListing"
>
-
-
-
-
+
diff --git a/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js b/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js
index 27e68ae56976b..1e88cc678b904 100644
--- a/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js
+++ b/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js
@@ -4,8 +4,11 @@
* you may not use this file except in compliance with the Elastic License.
*/
+import React from 'react';
import { find } from 'lodash';
+import { render } from 'react-dom';
import uiRoutes from 'ui/routes';
+import moment from 'moment';
import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler';
import { routeInitProvider } from 'plugins/monitoring/lib/route_init';
import {
@@ -13,6 +16,9 @@ import {
} from 'plugins/monitoring/lib/logstash/pipelines';
import template from './index.html';
import { timefilter } from 'ui/timefilter';
+import { I18nProvider } from '@kbn/i18n/react';
+import { PipelineListing } from '../../../components/logstash/pipeline_listing/pipeline_listing';
+import { MonitoringViewBaseEuiTableController } from '../..';
/*
* Logstash Pipelines Listing page
@@ -40,16 +46,14 @@ const getPageData = ($injector) => {
});
};
-function makeUpgradeMessage(logstashVersions, i18n) {
+function makeUpgradeMessage(logstashVersions) {
if (!Array.isArray(logstashVersions)
|| (logstashVersions.length === 0)
|| logstashVersions.some(isPipelineMonitoringSupportedInVersion)) {
return null;
}
- return i18n('xpack.monitoring.logstash.pipelines.notAvalibleDescription', {
- defaultMessage: 'Pipeline monitoring is only available in Logstash version 6.0.0 or higher.'
- });
+ return 'Pipeline monitoring is only available in Logstash version 6.0.0 or higher.';
}
uiRoutes
@@ -62,30 +66,63 @@ 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 LogstashPipelinesList extends MonitoringViewBaseEuiTableController {
+ constructor($injector, $scope, i18n) {
+ super({
+ title: 'Logstash Pipelines',
+ storageKey: 'logstash.pipelines',
+ getPageData,
+ $scope,
+ $injector
+ });
- $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid });
- $scope.pageData = $route.current.locals.pageData;
+ const $route = $injector.get('$route');
+ const kbnUrl = $injector.get('kbnUrl');
+ this.data = $route.current.locals.pageData;
+ const globalState = $injector.get('globalState');
+ $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid });
- $scope.upgradeMessage = makeUpgradeMessage($scope.pageData.clusterStatus.versions, i18n);
- timefilter.enableTimeRangeSelector();
- timefilter.enableAutoRefreshSelector();
+ function onBrush(xaxis) {
+ timefilter.setTime({
+ from: moment(xaxis.from),
+ to: moment(xaxis.to),
+ mode: 'absolute'
+ });
+ }
- title($scope.cluster, i18n('xpack.monitoring.logstash.pipelines.routeTitle', {
- defaultMessage: 'Logstash Pipelines'
- }));
+ const renderReact = (pageData) => {
+ if (!pageData) {
+ return;
+ }
- $executor.register({
- execute: () => getPageData($injector),
- handleResponse: (response) => $scope.pageData = response
- });
+ const upgradeMessage = pageData
+ ? makeUpgradeMessage(pageData.clusterStatus.versions, i18n)
+ : null;
- $executor.start($scope);
+ render(
+
+
+ ,
+ document.getElementById('monitoringLogstashPipelinesApp')
+ );
+ };
- $scope.$on('$destroy', $executor.destroy);
+ $scope.$watch(() => this.data, pageData => {
+ renderReact(pageData);
+ });
+ }
}
});
diff --git a/x-pack/plugins/monitoring/server/lib/logstash/get_logstash_for_clusters.js b/x-pack/plugins/monitoring/server/lib/logstash/get_logstash_for_clusters.js
index fae1a9431135d..0bd527523ad7d 100644
--- a/x-pack/plugins/monitoring/server/lib/logstash/get_logstash_for_clusters.js
+++ b/x-pack/plugins/monitoring/server/lib/logstash/get_logstash_for_clusters.js
@@ -182,6 +182,7 @@ export function getLogstashForClusters(req, lsIndexPattern, clusters) {
const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('monitoring');
return callWithRequest(req, 'search', params)
.then(result => {
+
const aggregations = get(result, 'aggregations', {});
const logstashUuids = get(aggregations, 'logstash_uuids.buckets', []);
const logstashVersions = get(aggregations, 'logstash_versions.buckets', []);
diff --git a/x-pack/test/functional/apps/monitoring/beats/listing.js b/x-pack/test/functional/apps/monitoring/beats/listing.js
index 69c7a8da797c6..0194f1162511d 100644
--- a/x-pack/test/functional/apps/monitoring/beats/listing.js
+++ b/x-pack/test/functional/apps/monitoring/beats/listing.js
@@ -39,8 +39,8 @@ export default function ({ getService, getPageObjects }) {
duckbeat: 1,
sheepbeat: 1,
winlogbeat: 1,
- totalEvents: '699.9k',
- bytesSent: '427.9 MB',
+ totalEvents: 'Total Events:\n699.9k',
+ bytesSent: 'Bytes Sent:\n427.9 MB',
});
});
diff --git a/x-pack/test/functional/apps/monitoring/beats/overview.js b/x-pack/test/functional/apps/monitoring/beats/overview.js
index d0beebce8bf90..bfd4058939568 100644
--- a/x-pack/test/functional/apps/monitoring/beats/overview.js
+++ b/x-pack/test/functional/apps/monitoring/beats/overview.js
@@ -43,8 +43,8 @@ export default function ({ getService, getPageObjects }) {
duckbeat: 1,
sheepbeat: 1,
winlogbeat: 1,
- totalEvents: '699.9k',
- bytesSent: '427.9 MB',
+ totalEvents: 'Total Events:\n699.9k',
+ bytesSent: 'Bytes Sent:\n427.9 MB',
});
});
diff --git a/x-pack/test/functional/apps/monitoring/elasticsearch/indices.js b/x-pack/test/functional/apps/monitoring/elasticsearch/indices.js
index 3c9e4a1e4d022..58ec00cf6db1a 100644
--- a/x-pack/test/functional/apps/monitoring/elasticsearch/indices.js
+++ b/x-pack/test/functional/apps/monitoring/elasticsearch/indices.js
@@ -43,48 +43,8 @@ export default function ({ getService, getPageObjects }) {
});
});
- it('should have an indices table with correct rows with default sorting', async () => {
- const rows = await indicesList.getRows();
- expect(rows.length).to.be(20);
-
- const indicesAll = await indicesList.getIndicesAll();
-
- const tableData = [ /*eslint-disable max-len*/
- { name: 'many-0007_milycdknpycp', status: 'Health: red', documentCount: '1', dataSize: '3.6 KB', indexRate: '0 /s', searchRate: '0 /s', unassignedShards: '1' },
- { name: 'many-0009_reolfgzjjtvh', status: 'Health: red', documentCount: '1', dataSize: '3.6 KB', indexRate: '0 /s', searchRate: '0 /s', unassignedShards: '1' },
- { name: 'many-0011_xtkcmlwmxcov', status: 'Health: red', documentCount: '1', dataSize: '3.6 KB', indexRate: '0 /s', searchRate: '0 /s', unassignedShards: '1' },
- { name: 'many-0013_smjuwdkhpduv', status: 'Health: red', documentCount: '1', dataSize: '3.6 KB', indexRate: '0 /s', searchRate: '0 /s', unassignedShards: '1' },
- { name: 'many-0015_vwmrucgzvohb', status: 'Health: red', documentCount: '1', dataSize: '3.6 KB', indexRate: '0 /s', searchRate: '0 /s', unassignedShards: '1' },
- { name: 'many-0017_zpyxggzmytun', status: 'Health: red', documentCount: '1', dataSize: '3.6 KB', indexRate: '0 /s', searchRate: '0 /s', unassignedShards: '1' },
- { name: 'many-0019_slpgftmneikv', status: 'Health: red', documentCount: '1', dataSize: '3.6 KB', indexRate: '0 /s', searchRate: '0 /s', unassignedShards: '1' },
- { name: 'many-0021_xjtlceanhvup', status: 'Health: red', documentCount: '1', dataSize: '3.6 KB', indexRate: '0 /s', searchRate: '0 /s', unassignedShards: '1' },
- { name: 'many-0023_hkbvktonytxh', status: 'Health: red', documentCount: '1', dataSize: '3.6 KB', indexRate: '0 /s', searchRate: '0 /s', unassignedShards: '1' },
- { name: 'many-0025_xmvpnfeuqxtp', status: 'Health: red', documentCount: '1', dataSize: '3.6 KB', indexRate: '0 /s', searchRate: '0 /s', unassignedShards: '1' },
- { name: 'phone-home', status: 'Health: yellow', documentCount: '1', dataSize: '66.2 KB', indexRate: '0 /s', searchRate: '0 /s', unassignedShards: '5' },
- { name: 'many-0006_gkuqbjonkjmg', status: 'Health: green', documentCount: '1', dataSize: '3.7 KB', indexRate: '0 /s', searchRate: '4.08 /s', unassignedShards: '0' },
- { name: 'many-0008_amnscruqlsnu', status: 'Health: green', documentCount: '1', dataSize: '3.7 KB', indexRate: '0 /s', searchRate: '4.08 /s', unassignedShards: '0' },
- { name: 'many-0010_dgnlpqtstfvi', status: 'Health: green', documentCount: '1', dataSize: '3.7 KB', indexRate: '0 /s', searchRate: '1.95 /s', unassignedShards: '0' },
- { name: 'many-0012_jwomwdgfpisl', status: 'Health: green', documentCount: '1', dataSize: '3.7 KB', indexRate: '0 /s', searchRate: '1.95 /s', unassignedShards: '0' },
- { name: 'many-0014_zrukbrvuluby', status: 'Health: green', documentCount: '1', dataSize: '3.7 KB', indexRate: '0 /s', searchRate: '1.95 /s', unassignedShards: '0' },
- { name: 'many-0016_gyvtsyauoqqg', status: 'Health: green', documentCount: '1', dataSize: '3.7 KB', indexRate: '0 /s', searchRate: '1.95 /s', unassignedShards: '0' },
- { name: 'many-0018_ipugjcmuagih', status: 'Health: green', documentCount: '1', dataSize: '3.7 KB', indexRate: '0 /s', searchRate: '1.95 /s', unassignedShards: '0' },
- { name: 'many-0020_fqfovcnznbus', status: 'Health: green', documentCount: '1', dataSize: '3.7 KB', indexRate: '0 /s', searchRate: '1.95 /s', unassignedShards: '0' },
- { name: 'many-0022_dqbcjopzejlk', status: 'Health: green', documentCount: '1', dataSize: '3.7 KB', indexRate: '0 /s', searchRate: '1.95 /s', unassignedShards: '0' },
- ]; /*eslint-enable*/
-
- // check the all data in the table
- indicesAll.forEach((obj, index) => {
- expect(indicesAll[index].name).to.be(tableData[index].name);
- expect(indicesAll[index].status).to.be(tableData[index].status);
- expect(indicesAll[index].documentCount).to.be(tableData[index].documentCount);
- expect(indicesAll[index].dataSize).to.be(tableData[index].dataSize);
- expect(indicesAll[index].indexRate).to.be(tableData[index].indexRate);
- expect(indicesAll[index].searchRate).to.be(tableData[index].searchRate);
- expect(indicesAll[index].unassignedShards).to.be(tableData[index].unassignedShards);
- });
- });
-
- it('should show indices table with correct rows after sorting by Search Rate Desc', async () => {
+ // Revisit once https://github.com/elastic/eui/issues/1322 is resolved
+ it.skip('should show indices table with correct rows after sorting by Search Rate Desc', async () => {
await indicesList.clickSearchCol();
await indicesList.clickSearchCol();
diff --git a/x-pack/test/functional/apps/monitoring/elasticsearch/node_detail.js b/x-pack/test/functional/apps/monitoring/elasticsearch/node_detail.js
index a5ab5a2326673..1bf5dd28277a7 100644
--- a/x-pack/test/functional/apps/monitoring/elasticsearch/node_detail.js
+++ b/x-pack/test/functional/apps/monitoring/elasticsearch/node_detail.js
@@ -40,7 +40,7 @@ export default function ({ getService, getPageObjects }) {
await nodesList.clickRowByResolver('jUT5KdxfRbORSCWkb5zjmA');
expect(await nodeDetail.getSummary()).to.eql({
- transportAddress: '127.0.0.1:9300',
+ transportAddress: 'Transport Address:\n127.0.0.1:9300',
jvmHeap: 'JVM Heap:\n29%',
freeDiskSpace: 'Free Disk Space:\n173.9 GB',
documentCount: 'Documents:\n24.8k',
@@ -56,7 +56,7 @@ export default function ({ getService, getPageObjects }) {
await nodesList.clickRowByResolver('bwQWH-7IQY-mFPpfoaoFXQ');
expect(await nodeDetail.getSummary()).to.eql({
- transportAddress: '127.0.0.1:9302',
+ transportAddress: 'Transport Address:\n127.0.0.1:9302',
jvmHeap: 'JVM Heap:\n17%',
freeDiskSpace: 'Free Disk Space:\n173.9 GB',
documentCount: 'Documents:\n240',
@@ -91,7 +91,7 @@ export default function ({ getService, getPageObjects }) {
await nodesList.clickRowByResolver('1jxg5T33TWub-jJL4qP0Wg');
expect(await nodeDetail.getSummary()).to.eql({
- transportAddress: '127.0.0.1:9302',
+ transportAddress: 'Transport Address:\n127.0.0.1:9302',
jvmHeap: 'JVM Heap:\nN/A',
freeDiskSpace: 'Free Disk Space:\nN/A',
documentCount: 'Documents:\nN/A',
diff --git a/x-pack/test/functional/apps/monitoring/elasticsearch/nodes.js b/x-pack/test/functional/apps/monitoring/elasticsearch/nodes.js
index 1919bca3bffa0..c20050c9b4bc0 100644
--- a/x-pack/test/functional/apps/monitoring/elasticsearch/nodes.js
+++ b/x-pack/test/functional/apps/monitoring/elasticsearch/nodes.js
@@ -50,8 +50,24 @@ export default function ({ getService, getPageObjects }) {
const nodesAll = await nodesList.getNodesAll();
const tableData = [
- { name: 'whatever-01', status: 'Status: Online', cpu: '0%', load: '3.28', memory: '39%', disk: '173.9 GB', shards: '38', },
- { name: 'whatever-02', status: 'Status: Online', cpu: '2%', load: '3.28', memory: '25%', disk: '173.9 GB', shards: '38', },
+ {
+ name: 'whatever-01',
+ status: 'Status: Online',
+ cpu: '0% \n3% max\n0% min',
+ load: '3.28 \n3.71 max\n2.19 min',
+ memory: '39% \n52% max\n25% min',
+ disk: '173.9 GB \n173.9 GB max\n173.9 GB min',
+ shards: '38',
+ },
+ {
+ name: 'whatever-02',
+ status: 'Status: Online',
+ cpu: '2% \n3% max\n0% min',
+ load: '3.28 \n3.73 max\n2.29 min',
+ memory: '25% \n49% max\n25% min',
+ disk: '173.9 GB \n173.9 GB max\n173.9 GB min',
+ shards: '38',
+ },
{ name: 'whatever-03', status: 'Status: Offline' },
];
nodesAll.forEach((obj, node) => {
@@ -100,7 +116,7 @@ export default function ({ getService, getPageObjects }) {
await nodesList.clickCpuCol();
const nodesAll = await nodesList.getNodesAll();
- const tableData = [{ cpu: '0%' }, { cpu: '2%' }, { cpu: undefined }];
+ const tableData = [{ cpu: '0% \n3% max\n0% min' }, { cpu: '2% \n3% max\n0% min' }, { cpu: undefined }];
nodesAll.forEach((obj, node) => {
expect(nodesAll[node].cpu).to.be(tableData[node].cpu);
});
@@ -112,8 +128,8 @@ export default function ({ getService, getPageObjects }) {
const nodesAll = await nodesList.getNodesAll();
const tableData = [
- { load: '3.28' },
- { load: '3.28' },
+ { load: '3.28 \n3.71 max\n2.19 min' },
+ { load: '3.28 \n3.73 max\n2.29 min' },
{ load: undefined },
];
nodesAll.forEach((obj, node) => {
@@ -127,8 +143,8 @@ export default function ({ getService, getPageObjects }) {
const nodesAll = await nodesList.getNodesAll();
const tableData = [
- { memory: '39%' },
- { memory: '25%' },
+ { memory: '39% \n52% max\n25% min' },
+ { memory: '25% \n49% max\n25% min' },
{ memory: undefined },
];
nodesAll.forEach((obj, node) => {
@@ -142,8 +158,8 @@ export default function ({ getService, getPageObjects }) {
const nodesAll = await nodesList.getNodesAll();
const tableData = [
- { disk: '173.9 GB' },
- { disk: '173.9 GB' },
+ { disk: '173.9 GB \n173.9 GB max\n173.9 GB min' },
+ { disk: '173.9 GB \n173.9 GB max\n173.9 GB min' },
{ disk: undefined },
];
nodesAll.forEach((obj, node) => {
@@ -198,7 +214,8 @@ export default function ({ getService, getPageObjects }) {
});
});
- it('should filter for specific indices', async () => {
+ // Skip until https://github.com/elastic/eui/issues/1318 is implemented
+ it.skip('should filter for specific indices', async () => {
await nodesList.setFilter('01');
const rows = await nodesList.getRows();
expect(rows.length).to.be(1);
diff --git a/x-pack/test/functional/page_objects/monitoring_page.js b/x-pack/test/functional/page_objects/monitoring_page.js
index 12f148d255ebe..9eef3dff01bba 100644
--- a/x-pack/test/functional/page_objects/monitoring_page.js
+++ b/x-pack/test/functional/page_objects/monitoring_page.js
@@ -30,11 +30,25 @@ export function MonitoringPageProvider({ getPageObjects, getService }) {
});
}
+ async assertEuiTableNoData(subj) {
+ await retry.try(async () => {
+ if (await testSubjects.exists(subj)) {
+ throw new Error('Expected to find the no data message');
+ }
+ });
+ }
+
async tableGetRows(subj) {
const table = await testSubjects.find(subj);
return table.findAllByTagName('tr');
}
+ async tableGetRowsFromContainer(subj) {
+ const table = await testSubjects.find(subj);
+ const tbody = await table.findByTagName('tbody');
+ return tbody.findAllByTagName('tr');
+ }
+
async tableSetFilter(subj, text) {
return await testSubjects.setValue(subj, text);
}
diff --git a/x-pack/test/functional/services/monitoring/beats_listing.js b/x-pack/test/functional/services/monitoring/beats_listing.js
index 505c0238b5458..3e61f1ea29919 100644
--- a/x-pack/test/functional/services/monitoring/beats_listing.js
+++ b/x-pack/test/functional/services/monitoring/beats_listing.js
@@ -15,8 +15,7 @@ export function MonitoringBeatsListingProvider({ getService, getPageObjects }) {
const SUBJ_TABLE_CONTAINER = 'beatsTableContainer';
const SUBJ_SEARCH_BAR = `${SUBJ_TABLE_CONTAINER} monitoringTableToolBar`;
- const SUBJ_TABLE_BODY = 'beatsTableBody';
- const SUBJ_INDEX_LINK_PREFIX = `${SUBJ_TABLE_BODY} beatLink-`;
+ const SUBJ_INDEX_LINK_PREFIX = `${SUBJ_TABLE_CONTAINER} beatLink-`;
return new class BeatsListing {
diff --git a/x-pack/test/functional/services/monitoring/cluster_alerts.js b/x-pack/test/functional/services/monitoring/cluster_alerts.js
index a47af62bfbdcd..6b51380600f04 100644
--- a/x-pack/test/functional/services/monitoring/cluster_alerts.js
+++ b/x-pack/test/functional/services/monitoring/cluster_alerts.js
@@ -23,8 +23,7 @@ export function MonitoringClusterAlertsProvider({ getService, getPageObjects })
const SUBJ_OVERVIEW_ACTIONS = `${SUBJ_OVERVIEW_CLUSTER_ALERTS} alertAction`;
const SUBJ_OVERVIEW_VIEW_ALL = `${SUBJ_OVERVIEW_CLUSTER_ALERTS} viewAllAlerts`;
- const SUBJ_LISTING_PAGE = 'clusterAlertsListingPage';
- const SUBJ_TABLE_BODY = 'alertsTableBody';
+ const SUBJ_TABLE_BODY = 'alertsTableContainer';
const SUBJ_TABLE_ICONS = `${SUBJ_TABLE_BODY} alertIcon`;
const SUBJ_TABLE_TEXTS = `${SUBJ_TABLE_BODY} alertText`;
const SUBJ_TABLE_ACTIONS = `${SUBJ_TABLE_BODY} alertAction`;
@@ -91,12 +90,12 @@ export function MonitoringClusterAlertsProvider({ getService, getPageObjects })
*/
async isOnListingPage() {
- const pageId = await retry.try(() => testSubjects.find(SUBJ_LISTING_PAGE));
+ const pageId = await retry.try(() => testSubjects.find(SUBJ_TABLE_BODY));
return pageId !== null;
}
getTableAlerts() {
- return PageObjects.monitoring.tableGetRows(SUBJ_TABLE_BODY);
+ return PageObjects.monitoring.tableGetRowsFromContainer(SUBJ_TABLE_BODY);
}
async getTableAlertsAll() {
diff --git a/x-pack/test/functional/services/monitoring/cluster_list.js b/x-pack/test/functional/services/monitoring/cluster_list.js
index a4e29c60e4b10..a157cf97827bb 100644
--- a/x-pack/test/functional/services/monitoring/cluster_list.js
+++ b/x-pack/test/functional/services/monitoring/cluster_list.js
@@ -10,7 +10,6 @@ export function MonitoringClusterListProvider({ getService, getPageObjects }) {
const PageObjects = getPageObjects(['monitoring']);
const SUBJ_TABLE_CONTAINER = 'clusterTableContainer';
- const SUBJ_TABLE_BODY = 'clusterTableBody';
const SUBJ_TABLE_NO_DATA = `${SUBJ_TABLE_CONTAINER} monitoringTableNoData`;
const SUBJ_SEARCH_BAR = `${SUBJ_TABLE_CONTAINER} monitoringTableToolBar`;
@@ -27,11 +26,11 @@ export function MonitoringClusterListProvider({ getService, getPageObjects }) {
}
assertNoData() {
- return PageObjects.monitoring.assertTableNoData(SUBJ_TABLE_NO_DATA);
+ return PageObjects.monitoring.assertEuiTableNoData(SUBJ_TABLE_NO_DATA);
}
getRows() {
- return PageObjects.monitoring.tableGetRows(SUBJ_TABLE_BODY);
+ return PageObjects.monitoring.tableGetRowsFromContainer(SUBJ_TABLE_CONTAINER);
}
setFilter(text) {
diff --git a/x-pack/test/functional/services/monitoring/elasticsearch_indices.js b/x-pack/test/functional/services/monitoring/elasticsearch_indices.js
index a57c5883dd8e2..fa1995d61b6b0 100644
--- a/x-pack/test/functional/services/monitoring/elasticsearch_indices.js
+++ b/x-pack/test/functional/services/monitoring/elasticsearch_indices.js
@@ -17,18 +17,17 @@ export function MonitoringElasticsearchIndicesProvider({ getService, getPageObje
const SUBJ_TABLE_NO_DATA = `${SUBJ_TABLE_CONTAINER} monitoringTableNoData`;
const SUBJ_SEARCH_BAR = `${SUBJ_TABLE_CONTAINER} monitoringTableToolBar`;
- const SUBJ_TABLE_SORT_SEARCH_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell-searchRate`;
+ const SUBJ_TABLE_SORT_SEARCH_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell_search_rate_5`;
- const SUBJ_TABLE_BODY = 'elasticsearchIndicesTableBody';
- const SUBJ_INDICES_NAMES = `${SUBJ_TABLE_BODY} name`;
- const SUBJ_INDICES_STATUSES = `${SUBJ_TABLE_BODY} statusIcon`;
- const SUBJ_INDICES_DOCUMENT_COUNTS = `${SUBJ_TABLE_BODY} documentCount`;
- const SUBJ_INDICES_DATA_SIZES = `${SUBJ_TABLE_BODY} dataSize`;
- const SUBJ_INDICES_INDEX_RATES = `${SUBJ_TABLE_BODY} indexRate`;
- const SUBJ_INDICES_SEARCH_RATES = `${SUBJ_TABLE_BODY} searchRate`;
- const SUBJ_INDICES_UNASSIGNED_SHARD_COUNTS = `${SUBJ_TABLE_BODY} unassignedShards`;
+ const SUBJ_INDICES_NAMES = `${SUBJ_TABLE_CONTAINER} name`;
+ const SUBJ_INDICES_STATUSES = `${SUBJ_TABLE_CONTAINER} statusIcon`;
+ const SUBJ_INDICES_DOCUMENT_COUNTS = `${SUBJ_TABLE_CONTAINER} documentCount`;
+ const SUBJ_INDICES_DATA_SIZES = `${SUBJ_TABLE_CONTAINER} dataSize`;
+ const SUBJ_INDICES_INDEX_RATES = `${SUBJ_TABLE_CONTAINER} indexRate`;
+ const SUBJ_INDICES_SEARCH_RATES = `${SUBJ_TABLE_CONTAINER} searchRate`;
+ const SUBJ_INDICES_UNASSIGNED_SHARD_COUNTS = `${SUBJ_TABLE_CONTAINER} unassignedShards`;
- const SUBJ_INDEX_LINK_PREFIX = `${SUBJ_TABLE_BODY} indexLink-`;
+ const SUBJ_INDEX_LINK_PREFIX = `${SUBJ_TABLE_CONTAINER} indexLink-`;
return new class ElasticsearchIndices {
async isOnListing() {
@@ -43,11 +42,11 @@ export function MonitoringElasticsearchIndicesProvider({ getService, getPageObje
}
assertNoData() {
- return PageObjects.monitoring.assertTableNoData(SUBJ_TABLE_NO_DATA);
+ return PageObjects.monitoring.assertEuiTableNoData(SUBJ_TABLE_NO_DATA);
}
getRows() {
- return PageObjects.monitoring.tableGetRows(SUBJ_TABLE_BODY);
+ return PageObjects.monitoring.tableGetRowsFromContainer(SUBJ_TABLE_CONTAINER);
}
setFilter(text) {
diff --git a/x-pack/test/functional/services/monitoring/elasticsearch_nodes.js b/x-pack/test/functional/services/monitoring/elasticsearch_nodes.js
index 6b7f9cdcc2d24..47863a83077d9 100644
--- a/x-pack/test/functional/services/monitoring/elasticsearch_nodes.js
+++ b/x-pack/test/functional/services/monitoring/elasticsearch_nodes.js
@@ -17,15 +17,15 @@ export function MonitoringElasticsearchNodesProvider({ getService, getPageObject
const SUBJ_TABLE_NO_DATA = `${SUBJ_TABLE_CONTAINER} monitoringTableNoData`;
const SUBJ_SEARCH_BAR = `${SUBJ_TABLE_CONTAINER} monitoringTableToolBar`;
- const SUBJ_TABLE_SORT_NAME_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell-name`;
- const SUBJ_TABLE_SORT_STATUS_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell-status`;
- const SUBJ_TABLE_SORT_CPU_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell-cpuUsage`;
- const SUBJ_TABLE_SORT_LOAD_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell-loadAverage`;
- const SUBJ_TABLE_SORT_MEM_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell-jvmMemory`;
- const SUBJ_TABLE_SORT_DISK_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell-diskFreeSpace`;
- const SUBJ_TABLE_SORT_SHARDS_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell-shards`;
-
- const SUBJ_TABLE_BODY = 'elasticsearchNodesTableBody';
+ const SUBJ_TABLE_SORT_NAME_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell_name_0`;
+ const SUBJ_TABLE_SORT_STATUS_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell_isOnline_1`;
+ const SUBJ_TABLE_SORT_CPU_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell_node_cpu_utilization_2`;
+ const SUBJ_TABLE_SORT_LOAD_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell_node_load_average_3`;
+ const SUBJ_TABLE_SORT_MEM_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell_node_jvm_mem_percent_4`;
+ const SUBJ_TABLE_SORT_DISK_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell_node_free_space_5`;
+ const SUBJ_TABLE_SORT_SHARDS_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell_shardCount_6`;
+
+ const SUBJ_TABLE_BODY = 'elasticsearchNodesTableContainer';
const SUBJ_NODES_NAMES = `${SUBJ_TABLE_BODY} name`;
const SUBJ_NODES_STATUSES = `${SUBJ_TABLE_BODY} statusIcon`;
const SUBJ_NODES_CPUS = `${SUBJ_TABLE_BODY} cpuUsage`;
@@ -89,7 +89,7 @@ export function MonitoringElasticsearchNodesProvider({ getService, getPageObject
}
getRows() {
- return PageObjects.monitoring.tableGetRows(SUBJ_TABLE_BODY);
+ return PageObjects.monitoring.tableGetRowsFromContainer(SUBJ_TABLE_BODY);
}
setFilter(text) {
@@ -101,7 +101,7 @@ export function MonitoringElasticsearchNodesProvider({ getService, getPageObject
}
assertNoData() {
- return PageObjects.monitoring.assertTableNoData(SUBJ_TABLE_NO_DATA);
+ return PageObjects.monitoring.assertEuiTableNoData(SUBJ_TABLE_NO_DATA);
}
async getNodesAll() {
diff --git a/x-pack/test/functional/services/monitoring/kibana_instances.js b/x-pack/test/functional/services/monitoring/kibana_instances.js
index feffdadbbd9f9..1153227c86751 100644
--- a/x-pack/test/functional/services/monitoring/kibana_instances.js
+++ b/x-pack/test/functional/services/monitoring/kibana_instances.js
@@ -10,7 +10,7 @@ export function MonitoringKibanaInstancesProvider({ getService }) {
const SUBJ_INSTANCES_PAGE = 'kibanaInstancesPage';
- const SUBJ_TABLE_BODY = 'kibanaInstancesTableBody';
+ const SUBJ_TABLE_BODY = 'kibanaInstancesTableContainer';
const SUBJ_INDEX_LINK_PREFIX = `${SUBJ_TABLE_BODY} kibanaLink-`;
return new class KibanaInstances {
diff --git a/x-pack/test/functional/services/monitoring/logstash_pipelines.js b/x-pack/test/functional/services/monitoring/logstash_pipelines.js
index 2a24e2534acbd..be5251a748c92 100644
--- a/x-pack/test/functional/services/monitoring/logstash_pipelines.js
+++ b/x-pack/test/functional/services/monitoring/logstash_pipelines.js
@@ -13,16 +13,15 @@ export function MonitoringLogstashPipelinesProvider({ getService, getPageObjects
const SUBJ_LISTING_PAGE = 'logstashPipelinesListing';
- const SUBJ_TABLE_CONTAINER = 'logstashPipelinesTableContainer';
+ const SUBJ_TABLE_CONTAINER = 'monitoringLogstashPipelinesTableContainer';
const SUBJ_TABLE_NO_DATA = `${SUBJ_TABLE_CONTAINER} monitoringTableNoData`;
const SUBJ_SEARCH_BAR = `${SUBJ_TABLE_CONTAINER} monitoringTableToolBar`;
- const SUBJ_TABLE_SORT_EVENTS_EMITTED_RATE_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell-eventsEmittedRate`;
+ const SUBJ_TABLE_SORT_EVENTS_EMITTED_RATE_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell_latestThroughput_1`;
- const SUBJ_TABLE_BODY = 'logstashPipelinesTableBody';
- const SUBJ_PIPELINES_IDS = `${SUBJ_TABLE_BODY} id`;
- const SUBJ_PIPELINES_EVENTS_EMITTED_RATES = `${SUBJ_TABLE_BODY} eventsEmittedRate`;
- const SUBJ_PIPELINES_NODE_COUNTS = `${SUBJ_TABLE_BODY} nodeCount`;
+ const SUBJ_PIPELINES_IDS = `${SUBJ_TABLE_CONTAINER} id`;
+ const SUBJ_PIPELINES_EVENTS_EMITTED_RATES = `${SUBJ_TABLE_CONTAINER} eventsEmittedRate`;
+ const SUBJ_PIPELINES_NODE_COUNTS = `${SUBJ_TABLE_CONTAINER} nodeCount`;
return new class LogstashPipelines {
async isOnListing() {
@@ -31,7 +30,7 @@ export function MonitoringLogstashPipelinesProvider({ getService, getPageObjects
}
getRows() {
- return PageObjects.monitoring.tableGetRows(SUBJ_TABLE_BODY);
+ return PageObjects.monitoring.tableGetRowsFromContainer(SUBJ_TABLE_CONTAINER);
}
async getPipelinesAll() {
@@ -69,7 +68,7 @@ export function MonitoringLogstashPipelinesProvider({ getService, getPageObjects
}
assertNoData() {
- return PageObjects.monitoring.assertTableNoData(SUBJ_TABLE_NO_DATA);
+ return PageObjects.monitoring.assertEuiTableNoData(SUBJ_TABLE_NO_DATA);
}
};
}