= ({
+ children,
+ metrics,
+ navLabel,
+ sectionLabel,
+ onChangeRangeTime,
+ isLiveStreaming,
+ stopLiveStreaming,
+}) => {
+ const { addNavItem } = useContext(SideNavContext);
+ const subNavItems: SubNavItem[] = [];
+
+ const childrenWithProps = useMemo(
+ () =>
+ Children.map(children, child => {
+ if (isValidElement(child)) {
+ const metric = (metrics && metrics.find(m => m.id === child.props.id)) || null;
+ if (metric) {
+ subNavItems.push({
+ id: child.props.id,
+ name: child.props.label,
+ onClick: () => {
+ const el = document.getElementById(child.props.id);
+ if (el) {
+ el.scrollIntoView();
+ }
+ },
+ });
+ }
+ return cloneElement(child, {
+ metrics,
+ onChangeRangeTime,
+ isLiveStreaming,
+ stopLiveStreaming,
+ });
+ }
+ return null;
+ }),
+ [children, metrics, onChangeRangeTime, isLiveStreaming, stopLiveStreaming]
+ );
+
+ if (metrics && subNavItems.length) {
+ addNavItem({ id: navLabel, name: navLabel, items: subNavItems });
+ return (
+
+
+ {sectionLabel}
+
+ {childrenWithProps}
+
+ );
+ }
+
+ return null;
+};
diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/sections/series_chart.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/series_chart.tsx
similarity index 100%
rename from x-pack/legacy/plugins/infra/public/components/metrics/sections/series_chart.tsx
rename to x-pack/legacy/plugins/infra/public/pages/metrics/components/series_chart.tsx
diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/components/side_nav.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/side_nav.tsx
new file mode 100644
index 0000000000000..8e922818222b4
--- /dev/null
+++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/side_nav.tsx
@@ -0,0 +1,52 @@
+/*
+ * 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 { EuiHideFor, EuiPageSideBar, EuiShowFor, EuiSideNav } from '@elastic/eui';
+import React, { useState, useCallback } from 'react';
+import euiStyled from '../../../../../../common/eui_styled_components';
+import { NavItem } from '../lib/side_nav_context';
+
+interface Props {
+ loading: boolean;
+ name: string;
+ items: NavItem[];
+}
+
+export const MetricsSideNav = ({ loading, name, items }: Props) => {
+ const [isOpenOnMobile, setMobileState] = useState(false);
+
+ const toggle = useCallback(() => {
+ setMobileState(!isOpenOnMobile);
+ }, [isOpenOnMobile]);
+
+ const content = loading ? null : ;
+ const mobileContent = loading ? null : (
+
+ );
+ return (
+
+
+ {content}
+
+ {mobileContent}
+
+ );
+};
+
+const SideNavContainer = euiStyled.div`
+ position: fixed;
+ z-index: 1;
+ height: 88vh;
+ padding-left: 16px;
+ margin-left: -16px;
+ overflow-y: auto;
+ overflow-x: hidden;
+`;
diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/components/sub_section.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/sub_section.tsx
new file mode 100644
index 0000000000000..f3db3b1670199
--- /dev/null
+++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/sub_section.tsx
@@ -0,0 +1,59 @@
+/*
+ * 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, { isValidElement, cloneElement, FunctionComponent, Children, useMemo } from 'react';
+import { EuiTitle } from '@elastic/eui';
+import { InventoryMetric } from '../../../../common/inventory_models/types';
+import { LayoutProps } from '../types';
+
+type SubSectionProps = LayoutProps & {
+ id: InventoryMetric;
+ label?: string;
+};
+
+export const SubSection: FunctionComponent = ({
+ id,
+ label,
+ children,
+ metrics,
+ onChangeRangeTime,
+ isLiveStreaming,
+ stopLiveStreaming,
+}) => {
+ if (!children || !metrics) {
+ return null;
+ }
+ const metric = metrics.find(m => m.id === id);
+ if (!metric) {
+ return null;
+ }
+ const childrenWithProps = useMemo(
+ () =>
+ Children.map(children, child => {
+ if (isValidElement(child)) {
+ return cloneElement(child, {
+ metric,
+ id,
+ onChangeRangeTime,
+ isLiveStreaming,
+ stopLiveStreaming,
+ });
+ }
+ return null;
+ }),
+ [children, metric, id, onChangeRangeTime, isLiveStreaming, stopLiveStreaming]
+ );
+ return (
+
+ {label ? (
+
+ {label}
+
+ ) : null}
+ {childrenWithProps}
+
+ );
+};
diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/time_controls.test.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.test.tsx
similarity index 95%
rename from x-pack/legacy/plugins/infra/public/components/metrics/time_controls.test.tsx
rename to x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.test.tsx
index 61872f52615a0..624a2bb4a6f0f 100644
--- a/x-pack/legacy/plugins/infra/public/components/metrics/time_controls.test.tsx
+++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.test.tsx
@@ -7,7 +7,7 @@
import React from 'react';
import { MetricsTimeControls } from './time_controls';
import { mount } from 'enzyme';
-import { MetricsTimeInput } from '../../containers/metrics/with_metrics_time';
+import { MetricsTimeInput } from '../containers/with_metrics_time';
describe('MetricsTimeControls', () => {
it('should set a valid from and to value for Today', () => {
diff --git a/x-pack/legacy/plugins/infra/public/components/metrics/time_controls.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.tsx
similarity index 92%
rename from x-pack/legacy/plugins/infra/public/components/metrics/time_controls.tsx
rename to x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.tsx
index 7d236cf0a3ea7..d181aa37f59aa 100644
--- a/x-pack/legacy/plugins/infra/public/components/metrics/time_controls.tsx
+++ b/x-pack/legacy/plugins/infra/public/pages/metrics/components/time_controls.tsx
@@ -6,8 +6,8 @@
import { EuiSuperDatePicker, OnRefreshChangeProps, OnTimeChangeProps } from '@elastic/eui';
import React from 'react';
-import euiStyled from '../../../../../common/eui_styled_components';
-import { MetricsTimeInput } from '../../containers/metrics/with_metrics_time';
+import euiStyled from '../../../../../../common/eui_styled_components';
+import { MetricsTimeInput } from '../containers/with_metrics_time';
interface MetricsTimeControlsProps {
currentTimeRange: MetricsTimeInput;
diff --git a/x-pack/legacy/plugins/infra/public/containers/metrics/metrics.gql_query.ts b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/metrics.gql_query.ts
similarity index 100%
rename from x-pack/legacy/plugins/infra/public/containers/metrics/metrics.gql_query.ts
rename to x-pack/legacy/plugins/infra/public/pages/metrics/containers/metrics.gql_query.ts
diff --git a/x-pack/legacy/plugins/infra/public/containers/metrics/metrics_time.test.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/metrics_time.test.tsx
similarity index 100%
rename from x-pack/legacy/plugins/infra/public/containers/metrics/metrics_time.test.tsx
rename to x-pack/legacy/plugins/infra/public/pages/metrics/containers/metrics_time.test.tsx
diff --git a/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics.tsx
similarity index 80%
rename from x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics.tsx
rename to x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics.tsx
index bb346553a4bf9..6f7e411628d27 100644
--- a/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics.tsx
+++ b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics.tsx
@@ -13,9 +13,9 @@ import {
InfraNodeType,
MetricsQuery,
InfraTimerangeInput,
-} from '../../graphql/types';
+} from '../../../graphql/types';
import { metricsQuery } from './metrics.gql_query';
-import { InventoryDetailLayout, InventoryMetric } from '../../../common/inventory_models/types';
+import { InventoryMetric, InventoryMetricRT } from '../../../../common/inventory_models/types';
interface WithMetricsArgs {
metrics: InfraMetricData[];
@@ -26,7 +26,7 @@ interface WithMetricsArgs {
interface WithMetricsProps {
children: (args: WithMetricsArgs) => React.ReactNode;
- layouts: InventoryDetailLayout[];
+ requiredMetrics: InventoryMetric[];
nodeType: InfraNodeType;
nodeId: string;
cloudId: string;
@@ -34,24 +34,20 @@ interface WithMetricsProps {
timerange: InfraTimerangeInput;
}
-const isInfraMetrics = (subject: string[]): subject is InfraMetric[] => {
- return subject.every(s => s in InfraMetric);
+const isInfraMetrics = (subject: any[]): subject is InfraMetric[] => {
+ return subject.every(s => InventoryMetricRT.is(s));
};
export const WithMetrics = ({
children,
- layouts,
+ requiredMetrics,
sourceId,
timerange,
nodeType,
nodeId,
cloudId,
}: WithMetricsProps) => {
- const metrics = layouts.reduce((acc, item) => {
- return acc.concat(item.sections.map(s => s.id));
- }, [] as InventoryMetric[]);
-
- if (!isInfraMetrics(metrics)) {
+ if (!isInfraMetrics(requiredMetrics)) {
throw new Error(
i18n.translate('xpack.infra.invalidInventoryMetricsError', {
defaultMessage: 'One of the InfraMetric is invalid',
@@ -66,7 +62,7 @@ export const WithMetrics = ({
notifyOnNetworkStatusChange
variables={{
sourceId,
- metrics,
+ metrics: requiredMetrics,
nodeType,
nodeId,
cloudId,
diff --git a/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics_time.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics_time.tsx
similarity index 98%
rename from x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics_time.tsx
rename to x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics_time.tsx
index 1afc3a04acd65..6a89e75679468 100644
--- a/x-pack/legacy/plugins/infra/public/containers/metrics/with_metrics_time.tsx
+++ b/x-pack/legacy/plugins/infra/public/pages/metrics/containers/with_metrics_time.tsx
@@ -11,8 +11,8 @@ import moment from 'moment';
import dateMath from '@elastic/datemath';
import * as rt from 'io-ts';
import { isRight } from 'fp-ts/lib/Either';
-import { replaceStateKeyInQueryString, UrlStateContainer } from '../../utils/url_state';
-import { InfraTimerangeInput } from '../../graphql/types';
+import { replaceStateKeyInQueryString, UrlStateContainer } from '../../../utils/url_state';
+import { InfraTimerangeInput } from '../../../graphql/types';
export interface MetricsTimeInput {
from: string;
diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/index.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/index.tsx
index 1996d51b4f26b..643d943273a81 100644
--- a/x-pack/legacy/plugins/infra/public/pages/metrics/index.tsx
+++ b/x-pack/legacy/plugins/infra/public/pages/metrics/index.tsx
@@ -14,34 +14,28 @@ import {
EuiTitle,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
-import { GraphQLFormattedError } from 'graphql';
-import React, { useCallback, useContext } from 'react';
+import React, { useContext, useState } from 'react';
import { UICapabilities } from 'ui/capabilities';
import { injectUICapabilities } from 'ui/capabilities/react';
import euiStyled, { EuiTheme, withTheme } from '../../../../../common/eui_styled_components';
-import { InfraMetricsErrorCodes } from '../../../common/errors';
import { AutoSizer } from '../../components/auto_sizer';
import { DocumentTitle } from '../../components/document_title';
import { Header } from '../../components/header';
-import { Metrics } from '../../components/metrics';
-import { InvalidNodeError } from '../../components/metrics/invalid_node';
-import { MetricsSideNav } from '../../components/metrics/side_nav';
-import { MetricsTimeControls } from '../../components/metrics/time_controls';
+import { MetricsSideNav } from './components/side_nav';
+import { MetricsTimeControls } from './components/time_controls';
import { ColumnarPage, PageContent } from '../../components/page';
-import { WithMetrics } from '../../containers/metrics/with_metrics';
-import {
- WithMetricsTime,
- WithMetricsTimeUrlState,
-} from '../../containers/metrics/with_metrics_time';
+import { WithMetrics } from './containers/with_metrics';
+import { WithMetricsTime, WithMetricsTimeUrlState } from './containers/with_metrics_time';
import { InfraNodeType } from '../../graphql/types';
-import { ErrorPageBody } from '../error';
import { withMetricPageProviders } from './page_providers';
import { useMetadata } from '../../containers/metadata/use_metadata';
import { Source } from '../../containers/source';
import { InfraLoadingPanel } from '../../components/loading';
-import { NodeDetails } from '../../components/metrics/node_details';
+import { NodeDetails } from './components/node_details';
import { findInventoryModel } from '../../../common/inventory_models';
-import { InventoryDetailSection } from '../../../common/inventory_models/types';
+import { PageError } from './components/page_error';
+import { NavItem, SideNavContext } from './lib/side_nav_context';
+import { PageBody } from './components/page_body';
const DetailPageContent = euiStyled(PageContent)`
overflow: auto;
@@ -69,15 +63,26 @@ export const MetricDetail = withMetricPageProviders(
const nodeId = match.params.node;
const nodeType = match.params.type as InfraNodeType;
const inventoryModel = findInventoryModel(nodeType);
- const layoutCreator = inventoryModel.layout;
const { sourceId } = useContext(Source.Context);
- const layouts = layoutCreator(theme);
- const { name, filteredLayouts, loading: metadataLoading, cloudId, metadata } = useMetadata(
- nodeId,
- nodeType,
- layouts,
- sourceId
+ const {
+ name,
+ filteredRequiredMetrics,
+ loading: metadataLoading,
+ cloudId,
+ metadata,
+ } = useMetadata(nodeId, nodeType, inventoryModel.requiredMetrics, sourceId);
+
+ const [sideNav, setSideNav] = useState([]);
+
+ const addNavItem = React.useCallback(
+ (item: NavItem) => {
+ if (!sideNav.some(n => n.id === item.id)) {
+ setSideNav([item, ...sideNav]);
+ }
+ },
+ [sideNav]
);
+
const breadcrumbs = [
{
href: '#/',
@@ -88,18 +93,7 @@ export const MetricDetail = withMetricPageProviders(
{ text: name },
];
- const handleClick = useCallback(
- (section: InventoryDetailSection) => () => {
- const id = section.linkToId || section.id;
- const el = document.getElementById(id);
- if (el) {
- el.scrollIntoView();
- }
- },
- []
- );
-
- if (metadataLoading && !filteredLayouts.length) {
+ if (metadataLoading && !filteredRequiredMetrics.length) {
return (
{({ metrics, error, loading, refetch }) => {
if (error) {
- const invalidNodeError = error.graphQLErrors.some(
- (err: GraphQLFormattedError) =>
- err.code === InfraMetricsErrorCodes.invalid_node
- );
-
- return (
- <>
-
- i18n.translate('xpack.infra.metricDetailPage.documentTitleError', {
- defaultMessage: '{previousTitle} | Uh oh',
- values: {
- previousTitle,
- },
- })
- }
- />
- {invalidNodeError ? (
-
- ) : (
-
- )}
- >
- );
+ return ;
}
return (
-
+
{({ measureRef, bounds: { width = 0 } }) => {
const w = width ? `${width}px` : `100%`;
@@ -209,19 +175,19 @@ export const MetricDetail = withMetricPageProviders(
- 0 && isAutoReloading ? false : loading
- }
- refetch={refetch}
- onChangeRangeTime={setTimeRange}
- isLiveStreaming={isAutoReloading}
- stopLiveStreaming={() => setAutoReload(false)}
- />
+
+ 0 && isAutoReloading ? false : loading
+ }
+ refetch={refetch}
+ type={nodeType}
+ metrics={metrics}
+ onChangeRangeTime={setTimeRange}
+ isLiveStreaming={isAutoReloading}
+ stopLiveStreaming={() => setAutoReload(false)}
+ />
+
diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/lib/side_nav_context.ts b/x-pack/legacy/plugins/infra/public/pages/metrics/lib/side_nav_context.ts
new file mode 100644
index 0000000000000..3afd91ef59e93
--- /dev/null
+++ b/x-pack/legacy/plugins/infra/public/pages/metrics/lib/side_nav_context.ts
@@ -0,0 +1,24 @@
+/*
+ * 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';
+
+export interface SubNavItem {
+ id: string;
+ name: string;
+ onClick: () => void;
+}
+
+export interface NavItem {
+ id: string | number;
+ name: string;
+ items: SubNavItem[];
+}
+
+export const SideNavContext = React.createContext({
+ items: [] as NavItem[],
+ addNavItem: (item: NavItem) => {},
+});
diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/page_providers.tsx b/x-pack/legacy/plugins/infra/public/pages/metrics/page_providers.tsx
index 5e43e79ab7c89..0abbd597dd65c 100644
--- a/x-pack/legacy/plugins/infra/public/pages/metrics/page_providers.tsx
+++ b/x-pack/legacy/plugins/infra/public/pages/metrics/page_providers.tsx
@@ -6,7 +6,7 @@
import React from 'react';
-import { MetricsTimeContainer } from '../../containers/metrics/with_metrics_time';
+import { MetricsTimeContainer } from './containers/with_metrics_time';
import { Source } from '../../containers/source';
export const withMetricPageProviders = (Component: React.ComponentType) => (
diff --git a/x-pack/legacy/plugins/infra/public/pages/metrics/types.ts b/x-pack/legacy/plugins/infra/public/pages/metrics/types.ts
new file mode 100644
index 0000000000000..e752164796150
--- /dev/null
+++ b/x-pack/legacy/plugins/infra/public/pages/metrics/types.ts
@@ -0,0 +1,62 @@
+/*
+ * 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 rt from 'io-ts';
+import { EuiTheme } from '../../../../../common/eui_styled_components';
+import { InfraMetricData } from '../../graphql/types';
+import { InventoryFormatterTypeRT } from '../../../common/inventory_models/types';
+import { MetricsTimeInput } from './containers/with_metrics_time';
+
+export interface LayoutProps {
+ metrics?: InfraMetricData[];
+ onChangeRangeTime?: (time: MetricsTimeInput) => void;
+ isLiveStreaming?: boolean;
+ stopLiveStreaming?: () => void;
+}
+
+export type LayoutPropsWithTheme = LayoutProps & { theme: EuiTheme };
+
+const ChartTypesRT = rt.keyof({
+ area: null,
+ bar: null,
+ line: null,
+});
+
+export const SeriesOverridesObjectRT = rt.intersection([
+ rt.type({
+ color: rt.string,
+ }),
+ rt.partial({
+ name: rt.string,
+ formatter: InventoryFormatterTypeRT,
+ formatterTemplate: rt.string,
+ gaugeMax: rt.number,
+ type: ChartTypesRT,
+ }),
+]);
+
+export const SeriesOverridesRT = rt.record(
+ rt.string,
+ rt.union([rt.undefined, SeriesOverridesObjectRT])
+);
+
+export type SeriesOverrides = rt.TypeOf;
+
+export const VisSectionPropsRT = rt.partial({
+ type: ChartTypesRT,
+ stacked: rt.boolean,
+ formatter: InventoryFormatterTypeRT,
+ formatterTemplate: rt.string,
+ seriesOverrides: SeriesOverridesRT,
+});
+
+export type VisSectionProps = rt.TypeOf & {
+ id?: string;
+ metric?: InfraMetricData;
+ onChangeRangeTime?: (time: MetricsTimeInput) => void;
+ isLiveStreaming?: boolean;
+ stopLiveStreaming?: () => void;
+};
diff --git a/x-pack/legacy/plugins/infra/public/utils/formatters/index.ts b/x-pack/legacy/plugins/infra/public/utils/formatters/index.ts
index 4006e672d8b74..efb20e71a9ce4 100644
--- a/x-pack/legacy/plugins/infra/public/utils/formatters/index.ts
+++ b/x-pack/legacy/plugins/infra/public/utils/formatters/index.ts
@@ -5,26 +5,25 @@
*/
import Mustache from 'mustache';
-import { InfraFormatterType, InfraWaffleMapDataFormat } from '../../lib/lib';
+import { InfraWaffleMapDataFormat } from '../../lib/lib';
import { createBytesFormatter } from './bytes';
import { formatNumber } from './number';
import { formatPercent } from './percent';
+import { InventoryFormatterType } from '../../../common/inventory_models/types';
export const FORMATTERS = {
- [InfraFormatterType.number]: formatNumber,
+ number: formatNumber,
// Because the implimentation for formatting large numbers is the same as formatting
// bytes we are re-using the same code, we just format the number using the abbreviated number format.
- [InfraFormatterType.abbreviatedNumber]: createBytesFormatter(
- InfraWaffleMapDataFormat.abbreviatedNumber
- ),
+ abbreviatedNumber: createBytesFormatter(InfraWaffleMapDataFormat.abbreviatedNumber),
// bytes in bytes formatted string out
- [InfraFormatterType.bytes]: createBytesFormatter(InfraWaffleMapDataFormat.bytesDecimal),
+ bytes: createBytesFormatter(InfraWaffleMapDataFormat.bytesDecimal),
// bytes in bits formatted string out
- [InfraFormatterType.bits]: createBytesFormatter(InfraWaffleMapDataFormat.bitsDecimal),
- [InfraFormatterType.percent]: formatPercent,
+ bits: createBytesFormatter(InfraWaffleMapDataFormat.bitsDecimal),
+ percent: formatPercent,
};
-export const createFormatter = (format: InfraFormatterType, template: string = '{{value}}') => (
+export const createFormatter = (format: InventoryFormatterType, template: string = '{{value}}') => (
val: string | number
) => {
if (val == null) {
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index cbb65c61c1bc6..f0c4cb3010eab 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -5977,7 +5977,6 @@
"xpack.infra.metrics.emptyViewTitle": "表示するデータがありません。",
"xpack.infra.metrics.invalidNodeErrorDescription": "構成をよく確認してください",
"xpack.infra.metrics.invalidNodeErrorTitle": "{nodeName} がメトリックデータを収集していないようです",
- "xpack.infra.metrics.layoutLabelOverviewTitle": "{layoutLabel} 概要",
"xpack.infra.metrics.loadingNodeDataText": "データを読み込み中",
"xpack.infra.metrics.refetchButtonLabel": "新規データを確認",
"xpack.infra.metricsExplorer.actionsLabel.aria": "{grouping} のアクション",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 6bbf7394023be..913cd85579f9d 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -5918,7 +5918,6 @@
"xpack.infra.metrics.emptyViewTitle": "没有可显示的数据。",
"xpack.infra.metrics.invalidNodeErrorDescription": "反复检查您的配置",
"xpack.infra.metrics.invalidNodeErrorTitle": "似乎 {nodeName} 未在收集任何指标数据",
- "xpack.infra.metrics.layoutLabelOverviewTitle": "{layoutLabel} 概览",
"xpack.infra.metrics.loadingNodeDataText": "正在加载数据",
"xpack.infra.metrics.refetchButtonLabel": "检查新数据",
"xpack.infra.metricsExplorer.actionsLabel.aria": "适用于 {grouping} 的操作",
diff --git a/x-pack/test/api_integration/apis/infra/metrics.ts b/x-pack/test/api_integration/apis/infra/metrics.ts
index d40359edc5ff2..00c57bcc45e32 100644
--- a/x-pack/test/api_integration/apis/infra/metrics.ts
+++ b/x-pack/test/api_integration/apis/infra/metrics.ts
@@ -7,7 +7,7 @@
import expect from '@kbn/expect';
import { first, last } from 'lodash';
-import { metricsQuery } from '../../../../legacy/plugins/infra/public/containers/metrics/metrics.gql_query';
+import { metricsQuery } from '../../../../legacy/plugins/infra/public/pages/metrics/containers/metrics.gql_query';
import { MetricsQuery } from '../../../../legacy/plugins/infra/public/graphql/types';
import { FtrProviderContext } from '../../ftr_provider_context';