Skip to content

Commit

Permalink
Convert layouts to use React compontents
Browse files Browse the repository at this point in the history
- This PR closes #48808
- Move all files under pages/metrics
  • Loading branch information
simianhacker committed Oct 28, 2019
1 parent b54c1a1 commit 64c250f
Show file tree
Hide file tree
Showing 45 changed files with 1,947 additions and 529 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,12 @@ export const container: InventoryModel = {
requiredModules: ['docker'],
layout,
metrics,
requiredMetrics: [
'containerOverview',
'containerCpuUsage',
'containerMemory',
'containerNetworkTraffic',
'containerDiskIOBytes',
'containerDiskIOOps',
],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
/*
* 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 { i18n } from '@kbn/i18n';
import { LayoutPropsWithTheme } from '../../../public/pages/metrics/types';
import { Section } from '../../../public/pages/metrics/components/section';
import { SubSection } from '../../../public/pages/metrics/components/sub_section';
import { GaugesSectionVis } from '../../../public/pages/metrics/components/gauges_section_vis';
import { ChartSectionVis } from '../../../public/pages/metrics/components/chart_section_vis';
import { withTheme } from '../../../../../common/eui_styled_components';

export const Layout = withTheme(({ metrics, theme }: LayoutPropsWithTheme) => (
<React.Fragment>
<Section
navLabel={i18n.translate('xpack.infra.metricDetailPage.containerMetricsLayout.layoutLabel', {
defaultMessage: 'Container',
})}
sectionLabel={i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.overviewSection.sectionLabel',
{
defaultMessage: 'Container Overview',
}
)}
metrics={metrics}
>
<SubSection id="containerOverview">
<GaugesSectionVis
seriesOverrides={{
cpu: {
name: i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.overviewSection.cpuUsageSeriesLabel',
{
defaultMessage: 'CPU Usage',
}
),
color: theme.eui.euiColorFullShade,
formatter: 'percent',
gaugeMax: 1,
},
memory: {
name: i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.overviewSection.memoryUsageSeriesLabel',
{
defaultMessage: 'Memory Usage',
}
),
color: theme.eui.euiColorFullShade,
formatter: 'percent',
gaugeMax: 1,
},
rx: {
name: i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.overviewSection.inboundRXSeriesLabel',
{
defaultMessage: 'Inbound (RX)',
}
),
color: theme.eui.euiColorFullShade,
formatter: 'bits',
formatterTemplate: '{{value}}/s',
},
tx: {
name: i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.overviewSection.outboundTXSeriesLabel',
{
defaultMessage: 'Outbound (TX)',
}
),
color: theme.eui.euiColorFullShade,
formatter: 'bits',
formatterTemplate: '{{value}}/s',
},
}}
/>
</SubSection>
<SubSection
id="containerCpuUsage"
label={i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.cpuUsageSection.sectionLabel',
{
defaultMessage: 'CPU Usage',
}
)}
>
<ChartSectionVis
stacked={true}
type="area"
formatter="percent"
seriesOverrides={{
cpu: { color: theme.eui.euiColorVis1 },
}}
/>
</SubSection>
<SubSection
id="containerMemory"
label={i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.memoryUsageSection.sectionLabel',
{
defaultMessage: 'Memory Usage',
}
)}
>
<ChartSectionVis
stacked={true}
type="area"
formatter="percent"
seriesOverrides={{
memory: { color: theme.eui.euiColorVis1 },
}}
/>
</SubSection>
<SubSection
id="containerNetworkTraffic"
label={i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.networkTrafficSection.sectionLabel',
{
defaultMessage: 'Network Traffic',
}
)}
>
<ChartSectionVis
formatter="bits"
formatterTemplate="{{value}}/s"
type="area"
seriesOverrides={{
rx: {
color: theme.eui.euiColorVis1,
name: i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.networkTrafficSection.networkRxRateSeriesLabel',
{
defaultMessage: 'in',
}
),
},
tx: {
color: theme.eui.euiColorVis2,
name: i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.networkTrafficSection.networkTxRateSeriesLabel',
{
defaultMessage: 'out',
}
),
},
}}
/>
</SubSection>
<SubSection
id="containerDiskIOOps"
label={i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.diskIoOpsSection.sectionLabel',
{
defaultMessage: 'Disk IO (Ops)',
}
)}
>
<ChartSectionVis
type="area"
formatterTemplate="{{value}}/s"
formatter="number"
seriesOverrides={{
read: {
color: theme.eui.euiColorVis1,
name: i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.diskIoOpsSection.readRateSeriesLabel',
{
defaultMessage: 'reads',
}
),
},
write: {
color: theme.eui.euiColorVis2,
name: i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.diskIoOpsSection.writeRateSeriesLabel',
{
defaultMessage: 'writes',
}
),
},
}}
/>
</SubSection>
<SubSection
id="containerDiskIOBytes"
label={i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.diskIoBytesSection.sectionLabel',
{
defaultMessage: 'Disk IO (Bytes)',
}
)}
>
<ChartSectionVis
type="area"
formatter="bytes"
formatterTemplate="{{value}}/s"
seriesOverrides={{
read: {
color: theme.eui.euiColorVis1,
name: i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.diskIoBytesSection.readRateSeriesLabel',
{
defaultMessage: 'reads',
}
),
},
write: {
color: theme.eui.euiColorVis2,
name: i18n.translate(
'xpack.infra.metricDetailPage.containerMetricsLayout.diskIoBytesSection.writeRateSeriesLabel',
{
defaultMessage: 'writes',
}
),
},
}}
/>
</SubSection>
</Section>
</React.Fragment>
));
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* 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, { FunctionComponent, useEffect, useMemo } from 'react';
import { EuiSideNav, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { InfraMetricData } from '../../../public/graphql/types';
import { Section } from '../../../public/pages/metrics/components/section';
import { SubSection } from '../../../public/pages/metrics/components/sub_section';
import { NavItem, SideNavContext } from '../../../public/pages/metrics/lib/side_nav_context';

interface VisSectionProps {
metric?: InfraMetricData;
}

const VisSection: FunctionComponent<VisSectionProps> = ({ metric }) => {
if (metric) {
return (
<div
style={{
display: 'flex',
width: '100%',
height: 250,
backgroundColor: '#CCC',
alignItems: 'center',
}}
>
<div style={{ textAlign: 'center', flex: '1 0 auto' }}>VISUALIZATION GOES HERE</div>
</div>
);
}
return <div>Gauges without Metric (you should never see this)</div>;
};

interface WithMetricsDataProps {
source: string;
ids: string[];
children: (props: LayoutProps) => React.ReactElement;
}

const WithMetricsData = ({ ids, children }: WithMetricsDataProps) => {
if (!children) {
return null;
}

// eslint-disable-next-line no-console
useEffect(() => console.log('Fetching', ids), [ids]);

const metrics = useMemo(() => {
return ids.map(m => ({ id: m, series: [] }));
}, [ids]) as InfraMetricData[];

return children({ metrics });
};

interface LayoutProps {
metrics: InfraMetricData[];
}

interface MetricsLayout {
requiredMetrics: string[];
Layout: FunctionComponent<LayoutProps>;
}

const Aws: MetricsLayout = {
requiredMetrics: ['awsOverview', 'awsCpuUsage'],
Layout: ({ metrics }) => (
<Section navLabel="AWS" sectionLabel="AWS Overview" metrics={metrics}>
<SubSection id="awsOverview">
<VisSection />
</SubSection>
<SubSection id="awsCpuUtilization" label="CPU Usage">
<VisSection />
</SubSection>
</Section>
),
};
const Nginx: MetricsLayout = {
requiredMetrics: ['nginxOverview'],
Layout: ({ metrics }) => (
<Section sectionLabel="Nginx Overview" navLabel="Nginx" metrics={metrics}>
<SubSection id="nginxHits">
<VisSection />
</SubSection>
</Section>
),
};

export const Host: MetricsLayout = {
requiredMetrics: [
'hostSystemOverview',
'hostSystemCPU',
...Aws.requiredMetrics,
...Nginx.requiredMetrics,
],
Layout: ({ metrics }) => (
<React.Fragment>
<Section navLabel="Host" sectionLabel="Host Overview" metrics={metrics}>
<SubSection id="hostSystemOverview">
<VisSection />
</SubSection>
<SubSection id="hostCpuUsage" label="CPU Usage">
<VisSection />
</SubSection>
</Section>
<Aws.Layout metrics={metrics} />
<Nginx.Layout metrics={metrics} />
</React.Fragment>
),
};

export const DetailPage: FunctionComponent = () => {
const [sideNav, setSideNav] = React.useState<NavItem[]>([]);

const addNavItem = React.useCallback(
(item: NavItem) => {
if (!sideNav.some(n => n.id === item.id)) {
setSideNav([item, ...sideNav]);
}
},
[sideNav]
);

return (
<div style={{ padding: 16, width: '100%' }}>
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<EuiSideNav items={sideNav} />
</EuiFlexItem>
<EuiFlexItem>
<SideNavContext.Provider value={{ items: sideNav, addNavItem }}>
<WithMetricsData source="default" ids={Aws.requiredMetrics}>
{({ metrics }) => <Aws.Layout metrics={metrics} />}
</WithMetricsData>
</SideNavContext.Provider>
</EuiFlexItem>
</EuiFlexGroup>
</div>
);
};
Loading

0 comments on commit 64c250f

Please sign in to comment.