mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* Monitoring Angular directives to use React components (#19183) * remove some webpack aliases for jest * remove status icon angular directive * fix some component import problems * prop name fix
This commit is contained in:
parent
ed354d6682
commit
d6e6f6ff96
17 changed files with 301 additions and 135 deletions
|
@ -5,8 +5,8 @@
|
|||
*/
|
||||
|
||||
import React, { Fragment } from 'react';
|
||||
import { MonitoringTimeseriesContainer } from 'plugins/monitoring/components';
|
||||
import { formatMetric } from 'plugins/monitoring/lib/format_number';
|
||||
import { MonitoringTimeseriesContainer } from '../../chart';
|
||||
import { formatMetric } from '../../../lib/format_number';
|
||||
|
||||
function renderTransportAddress(summary) {
|
||||
let output = null;
|
||||
|
|
|
@ -9,7 +9,7 @@ import { LatestActive } from './latest_active';
|
|||
import { LatestVersions } from './latest_versions';
|
||||
import { LatestTypes } from './latest_types';
|
||||
import { Stats } from '../';
|
||||
import { MonitoringTimeseriesContainer } from 'plugins/monitoring/components';
|
||||
import { MonitoringTimeseriesContainer } from '../../chart';
|
||||
import { EuiCallOut } from '@elastic/eui';
|
||||
|
||||
function renderLatestActive(latestActive, latestTypes, latestVersions) {
|
||||
|
|
|
@ -22,7 +22,7 @@ export function ClusterStatus({ stats }) {
|
|||
status
|
||||
} = stats;
|
||||
|
||||
const children = [
|
||||
const metrics = [
|
||||
{
|
||||
label: 'Nodes',
|
||||
value: nodesCount,
|
||||
|
@ -68,7 +68,7 @@ export function ClusterStatus({ stats }) {
|
|||
|
||||
return (
|
||||
<SummaryStatus
|
||||
children={children}
|
||||
metrics={metrics}
|
||||
status={status}
|
||||
IconComponent={IconComponent}
|
||||
data-test-subj="elasticsearchClusterStatus"
|
||||
|
|
|
@ -18,7 +18,7 @@ export function IndexDetailStatus({ stats }) {
|
|||
status
|
||||
} = stats;
|
||||
|
||||
const children = [
|
||||
const metrics = [
|
||||
{
|
||||
label: 'Total',
|
||||
value: formatMetric(dataSize.total, '0.0 b'),
|
||||
|
@ -54,7 +54,7 @@ export function IndexDetailStatus({ stats }) {
|
|||
|
||||
return (
|
||||
<SummaryStatus
|
||||
children={children}
|
||||
metrics={metrics}
|
||||
status={status}
|
||||
IconComponent={IconComponent}
|
||||
data-test-subj="elasticsearchIndexDetailStatus"
|
||||
|
|
|
@ -11,7 +11,7 @@ import { LARGE_FLOAT, LARGE_BYTES, LARGE_ABBREVIATED } from '../../../../common/
|
|||
import { formatMetric } from '../../../lib/format_number';
|
||||
import { ElasticsearchStatusIcon } from '../status_icon';
|
||||
import { ClusterStatus } from '../cluster_status';
|
||||
import { MonitoringTable } from '../../';
|
||||
import { MonitoringTable } from '../../table';
|
||||
import { EuiLink } from '@elastic/eui';
|
||||
import { KuiTableRowCell, KuiTableRow } from '@kbn/ui-framework/components';
|
||||
import { SystemIndicesCheckbox } from './system_indices_checkbox';
|
||||
|
|
|
@ -23,7 +23,7 @@ export function NodeDetailStatus({ stats }) {
|
|||
isOnline,
|
||||
} = stats;
|
||||
|
||||
const children = [
|
||||
const metrics = [
|
||||
{
|
||||
value: transportAddress,
|
||||
dataTestSubj: 'transportAddress'
|
||||
|
@ -73,7 +73,7 @@ export function NodeDetailStatus({ stats }) {
|
|||
|
||||
return (
|
||||
<SummaryStatus
|
||||
children={children}
|
||||
metrics={metrics}
|
||||
status={status}
|
||||
isOnline={isOnline}
|
||||
IconComponent={IconComponent}
|
||||
|
|
|
@ -10,7 +10,7 @@ import { SORT_ASCENDING } from '../../../../common/constants';
|
|||
import { NodeStatusIcon } from '../node';
|
||||
import { extractIp } from '../../../lib/extract_ip'; // TODO this is only used for elasticsearch nodes summary / node detail, so it should be moved to components/elasticsearch/nodes/lib
|
||||
import { ClusterStatus } from '../cluster_status';
|
||||
import { MonitoringTable } from '../../';
|
||||
import { MonitoringTable } from '../../table';
|
||||
import { MetricCell, OfflineCell } from './cells';
|
||||
import { EuiLink, EuiToolTip } from '@elastic/eui';
|
||||
import { KuiTableRowCell, KuiTableRow } from '@kbn/ui-framework/components';
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
import React, { Fragment } from 'react';
|
||||
import { ClusterStatus } from '../cluster_status';
|
||||
import { ShardActivity } from '../shard_activity';
|
||||
import { MonitoringTimeseriesContainer } from 'plugins/monitoring/components';
|
||||
import { MonitoringTimeseriesContainer } from '../../chart';
|
||||
|
||||
export function ElasticsearchOverview({
|
||||
clusterStatus,
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
export { MonitoringTimeseriesContainer } from './chart';
|
||||
export { MonitoringTable } from './table';
|
||||
export { Tooltip } from './tooltip';
|
||||
|
||||
/*
|
||||
* This file should only export page-level components for view controllers to
|
||||
* mount React to the DOM
|
||||
*/
|
||||
export { NoData } from './no_data';
|
||||
export { License } from './license';
|
||||
export { StatusIcon } from './status_icon';
|
||||
export { SummaryStatus } from './summary_status'; // TODO this line can be removed, component is only used by other components
|
||||
export { PageLoading } from './page_loading';
|
||||
export {
|
||||
ElasticsearchOverview,
|
||||
|
|
|
@ -20,7 +20,7 @@ export function ClusterStatus({ stats }) {
|
|||
status,
|
||||
} = stats;
|
||||
|
||||
const children = [
|
||||
const metrics = [
|
||||
{
|
||||
label: 'Instances',
|
||||
value: instances,
|
||||
|
@ -56,7 +56,7 @@ export function ClusterStatus({ stats }) {
|
|||
|
||||
return (
|
||||
<SummaryStatus
|
||||
children={children}
|
||||
metrics={metrics}
|
||||
status={status}
|
||||
IconComponent={IconComponent}
|
||||
data-test-subj="kibanaClusterStatus"
|
||||
|
|
|
@ -18,7 +18,7 @@ export function DetailStatus({ stats }) {
|
|||
status
|
||||
} = stats;
|
||||
|
||||
const children = [
|
||||
const metrics = [
|
||||
{
|
||||
value: transportAddress,
|
||||
dataTestSubj: 'transportAddress'
|
||||
|
@ -48,7 +48,7 @@ export function DetailStatus({ stats }) {
|
|||
|
||||
return (
|
||||
<SummaryStatus
|
||||
children={children}
|
||||
metrics={metrics}
|
||||
status={status}
|
||||
IconComponent={IconComponent}
|
||||
data-test-subj="kibanaDetailStatus"
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`Summary Status Component should allow label to be optional 1`] = `
|
||||
<div
|
||||
class="monitoring-summary-status"
|
||||
role="status"
|
||||
>
|
||||
<div
|
||||
class="monitoring-summary-status__content"
|
||||
>
|
||||
<div
|
||||
class="euiFlexGroup euiFlexGroup--gutterExtraSmall euiFlexGroup--alignItemsCenter euiFlexGroup--directionRow euiFlexGroup--responsive"
|
||||
>
|
||||
<div
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero monitoring-summary-status__eui-content"
|
||||
data-test-subj="transportAddress"
|
||||
>
|
||||
<strong>
|
||||
127.0.0.1:9300
|
||||
</strong>
|
||||
</div>
|
||||
<div
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero monitoring-summary-status__eui-content"
|
||||
data-test-subj="documentCount"
|
||||
>
|
||||
Documents:
|
||||
<strong>
|
||||
24.8k
|
||||
</strong>
|
||||
</div>
|
||||
<div
|
||||
class="euiFlexItem monitoring-summary-status__eui-content"
|
||||
>
|
||||
<div
|
||||
class="monitoring-summary-status__status-indicator"
|
||||
>
|
||||
Status:
|
||||
<span
|
||||
class="kuiStatusText"
|
||||
>
|
||||
<img
|
||||
alt="Status: yellow"
|
||||
data-test-subj="statusIcon"
|
||||
src="../plugins/monitoring/icons/health-yellow.svg"
|
||||
/>
|
||||
</span>
|
||||
Yellow
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Summary Status Component should allow status to be optional 1`] = `
|
||||
<div
|
||||
class="monitoring-summary-status"
|
||||
role="status"
|
||||
>
|
||||
<div
|
||||
class="monitoring-summary-status__content"
|
||||
>
|
||||
<div
|
||||
class="euiFlexGroup euiFlexGroup--gutterExtraSmall euiFlexGroup--alignItemsCenter euiFlexGroup--directionRow euiFlexGroup--responsive"
|
||||
>
|
||||
<div
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero monitoring-summary-status__eui-content"
|
||||
data-test-subj="freeDiskSpace"
|
||||
>
|
||||
Free Disk Space:
|
||||
<strong>
|
||||
173.9 GB
|
||||
</strong>
|
||||
</div>
|
||||
<div
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero monitoring-summary-status__eui-content"
|
||||
data-test-subj="documentCount"
|
||||
>
|
||||
Documents:
|
||||
<strong>
|
||||
24.8k
|
||||
</strong>
|
||||
</div>
|
||||
<div
|
||||
class="euiFlexItem monitoring-summary-status__eui-content"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`Summary Status Component should render metrics in a summary bar 1`] = `
|
||||
<div
|
||||
class="monitoring-summary-status"
|
||||
role="status"
|
||||
>
|
||||
<div
|
||||
class="monitoring-summary-status__content"
|
||||
>
|
||||
<div
|
||||
class="euiFlexGroup euiFlexGroup--gutterExtraSmall euiFlexGroup--alignItemsCenter euiFlexGroup--directionRow euiFlexGroup--responsive"
|
||||
>
|
||||
<div
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero monitoring-summary-status__eui-content"
|
||||
data-test-subj="freeDiskSpace"
|
||||
>
|
||||
Free Disk Space:
|
||||
<strong>
|
||||
173.9 GB
|
||||
</strong>
|
||||
</div>
|
||||
<div
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero monitoring-summary-status__eui-content"
|
||||
data-test-subj="documentCount"
|
||||
>
|
||||
Documents:
|
||||
<strong>
|
||||
24.8k
|
||||
</strong>
|
||||
</div>
|
||||
<div
|
||||
class="euiFlexItem monitoring-summary-status__eui-content"
|
||||
>
|
||||
<div
|
||||
class="monitoring-summary-status__status-indicator"
|
||||
>
|
||||
Status:
|
||||
<span
|
||||
class="kuiStatusText"
|
||||
>
|
||||
<img
|
||||
alt="Status: green"
|
||||
data-test-subj="statusIcon"
|
||||
src="../plugins/monitoring/icons/health-green.svg"
|
||||
/>
|
||||
</span>
|
||||
Green
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
|
@ -4,59 +4,4 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React, { Fragment } from 'react';
|
||||
import { isEmpty, capitalize } from 'lodash';
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { StatusIcon } from '../';
|
||||
|
||||
const wrapChild = ({ label, value, dataTestSubj }, index) => (
|
||||
<EuiFlexItem
|
||||
key={`summary-status-item-${index}`}
|
||||
grow={false}
|
||||
className="monitoring-summary-status__eui-content"
|
||||
data-test-subj={dataTestSubj}
|
||||
>
|
||||
{label ? label + ': ' : null}
|
||||
<strong>{value}</strong>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
|
||||
const DefaultIconComponent = ({ status }) => (
|
||||
<Fragment>
|
||||
Status: {(
|
||||
<StatusIcon type={status.toUpperCase()} label={`Status: ${status}`} />
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
const StatusIndicator = ({ status, isOnline, IconComponent }) => {
|
||||
if (isEmpty(status)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="monitoring-summary-status__status-indicator">
|
||||
<IconComponent status={status} isOnline={isOnline} />{' '}
|
||||
{capitalize(status)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export function SummaryStatus({ children, status, isOnline, IconComponent = DefaultIconComponent, ...props }) {
|
||||
return (
|
||||
<div className="monitoring-summary-status" role="status">
|
||||
<div className="monitoring-summary-status__content" {...props}>
|
||||
<EuiFlexGroup gutterSize="xs" alignItems="center">
|
||||
{children.map(wrapChild)}
|
||||
|
||||
<EuiFlexItem
|
||||
grow={true}
|
||||
className="monitoring-summary-status__eui-content"
|
||||
>
|
||||
<StatusIndicator status={status} IconComponent={IconComponent} isOnline={isOnline} />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export { SummaryStatus } from './summary_status';
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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, { Fragment } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { isEmpty, capitalize } from 'lodash';
|
||||
import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
|
||||
import { StatusIcon } from '../status_icon';
|
||||
|
||||
const wrapChild = ({ label, value, dataTestSubj }, index) => (
|
||||
<EuiFlexItem
|
||||
key={`summary-status-item-${index}`}
|
||||
grow={false}
|
||||
className="monitoring-summary-status__eui-content"
|
||||
data-test-subj={dataTestSubj}
|
||||
>
|
||||
{label ? label + ': ' : null}
|
||||
<strong>{value}</strong>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
|
||||
const DefaultIconComponent = ({ status }) => (
|
||||
<Fragment>
|
||||
Status: {(
|
||||
<StatusIcon type={status.toUpperCase()} label={`Status: ${status}`} />
|
||||
)}
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
const StatusIndicator = ({ status, isOnline, IconComponent }) => {
|
||||
if (isEmpty(status)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="monitoring-summary-status__status-indicator">
|
||||
<IconComponent status={status} isOnline={isOnline} />{' '}
|
||||
{capitalize(status)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export function SummaryStatus({ metrics, status, isOnline, IconComponent = DefaultIconComponent, ...props }) {
|
||||
return (
|
||||
<div className="monitoring-summary-status" role="status">
|
||||
<div className="monitoring-summary-status__content" {...props}>
|
||||
<EuiFlexGroup gutterSize="xs" alignItems="center">
|
||||
{metrics.map(wrapChild)}
|
||||
|
||||
<EuiFlexItem
|
||||
grow={true}
|
||||
className="monitoring-summary-status__eui-content"
|
||||
>
|
||||
<StatusIndicator status={status} IconComponent={IconComponent} isOnline={isOnline} />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
SummaryStatus.propTypes = {
|
||||
metrics: PropTypes.array.isRequired
|
||||
};
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* 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 { render } from 'enzyme';
|
||||
import { SummaryStatus } from './summary_status';
|
||||
|
||||
describe('Summary Status Component', () => {
|
||||
it('should render metrics in a summary bar', () => {
|
||||
const props = {
|
||||
metrics: [
|
||||
{
|
||||
label: 'Free Disk Space',
|
||||
value: '173.9 GB',
|
||||
dataTestSubj: 'freeDiskSpace'
|
||||
},
|
||||
{
|
||||
label: 'Documents',
|
||||
value: '24.8k',
|
||||
dataTestSubj: 'documentCount'
|
||||
},
|
||||
],
|
||||
status: 'green'
|
||||
};
|
||||
|
||||
expect(render(<SummaryStatus {...props} />)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should allow label to be optional', () => {
|
||||
const props = {
|
||||
metrics: [
|
||||
{
|
||||
value: '127.0.0.1:9300',
|
||||
dataTestSubj: 'transportAddress'
|
||||
},
|
||||
{
|
||||
label: 'Documents',
|
||||
value: '24.8k',
|
||||
dataTestSubj: 'documentCount'
|
||||
},
|
||||
],
|
||||
status: 'yellow'
|
||||
};
|
||||
|
||||
expect(render(<SummaryStatus {...props} />)).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should allow status to be optional', () => {
|
||||
const props = {
|
||||
metrics: [
|
||||
{
|
||||
label: 'Free Disk Space',
|
||||
value: '173.9 GB',
|
||||
dataTestSubj: 'freeDiskSpace'
|
||||
},
|
||||
{
|
||||
label: 'Documents',
|
||||
value: '24.8k',
|
||||
dataTestSubj: 'documentCount'
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
expect(render(<SummaryStatus {...props} />)).toMatchSnapshot();
|
||||
});
|
||||
});
|
|
@ -8,7 +8,6 @@ import './main';
|
|||
import './chart';
|
||||
import './sparkline';
|
||||
import './alerts';
|
||||
import './status_icon';
|
||||
import './cluster/overview';
|
||||
import './cluster/listing';
|
||||
import './elasticsearch/cluster_status';
|
||||
|
|
|
@ -1,57 +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 { uiModules } from 'ui/modules';
|
||||
import { ElasticsearchStatusIcon } from 'plugins/monitoring/components/elasticsearch/status_icon';
|
||||
import { NodeStatusIcon } from 'plugins/monitoring/components/elasticsearch/node/status_icon';
|
||||
import { KibanaStatusIcon } from 'plugins/monitoring/components/kibana/status_icon';
|
||||
|
||||
const uiModule = uiModules.get('monitoring/directives', []);
|
||||
|
||||
function linkStatusIconComponent(scope, $el, StatusIconComponent) {
|
||||
// The watch callback always runs the first time connecting the data to the directive
|
||||
// The first time callback runs, unmountComponentAtNode does nothing
|
||||
scope.$watch('status', (status) => {
|
||||
ReactDOM.unmountComponentAtNode($el[0]);
|
||||
ReactDOM.render((
|
||||
<div title={scope.title}>
|
||||
<StatusIconComponent status={status} />
|
||||
</div>
|
||||
), $el[0]);
|
||||
});
|
||||
}
|
||||
|
||||
uiModule.directive('monitoringKibanaStatusIcon', function () {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: { status: '=' },
|
||||
link(scope, $el) {
|
||||
linkStatusIconComponent(scope, $el, KibanaStatusIcon);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
uiModule.directive('monitoringElasticsearchStatusIcon', function () {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: { status: '=' },
|
||||
link(scope, $el) {
|
||||
linkStatusIconComponent(scope, $el, ElasticsearchStatusIcon);
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
uiModule.directive('monitoringElasticsearchNodeStatusIcon', function () {
|
||||
return {
|
||||
restrict: 'E',
|
||||
scope: { status: '=' },
|
||||
link(scope, $el) {
|
||||
linkStatusIconComponent(scope, $el, NodeStatusIcon);
|
||||
}
|
||||
};
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue