diff --git a/x-pack/plugins/observability/public/application/index.tsx b/x-pack/plugins/observability/public/application/index.tsx index f8dce3ce1d487e..69ee6fa19cf0f7 100644 --- a/x-pack/plugins/observability/public/application/index.tsx +++ b/x-pack/plugins/observability/public/application/index.tsx @@ -6,30 +6,25 @@ */ import { i18n } from '@kbn/i18n'; -import React, { MouseEvent, useEffect } from 'react'; +import React from 'react'; import ReactDOM from 'react-dom'; import { Route, Router, Switch } from 'react-router-dom'; -import { EuiThemeProvider } from '../../../../../src/plugins/kibana_react/common'; +import { ConfigSchema } from '..'; import { AppMountParameters, APP_WRAPPER_CLASS, CoreStart } from '../../../../../src/core/public'; +import { EuiThemeProvider } from '../../../../../src/plugins/kibana_react/common'; import { KibanaContextProvider, RedirectAppLinks, } from '../../../../../src/plugins/kibana_react/public'; +import { Storage } from '../../../../../src/plugins/kibana_utils/public'; +import type { LazyObservabilityPageTemplateProps } from '../components/shared/page_template/lazy_page_template'; +import { HasDataContextProvider } from '../context/has_data_context'; import { PluginContext } from '../context/plugin_context'; -import { usePluginContext } from '../hooks/use_plugin_context'; import { useRouteParams } from '../hooks/use_route_params'; import { ObservabilityPublicPluginsStart } from '../plugin'; -import type { LazyObservabilityPageTemplateProps } from '../components/shared/page_template/lazy_page_template'; -import { HasDataContextProvider } from '../context/has_data_context'; -import { Breadcrumbs, routes } from '../routes'; -import { Storage } from '../../../../../src/plugins/kibana_utils/public'; -import { ConfigSchema } from '..'; +import { routes } from '../routes'; import { ObservabilityRuleTypeRegistry } from '../rules/create_observability_rule_type_registry'; -function getTitleFromBreadCrumbs(breadcrumbs: Breadcrumbs) { - return breadcrumbs.map(({ text }) => text).reverse(); -} - function App() { return ( <> @@ -38,27 +33,6 @@ function App() { const path = key as keyof typeof routes; const route = routes[path]; const Wrapper = () => { - const { core } = usePluginContext(); - - useEffect(() => { - const href = core.http.basePath.prepend('/app/observability'); - const breadcrumbs = [ - { - href, - text: i18n.translate('xpack.observability.observability.breadcrumb.', { - defaultMessage: 'Observability', - }), - onClick: (event: MouseEvent) => { - event.preventDefault(); - core.application.navigateToUrl(href); - }, - }, - ...route.breadcrumb, - ]; - core.chrome.setBreadcrumbs(breadcrumbs); - core.chrome.docTitle.change(getTitleFromBreadCrumbs(breadcrumbs)); - }, [core]); - const params = useRouteParams(path); return route.handler(params); }; diff --git a/x-pack/plugins/observability/public/components/app/cases/case_view/index.tsx b/x-pack/plugins/observability/public/components/app/cases/case_view/index.tsx index 3267f7bb17cce6..728333ac8c544f 100644 --- a/x-pack/plugins/observability/public/components/app/cases/case_view/index.tsx +++ b/x-pack/plugins/observability/public/components/app/cases/case_view/index.tsx @@ -7,6 +7,7 @@ import React, { useCallback, useState } from 'react'; import { + casesBreadcrumbs, getCaseDetailsUrl, getCaseDetailsUrlWithCommentId, getCaseUrl, @@ -17,7 +18,7 @@ import { Case } from '../../../../../../cases/common'; import { useFetchAlertData } from './helpers'; import { useKibana } from '../../../../utils/kibana_react'; import { CASES_APP_ID } from '../constants'; -import { casesBreadcrumbs, useBreadcrumbs } from '../../../../hooks/use_breadcrumbs'; +import { useBreadcrumbs } from '../../../../hooks/use_breadcrumbs'; interface Props { caseId: string; diff --git a/x-pack/plugins/observability/public/hooks/use_breadcrumbs.test.tsx b/x-pack/plugins/observability/public/hooks/use_breadcrumbs.test.tsx new file mode 100644 index 00000000000000..d033ecc2069cdf --- /dev/null +++ b/x-pack/plugins/observability/public/hooks/use_breadcrumbs.test.tsx @@ -0,0 +1,116 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { renderHook } from '@testing-library/react-hooks'; +import React, { ReactNode } from 'react'; +import { MemoryRouter } from 'react-router-dom'; +import { CoreStart } from '../../../../../src/core/public'; +import { createKibanaReactContext } from '../../../../../src/plugins/kibana_react/public'; +import { useBreadcrumbs } from './use_breadcrumbs'; + +const setBreadcrumbs = jest.fn(); +const setTitle = jest.fn(); +const kibanaServices = ({ + application: { getUrlForApp: () => {}, navigateToApp: () => {} }, + chrome: { setBreadcrumbs, docTitle: { change: setTitle } }, + uiSettings: { get: () => true }, +} as unknown) as Partial; +const KibanaContext = createKibanaReactContext(kibanaServices); + +function Wrapper({ children }: { children?: ReactNode }) { + return ( + + {children} + + ); +} + +describe('useBreadcrumbs', () => { + afterEach(() => { + setBreadcrumbs.mockClear(); + setTitle.mockClear(); + }); + + describe('when setBreadcrumbs and setTitle are not defined', () => { + it('does not set breadcrumbs or the title', () => { + renderHook(() => useBreadcrumbs([]), { + wrapper: ({ children }) => ( + + + } + > + {children} + + + ), + }); + + expect(setBreadcrumbs).not.toHaveBeenCalled(); + expect(setTitle).not.toHaveBeenCalled(); + }); + }); + + describe('with an empty array', () => { + it('sets the overview breadcrumb', () => { + renderHook(() => useBreadcrumbs([]), { wrapper: Wrapper }); + + expect(setBreadcrumbs).toHaveBeenCalledWith([ + { href: '/overview', onClick: expect.any(Function), text: 'Observability' }, + ]); + }); + + it('sets the overview title', () => { + renderHook(() => useBreadcrumbs([]), { wrapper: Wrapper }); + + expect(setTitle).toHaveBeenCalledWith(['Observability']); + }); + }); + + describe('given breadcrumbs', () => { + it('sets the breadcrumbs', () => { + renderHook( + () => + useBreadcrumbs([ + { text: 'One', href: '/one' }, + { + text: 'Two', + }, + ]), + { wrapper: Wrapper } + ); + + expect(setBreadcrumbs).toHaveBeenCalledWith([ + { href: '/overview', onClick: expect.any(Function), text: 'Observability' }, + { + href: '/one', + onClick: expect.any(Function), + text: 'One', + }, + { + text: 'Two', + }, + ]); + }); + + it('sets the title', () => { + renderHook( + () => + useBreadcrumbs([ + { text: 'One', href: '/one' }, + { + text: 'Two', + }, + ]), + { wrapper: Wrapper } + ); + + expect(setTitle).toHaveBeenCalledWith(['Two', 'One', 'Observability']); + }); + }); +}); diff --git a/x-pack/plugins/observability/public/hooks/use_breadcrumbs.ts b/x-pack/plugins/observability/public/hooks/use_breadcrumbs.ts index 090031e314fd1a..241a978d36948b 100644 --- a/x-pack/plugins/observability/public/hooks/use_breadcrumbs.ts +++ b/x-pack/plugins/observability/public/hooks/use_breadcrumbs.ts @@ -5,14 +5,13 @@ * 2.0. */ -import { ChromeBreadcrumb } from 'kibana/public'; import { i18n } from '@kbn/i18n'; +import { ChromeBreadcrumb } from 'kibana/public'; import { MouseEvent, useEffect } from 'react'; -import { EuiBreadcrumb } from '@elastic/eui'; -import { useQueryParams } from './use_query_params'; import { useKibana } from '../utils/kibana_react'; +import { useQueryParams } from './use_query_params'; -function handleBreadcrumbClick( +function addClickHandlers( breadcrumbs: ChromeBreadcrumb[], navigateToHref?: (url: string) => Promise ) { @@ -31,52 +30,37 @@ function handleBreadcrumbClick( })); } -export const makeBaseBreadcrumb = (href: string): EuiBreadcrumb => { - return { - text: i18n.translate('xpack.observability.breadcrumbs.observability', { - defaultMessage: 'Observability', - }), - href, - }; -}; -export const casesBreadcrumbs = { - cases: { - text: i18n.translate('xpack.observability.breadcrumbs.observability.cases', { - defaultMessage: 'Cases', - }), - }, - create: { - text: i18n.translate('xpack.observability.breadcrumbs.observability.cases.create', { - defaultMessage: 'Create', - }), - }, - configure: { - text: i18n.translate('xpack.observability.breadcrumbs.observability.cases.configure', { - defaultMessage: 'Configure', - }), - }, -}; +function getTitleFromBreadCrumbs(breadcrumbs: ChromeBreadcrumb[]) { + return breadcrumbs.map(({ text }) => text?.toString() ?? '').reverse(); +} + export const useBreadcrumbs = (extraCrumbs: ChromeBreadcrumb[]) => { const params = useQueryParams(); const { services: { - chrome: { setBreadcrumbs }, + chrome: { docTitle, setBreadcrumbs }, application: { getUrlForApp, navigateToUrl }, }, } = useKibana(); - + const setTitle = docTitle.change; const appPath = getUrlForApp('observability-overview') ?? ''; - const navigate = navigateToUrl; useEffect(() => { + const breadcrumbs = [ + { + text: i18n.translate('xpack.observability.breadcrumbs.observabilityLinkText', { + defaultMessage: 'Observability', + }), + href: appPath + '/overview', + }, + ...extraCrumbs, + ]; if (setBreadcrumbs) { - setBreadcrumbs( - handleBreadcrumbClick( - [makeBaseBreadcrumb(appPath + '/overview')].concat(extraCrumbs), - navigate - ) - ); + setBreadcrumbs(addClickHandlers(breadcrumbs, navigateToUrl)); + } + if (setTitle) { + setTitle(getTitleFromBreadCrumbs(breadcrumbs)); } - }, [appPath, extraCrumbs, navigate, params, setBreadcrumbs]); + }, [appPath, extraCrumbs, navigateToUrl, params, setBreadcrumbs, setTitle]); }; diff --git a/x-pack/plugins/observability/public/pages/alerts/index.tsx b/x-pack/plugins/observability/public/pages/alerts/index.tsx index bd926f3a326bf7..6f696a70665ce6 100644 --- a/x-pack/plugins/observability/public/pages/alerts/index.tsx +++ b/x-pack/plugins/observability/public/pages/alerts/index.tsx @@ -12,6 +12,7 @@ import { useHistory } from 'react-router-dom'; import { ParsedTechnicalFields } from '../../../../rule_registry/common/parse_technical_fields'; import type { AlertStatus } from '../../../common/typings'; import { ExperimentalBadge } from '../../components/shared/experimental_badge'; +import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; import { useFetcher } from '../../hooks/use_fetcher'; import { usePluginContext } from '../../hooks/use_plugin_context'; import { RouteParams } from '../../routes'; @@ -44,6 +45,14 @@ export function AlertsPage({ routeParams }: AlertsPageProps) { query: { rangeFrom = 'now-15m', rangeTo = 'now', kuery = '', status = 'open' }, } = routeParams; + useBreadcrumbs([ + { + text: i18n.translate('xpack.observability.breadcrumbs.alertsLinkText', { + defaultMessage: 'Alerts', + }), + }, + ]); + // In a future milestone we'll have a page dedicated to rule management in // observability. For now link to the settings page. const manageDetectionRulesHref = prepend( diff --git a/x-pack/plugins/observability/public/pages/cases/all_cases.tsx b/x-pack/plugins/observability/public/pages/cases/all_cases.tsx index 4131cdc40738f2..f73f3b4cf57d75 100644 --- a/x-pack/plugins/observability/public/pages/cases/all_cases.tsx +++ b/x-pack/plugins/observability/public/pages/cases/all_cases.tsx @@ -14,10 +14,15 @@ import { permissionsReadOnlyErrorMessage, CaseCallOut } from '../../components/a import { CaseFeatureNoPermissions } from './feature_no_permissions'; import { useGetUserCasesPermissions } from '../../hooks/use_get_user_cases_permissions'; import { usePluginContext } from '../../hooks/use_plugin_context'; +import { casesBreadcrumbs } from './links'; +import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; export const AllCasesPage = React.memo(() => { const userPermissions = useGetUserCasesPermissions(); const { ObservabilityPageTemplate } = usePluginContext(); + + useBreadcrumbs([casesBreadcrumbs.cases]); + return userPermissions == null || userPermissions?.read ? ( <> {userPermissions != null && !userPermissions?.crud && userPermissions?.read && ( diff --git a/x-pack/plugins/observability/public/pages/cases/configure_cases.tsx b/x-pack/plugins/observability/public/pages/cases/configure_cases.tsx index acc6bdf68fba75..2986c1ff34e11c 100644 --- a/x-pack/plugins/observability/public/pages/cases/configure_cases.tsx +++ b/x-pack/plugins/observability/public/pages/cases/configure_cases.tsx @@ -14,8 +14,8 @@ import { CASES_APP_ID, CASES_OWNER } from '../../components/app/cases/constants' import { useKibana } from '../../utils/kibana_react'; import { useGetUserCasesPermissions } from '../../hooks/use_get_user_cases_permissions'; import { usePluginContext } from '../../hooks/use_plugin_context'; -import { casesBreadcrumbs, useBreadcrumbs } from '../../hooks/use_breadcrumbs'; -import { getCaseUrl, useFormatUrl } from './links'; +import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; +import { casesBreadcrumbs, getCaseUrl, useFormatUrl } from './links'; const ButtonEmpty = styled(EuiButtonEmpty)` display: block; diff --git a/x-pack/plugins/observability/public/pages/cases/create_case.tsx b/x-pack/plugins/observability/public/pages/cases/create_case.tsx index d0e25e6263075b..11f6d62da61033 100644 --- a/x-pack/plugins/observability/public/pages/cases/create_case.tsx +++ b/x-pack/plugins/observability/public/pages/cases/create_case.tsx @@ -14,8 +14,8 @@ import { CASES_APP_ID } from '../../components/app/cases/constants'; import { useKibana } from '../../utils/kibana_react'; import { useGetUserCasesPermissions } from '../../hooks/use_get_user_cases_permissions'; import { usePluginContext } from '../../hooks/use_plugin_context'; -import { getCaseUrl, useFormatUrl } from './links'; -import { casesBreadcrumbs, useBreadcrumbs } from '../../hooks/use_breadcrumbs'; +import { casesBreadcrumbs, getCaseUrl, useFormatUrl } from './links'; +import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; const ButtonEmpty = styled(EuiButtonEmpty)` display: block; diff --git a/x-pack/plugins/observability/public/pages/cases/links.ts b/x-pack/plugins/observability/public/pages/cases/links.ts index 768d74ec4e7ee3..9b2f464a0e8471 100644 --- a/x-pack/plugins/observability/public/pages/cases/links.ts +++ b/x-pack/plugins/observability/public/pages/cases/links.ts @@ -5,10 +5,29 @@ * 2.0. */ -import { useCallback } from 'react'; +import { i18n } from '@kbn/i18n'; import { isEmpty } from 'lodash/fp'; +import { useCallback } from 'react'; import { useKibana } from '../../utils/kibana_react'; +export const casesBreadcrumbs = { + cases: { + text: i18n.translate('xpack.observability.breadcrumbs.casesLinkText', { + defaultMessage: 'Cases', + }), + }, + create: { + text: i18n.translate('xpack.observability.breadcrumbs.casesCreateLinkText', { + defaultMessage: 'Create', + }), + }, + configure: { + text: i18n.translate('xpack.observability.breadcrumbs.casesConfigureLinkText', { + defaultMessage: 'Configure', + }), + }, +}; + export const getCaseDetailsUrl = ({ id, subCaseId }: { id: string; subCaseId?: string }) => { if (subCaseId) { return `/${encodeURIComponent(id)}/sub-cases/${encodeURIComponent(subCaseId)}`; diff --git a/x-pack/plugins/observability/public/pages/landing/index.tsx b/x-pack/plugins/observability/public/pages/landing/index.tsx index 46c99bffbcc698..28d3784c65c4ae 100644 --- a/x-pack/plugins/observability/public/pages/landing/index.tsx +++ b/x-pack/plugins/observability/public/pages/landing/index.tsx @@ -21,6 +21,7 @@ import React, { useContext } from 'react'; import styled, { ThemeContext } from 'styled-components'; import { FleetPanel } from '../../components/app/fleet_panel'; import { ObservabilityHeaderMenu } from '../../components/app/header'; +import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; import { usePluginContext } from '../../hooks/use_plugin_context'; import { useTrackPageview } from '../../hooks/use_track_metric'; import { appsSection } from '../home/section'; @@ -33,6 +34,13 @@ const EuiCardWithoutPadding = styled(EuiCard)` export function LandingPage() { useTrackPageview({ app: 'observability-overview', path: 'landing' }); useTrackPageview({ app: 'observability-overview', path: 'landing', delay: 15000 }); + useBreadcrumbs([ + { + text: i18n.translate('xpack.observability.breadcrumbs.landingLinkText', { + defaultMessage: 'Getting started', + }), + }, + ]); const { core, ObservabilityPageTemplate } = usePluginContext(); const theme = useContext(ThemeContext); diff --git a/x-pack/plugins/observability/public/pages/overview/index.tsx b/x-pack/plugins/observability/public/pages/overview/index.tsx index 4cb6792d501952..89398ad16f1988 100644 --- a/x-pack/plugins/observability/public/pages/overview/index.tsx +++ b/x-pack/plugins/observability/public/pages/overview/index.tsx @@ -16,6 +16,7 @@ import { NewsFeed } from '../../components/app/news_feed'; import { Resources } from '../../components/app/resources'; import { AlertsSection } from '../../components/app/section/alerts'; import { DatePicker } from '../../components/shared/date_picker'; +import { useBreadcrumbs } from '../../hooks/use_breadcrumbs'; import { useFetcher } from '../../hooks/use_fetcher'; import { useHasData } from '../../hooks/use_has_data'; import { usePluginContext } from '../../hooks/use_plugin_context'; @@ -39,6 +40,14 @@ function calculateBucketSize({ start, end }: { start?: number; end?: number }) { export function OverviewPage({ routeParams }: Props) { useTrackPageview({ app: 'observability-overview', path: 'overview' }); useTrackPageview({ app: 'observability-overview', path: 'overview', delay: 15000 }); + useBreadcrumbs([ + { + text: i18n.translate('xpack.observability.breadcrumbs.overviewLinkText', { + defaultMessage: 'Overview', + }), + }, + ]); + const { core, ObservabilityPageTemplate } = usePluginContext(); const { relativeStart, relativeEnd, absoluteStart, absoluteEnd } = useTimeRange(); diff --git a/x-pack/plugins/observability/public/routes/index.tsx b/x-pack/plugins/observability/public/routes/index.tsx index a2a67a42bd166a..92f51aeff9bd63 100644 --- a/x-pack/plugins/observability/public/routes/index.tsx +++ b/x-pack/plugins/observability/public/routes/index.tsx @@ -5,21 +5,19 @@ * 2.0. */ -import React from 'react'; import * as t from 'io-ts'; -import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { alertStatusRt } from '../../common/typings'; +import { ExploratoryViewPage } from '../components/shared/exploratory_view'; +import { AlertsPage } from '../pages/alerts'; +import { AllCasesPage } from '../pages/cases/all_cases'; +import { CaseDetailsPage } from '../pages/cases/case_details'; +import { ConfigureCasesPage } from '../pages/cases/configure_cases'; +import { CreateCasePage } from '../pages/cases/create_case'; import { HomePage } from '../pages/home'; import { LandingPage } from '../pages/landing'; import { OverviewPage } from '../pages/overview'; import { jsonRt } from './json_rt'; -import { AlertsPage } from '../pages/alerts'; -import { CreateCasePage } from '../pages/cases/create_case'; -import { ExploratoryViewPage } from '../components/shared/exploratory_view'; -import { CaseDetailsPage } from '../pages/cases/case_details'; -import { ConfigureCasesPage } from '../pages/cases/configure_cases'; -import { AllCasesPage } from '../pages/cases/all_cases'; -import { casesBreadcrumbs } from '../hooks/use_breadcrumbs'; -import { alertStatusRt } from '../../common/typings'; export type RouteParams = DecodeParams; @@ -27,8 +25,6 @@ type DecodeParams = { [key in keyof TParams]: TParams[key] extends t.Any ? t.TypeOf : never; }; -export type Breadcrumbs = Array<{ text: string }>; - export interface Params { query?: t.HasProps; path?: t.HasProps; @@ -40,26 +36,12 @@ export const routes = { return ; }, params: {}, - breadcrumb: [ - { - text: i18n.translate('xpack.observability.home.breadcrumb', { - defaultMessage: 'Overview', - }), - }, - ], }, '/landing': { handler: () => { return ; }, params: {}, - breadcrumb: [ - { - text: i18n.translate('xpack.observability.landing.breadcrumb', { - defaultMessage: 'Getting started', - }), - }, - ], }, '/overview': { handler: ({ query }: any) => { @@ -73,34 +55,24 @@ export const routes = { refreshInterval: jsonRt.pipe(t.number), }), }, - breadcrumb: [ - { - text: i18n.translate('xpack.observability.overview.breadcrumb', { - defaultMessage: 'Overview', - }), - }, - ], }, '/cases': { handler: () => { return ; }, params: {}, - breadcrumb: [casesBreadcrumbs.cases], }, '/cases/create': { handler: () => { return ; }, params: {}, - breadcrumb: [casesBreadcrumbs.cases, casesBreadcrumbs.create], }, '/cases/configure': { handler: () => { return ; }, params: {}, - breadcrumb: [casesBreadcrumbs.cases, casesBreadcrumbs.configure], }, '/cases/:detailName': { handler: () => { @@ -111,7 +83,6 @@ export const routes = { detailName: t.string, }), }, - breadcrumb: [casesBreadcrumbs.cases], }, '/alerts': { handler: (routeParams: any) => { @@ -127,13 +98,6 @@ export const routes = { refreshInterval: jsonRt.pipe(t.number), }), }, - breadcrumb: [ - { - text: i18n.translate('xpack.observability.alerts.breadcrumb', { - defaultMessage: 'Alerts', - }), - }, - ], }, '/exploratory-view': { handler: () => { @@ -147,12 +111,5 @@ export const routes = { refreshInterval: jsonRt.pipe(t.number), }), }, - breadcrumb: [ - { - text: i18n.translate('xpack.observability.overview.exploratoryView', { - defaultMessage: 'Analyze data', - }), - }, - ], }, }; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index efe3345c7039fa..8eb19f0b0347d6 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -17233,7 +17233,6 @@ "xpack.monitoring.updateLicenseButtonLabel": "ライセンスを更新", "xpack.monitoring.updateLicenseTitle": "ライセンスの更新", "xpack.monitoring.useAvailableLicenseDescription": "すでに新しいライセンスがある場合は、今すぐアップロードしてください。", - "xpack.observability.alerts.breadcrumb": "アラート", "xpack.observability.alerts.manageDetectionRulesButtonLabel": "検出ルールの管理", "xpack.observability.alerts.searchBarPlaceholder": "\"domain\": \"ecommerce\" AND (\"service.name\":\"ProductCatalogService\" …)", "xpack.observability.alertsDisclaimerLinkText": "アラートとアクション", @@ -17254,7 +17253,6 @@ "xpack.observability.alertsTable.triggeredColumnDescription": "実行済み", "xpack.observability.alertsTable.viewInAppButtonLabel": "アプリで表示", "xpack.observability.alertsTitle": "アラート", - "xpack.observability.breadcrumbs.observability": "オブザーバビリティ", "xpack.observability.emptySection.apps.alert.description": "503 エラーが累積していますか?サービスは応答していますか?CPUとRAMの使用量が跳ね上がっていますか?このような警告を、事後にではなく、発生と同時に把握しましょう。", "xpack.observability.emptySection.apps.alert.link": "アラートの作成", "xpack.observability.emptySection.apps.alert.title": "アラートが見つかりません。", @@ -17330,15 +17328,12 @@ "xpack.observability.formatters.secondsTimeUnitLabel": "s", "xpack.observability.formatters.secondsTimeUnitLabelExtended": "秒", "xpack.observability.home.addData": "データの追加", - "xpack.observability.home.breadcrumb": "概要", "xpack.observability.home.getStatedButton": "使ってみる", "xpack.observability.home.sectionsubtitle": "ログ、メトリック、トレースを大規模に、1つのスタックにまとめて、環境内のあらゆる場所で生じるイベントの監視、分析、対応を行います。", "xpack.observability.home.sectionTitle": "エコシステム全体の一元的な可視性", - "xpack.observability.landing.breadcrumb": "はじめて使う", "xpack.observability.news.readFullStory": "詳細なストーリーを読む", "xpack.observability.news.title": "新機能", "xpack.observability.notAvailable": "N/A", - "xpack.observability.observability.breadcrumb.": "オブザーバビリティ", "xpack.observability.overview.alert.allTypes": "すべてのタイプ", "xpack.observability.overview.alert.appLink": "アラートを管理", "xpack.observability.overview.alert.view": "表示", @@ -17348,7 +17343,6 @@ "xpack.observability.overview.apm.services": "サービス", "xpack.observability.overview.apm.throughput": "スループット", "xpack.observability.overview.apm.title": "APM", - "xpack.observability.overview.breadcrumb": "概要", "xpack.observability.overview.exploratoryView": "調査ビュー", "xpack.observability.overview.exploratoryView.lensDisabled": "Lensアプリを使用できません。調査ビューを使用するには、Lensを有効にしてください。", "xpack.observability.overview.loadingObservability": "オブザーバビリティを読み込んでいます", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 5409da1c6c00b8..9fc6453ef2c3f6 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -17469,7 +17469,6 @@ "xpack.monitoring.updateLicenseButtonLabel": "更新许可证", "xpack.monitoring.updateLicenseTitle": "更新您的许可证", "xpack.monitoring.useAvailableLicenseDescription": "如果您已经持有新的许可证,请立即上传。", - "xpack.observability.alerts.breadcrumb": "告警", "xpack.observability.alerts.manageDetectionRulesButtonLabel": "管理检测规则", "xpack.observability.alerts.searchBarPlaceholder": "\"domain\": \"ecommerce\" AND (\"service.name\":\"ProductCatalogService\" …)", "xpack.observability.alertsDisclaimerLinkText": "告警和操作", @@ -17490,7 +17489,6 @@ "xpack.observability.alertsTable.triggeredColumnDescription": "已触发", "xpack.observability.alertsTable.viewInAppButtonLabel": "在应用中查看", "xpack.observability.alertsTitle": "告警", - "xpack.observability.breadcrumbs.observability": "可观测性", "xpack.observability.emptySection.apps.alert.description": "503 错误是否越来越多?服务是否响应?CPU 和 RAM 利用率是否激增?实时查看警告,而不是事后再进行剖析。", "xpack.observability.emptySection.apps.alert.link": "创建告警", "xpack.observability.emptySection.apps.alert.title": "未找到告警。", @@ -17566,15 +17564,12 @@ "xpack.observability.formatters.secondsTimeUnitLabel": "s", "xpack.observability.formatters.secondsTimeUnitLabelExtended": "秒", "xpack.observability.home.addData": "添加数据", - "xpack.observability.home.breadcrumb": "概览", "xpack.observability.home.getStatedButton": "开始使用", "xpack.observability.home.sectionsubtitle": "通过根据需要将日志、指标和跟踪都置于单个堆栈上,来监测、分析和响应环境中任何位置发生的事件。", "xpack.observability.home.sectionTitle": "整个生态系统的统一可见性", - "xpack.observability.landing.breadcrumb": "入门", "xpack.observability.news.readFullStory": "详细了解", "xpack.observability.news.title": "最新动态", "xpack.observability.notAvailable": "不可用", - "xpack.observability.observability.breadcrumb.": "可观测性", "xpack.observability.overview.alert.allTypes": "所有类型", "xpack.observability.overview.alert.appLink": "管理告警", "xpack.observability.overview.alert.view": "查看", @@ -17584,7 +17579,6 @@ "xpack.observability.overview.apm.services": "服务", "xpack.observability.overview.apm.throughput": "吞吐量", "xpack.observability.overview.apm.title": "APM", - "xpack.observability.overview.breadcrumb": "概览", "xpack.observability.overview.exploratoryView": "浏览视图", "xpack.observability.overview.exploratoryView.lensDisabled": "Lens 应用不可用,请启用 Lens 以使用浏览视图。", "xpack.observability.overview.loadingObservability": "正在加载可观测性",