mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[8.16] [Observability] Update breadcrumbs for observability project based navigation (#196785) (#198216)
# Backport This will backport the following commits from `main` to `8.16`: - [[Observability] Update breadcrumbs for observability project based navigation (#196785)](https://github.com/elastic/kibana/pull/196785) <!--- Backport version: 9.4.3 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sqren/backport) <!--BACKPORT [{"author":{"name":"Kerry Gallagher","email":"kerry.gallagher@elastic.co"},"sourceCommit":{"committedDate":"2024-10-29T22:04:01Z","message":"[Observability] Update breadcrumbs for observability project based navigation (#196785)\n\n~⚠️ I'm still putting out some fires with tests, but this is ready to\r\nstart being reviewed.~\r\n\r\n## Summary\r\n\r\nA continuation of https://github.com/elastic/kibana/pull/196169 for\r\nObservability (please read that PR description first).\r\n\r\nRelated: https://github.com/elastic/kibana/issues/192050\r\n\r\n## Overview of changes\r\n\r\nThere are essentially three types of breadcrumbs - serverless (which is\r\nproject style), stateful project style (set through spaces settings),\r\nand classic style (the old breadcrumbs we've seen for years). Whilst\r\nserverless and stateful project style both use the project based style\r\nthe navigation trees are slightly different, so the breadcrumbs results\r\nare not identical [when they derive the \"nav\r\ncrumbs\"](9577aa980d/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/breadcrumbs.tsx (L55)
).\r\n\r\nHere \"project style\" will refer to serverless and stateful project\r\nstyle.\r\n\r\nIn these changes I've, for the most part, tried to refactor things so\r\nObservability solutions route their breadcrumbs through the\r\nobservability-shared `useBreadcrumbs` hook, this way the logic around\r\nproject style, adding an Observability crumb in classic etc is\r\nconsolidated in one place.\r\n\r\n[For several solutions `absolute` breadcrumbs are being\r\nused](9577aa980d/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/breadcrumbs.tsx (L46)
),\r\nand this means we'll roughly have the same breadcrumbs across the 3\r\nexperiences (bar Observability being prepended). Teams may want to\r\nrefine this going forward to pass curated breadcrumbs that take into\r\naccount the navigation derived \"nav crumbs\" (again, bearing in mind the\r\ntrees from serverless and project based chrome do differ), and not use\r\nabsolute mode. APM is an example of this at the moment. Right now this\r\nis an 8.16 bug though, so this aims to make things acceptable, but not\r\nnecessarily perfect.\r\n\r\n### APM\r\n\r\n- Project style chrome crumbs have been modelled off the serverless\r\nones. The navigation trees here are the same so this should be fine.\r\n\r\n### Infra\r\n\r\n- The `infra` `useBreadcrumbs` hook has been removed, it was only being\r\nused by logs. Logs now goes via the Observability shared hook using\r\n`classicOnly`.\r\n\r\n- Metrics (`useMetricsBreadcrumbs` hook) has been slightly amended to\r\nroute more of it's logic through the shared hook.\r\n\r\n### Logs explorer\r\n\r\n- Wasn't setting any nested breadcrumbs at the moment so the logic has\r\nbeen simplified to just set some classic crumbs, and defer the rest to\r\nthe nav crumbs via the shared hook.\r\n\r\n### Synthetics \r\n\r\n- Removed custom logic around prepending Observability, adding link\r\nhandlers etc in favour of the shared hook.\r\n\r\n\r\n### Alerts / rules / SLOs etc\r\n\r\n- Simple breadcrumb needs so these are mostly setting `classicOnly` and\r\ndeferring to the nav crumbs in project style.\r\n\r\nSeveral solutions have had their usage of the shared hook updated to\r\npass in the `serverless` plugin. This was missing before, so calls to\r\n`serverless.setBreadcrumbs` weren't explicitly happening.\r\n\r\n## Testing \r\n\r\n- Add the following to your `kibana.dev.yml`:\r\n\r\n```yml\r\nxpack.cloud.id: \"ftr_fake_cloud_id:aGVsbG8uY29tOjQ0MyRFUzEyM2FiYyRrYm4xMjNhYmM=\"\r\nxpack.cloud.base_url: \"https://cloud.elastic.co\"\r\n```\r\n\r\n- For testing stateful project style chrome you'll need to go to Stack\r\nManagement > Spaces and change the solution view:\r\n\r\n\r\n\r\n- Set the above to Classic to test classic breadcrumbs.\r\n\r\n- As a reviewer please check your solution against the 3 modes.\r\n\r\n## Comparison\r\n\r\nBefore these changes we'd see something like the following in APM:\r\n\r\n\r\n\r\nNow we'll see something like this in project style:\r\n\r\n","sha":"641d9159451447484f3940f0b1c17438472fea5c","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","ci:project-deploy-observability","Team:obs-ux-infra_services","Team:obs-ux-management","apm:review","v8.16.0","backport:version","v8.17.0"],"title":"[Observability] Update breadcrumbs for observability project based navigation","number":196785,"url":"https://github.com/elastic/kibana/pull/196785","mergeCommit":{"message":"[Observability] Update breadcrumbs for observability project based navigation (#196785)\n\n~⚠️ I'm still putting out some fires with tests, but this is ready to\r\nstart being reviewed.~\r\n\r\n## Summary\r\n\r\nA continuation of https://github.com/elastic/kibana/pull/196169 for\r\nObservability (please read that PR description first).\r\n\r\nRelated: https://github.com/elastic/kibana/issues/192050\r\n\r\n## Overview of changes\r\n\r\nThere are essentially three types of breadcrumbs - serverless (which is\r\nproject style), stateful project style (set through spaces settings),\r\nand classic style (the old breadcrumbs we've seen for years). Whilst\r\nserverless and stateful project style both use the project based style\r\nthe navigation trees are slightly different, so the breadcrumbs results\r\nare not identical [when they derive the \"nav\r\ncrumbs\"](9577aa980d/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/breadcrumbs.tsx (L55)
).\r\n\r\nHere \"project style\" will refer to serverless and stateful project\r\nstyle.\r\n\r\nIn these changes I've, for the most part, tried to refactor things so\r\nObservability solutions route their breadcrumbs through the\r\nobservability-shared `useBreadcrumbs` hook, this way the logic around\r\nproject style, adding an Observability crumb in classic etc is\r\nconsolidated in one place.\r\n\r\n[For several solutions `absolute` breadcrumbs are being\r\nused](9577aa980d/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/breadcrumbs.tsx (L46)
),\r\nand this means we'll roughly have the same breadcrumbs across the 3\r\nexperiences (bar Observability being prepended). Teams may want to\r\nrefine this going forward to pass curated breadcrumbs that take into\r\naccount the navigation derived \"nav crumbs\" (again, bearing in mind the\r\ntrees from serverless and project based chrome do differ), and not use\r\nabsolute mode. APM is an example of this at the moment. Right now this\r\nis an 8.16 bug though, so this aims to make things acceptable, but not\r\nnecessarily perfect.\r\n\r\n### APM\r\n\r\n- Project style chrome crumbs have been modelled off the serverless\r\nones. The navigation trees here are the same so this should be fine.\r\n\r\n### Infra\r\n\r\n- The `infra` `useBreadcrumbs` hook has been removed, it was only being\r\nused by logs. Logs now goes via the Observability shared hook using\r\n`classicOnly`.\r\n\r\n- Metrics (`useMetricsBreadcrumbs` hook) has been slightly amended to\r\nroute more of it's logic through the shared hook.\r\n\r\n### Logs explorer\r\n\r\n- Wasn't setting any nested breadcrumbs at the moment so the logic has\r\nbeen simplified to just set some classic crumbs, and defer the rest to\r\nthe nav crumbs via the shared hook.\r\n\r\n### Synthetics \r\n\r\n- Removed custom logic around prepending Observability, adding link\r\nhandlers etc in favour of the shared hook.\r\n\r\n\r\n### Alerts / rules / SLOs etc\r\n\r\n- Simple breadcrumb needs so these are mostly setting `classicOnly` and\r\ndeferring to the nav crumbs in project style.\r\n\r\nSeveral solutions have had their usage of the shared hook updated to\r\npass in the `serverless` plugin. This was missing before, so calls to\r\n`serverless.setBreadcrumbs` weren't explicitly happening.\r\n\r\n## Testing \r\n\r\n- Add the following to your `kibana.dev.yml`:\r\n\r\n```yml\r\nxpack.cloud.id: \"ftr_fake_cloud_id:aGVsbG8uY29tOjQ0MyRFUzEyM2FiYyRrYm4xMjNhYmM=\"\r\nxpack.cloud.base_url: \"https://cloud.elastic.co\"\r\n```\r\n\r\n- For testing stateful project style chrome you'll need to go to Stack\r\nManagement > Spaces and change the solution view:\r\n\r\n\r\n\r\n- Set the above to Classic to test classic breadcrumbs.\r\n\r\n- As a reviewer please check your solution against the 3 modes.\r\n\r\n## Comparison\r\n\r\nBefore these changes we'd see something like the following in APM:\r\n\r\n\r\n\r\nNow we'll see something like this in project style:\r\n\r\n","sha":"641d9159451447484f3940f0b1c17438472fea5c"}},"sourceBranch":"main","suggestedTargetBranches":["8.16","8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/196785","number":196785,"mergeCommit":{"message":"[Observability] Update breadcrumbs for observability project based navigation (#196785)\n\n~⚠️ I'm still putting out some fires with tests, but this is ready to\r\nstart being reviewed.~\r\n\r\n## Summary\r\n\r\nA continuation of https://github.com/elastic/kibana/pull/196169 for\r\nObservability (please read that PR description first).\r\n\r\nRelated: https://github.com/elastic/kibana/issues/192050\r\n\r\n## Overview of changes\r\n\r\nThere are essentially three types of breadcrumbs - serverless (which is\r\nproject style), stateful project style (set through spaces settings),\r\nand classic style (the old breadcrumbs we've seen for years). Whilst\r\nserverless and stateful project style both use the project based style\r\nthe navigation trees are slightly different, so the breadcrumbs results\r\nare not identical [when they derive the \"nav\r\ncrumbs\"](9577aa980d/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/breadcrumbs.tsx (L55)
).\r\n\r\nHere \"project style\" will refer to serverless and stateful project\r\nstyle.\r\n\r\nIn these changes I've, for the most part, tried to refactor things so\r\nObservability solutions route their breadcrumbs through the\r\nobservability-shared `useBreadcrumbs` hook, this way the logic around\r\nproject style, adding an Observability crumb in classic etc is\r\nconsolidated in one place.\r\n\r\n[For several solutions `absolute` breadcrumbs are being\r\nused](9577aa980d/packages/core/chrome/core-chrome-browser-internal/src/project_navigation/breadcrumbs.tsx (L46)
),\r\nand this means we'll roughly have the same breadcrumbs across the 3\r\nexperiences (bar Observability being prepended). Teams may want to\r\nrefine this going forward to pass curated breadcrumbs that take into\r\naccount the navigation derived \"nav crumbs\" (again, bearing in mind the\r\ntrees from serverless and project based chrome do differ), and not use\r\nabsolute mode. APM is an example of this at the moment. Right now this\r\nis an 8.16 bug though, so this aims to make things acceptable, but not\r\nnecessarily perfect.\r\n\r\n### APM\r\n\r\n- Project style chrome crumbs have been modelled off the serverless\r\nones. The navigation trees here are the same so this should be fine.\r\n\r\n### Infra\r\n\r\n- The `infra` `useBreadcrumbs` hook has been removed, it was only being\r\nused by logs. Logs now goes via the Observability shared hook using\r\n`classicOnly`.\r\n\r\n- Metrics (`useMetricsBreadcrumbs` hook) has been slightly amended to\r\nroute more of it's logic through the shared hook.\r\n\r\n### Logs explorer\r\n\r\n- Wasn't setting any nested breadcrumbs at the moment so the logic has\r\nbeen simplified to just set some classic crumbs, and defer the rest to\r\nthe nav crumbs via the shared hook.\r\n\r\n### Synthetics \r\n\r\n- Removed custom logic around prepending Observability, adding link\r\nhandlers etc in favour of the shared hook.\r\n\r\n\r\n### Alerts / rules / SLOs etc\r\n\r\n- Simple breadcrumb needs so these are mostly setting `classicOnly` and\r\ndeferring to the nav crumbs in project style.\r\n\r\nSeveral solutions have had their usage of the shared hook updated to\r\npass in the `serverless` plugin. This was missing before, so calls to\r\n`serverless.setBreadcrumbs` weren't explicitly happening.\r\n\r\n## Testing \r\n\r\n- Add the following to your `kibana.dev.yml`:\r\n\r\n```yml\r\nxpack.cloud.id: \"ftr_fake_cloud_id:aGVsbG8uY29tOjQ0MyRFUzEyM2FiYyRrYm4xMjNhYmM=\"\r\nxpack.cloud.base_url: \"https://cloud.elastic.co\"\r\n```\r\n\r\n- For testing stateful project style chrome you'll need to go to Stack\r\nManagement > Spaces and change the solution view:\r\n\r\n\r\n\r\n- Set the above to Classic to test classic breadcrumbs.\r\n\r\n- As a reviewer please check your solution against the 3 modes.\r\n\r\n## Comparison\r\n\r\nBefore these changes we'd see something like the following in APM:\r\n\r\n\r\n\r\nNow we'll see something like this in project style:\r\n\r\n","sha":"641d9159451447484f3940f0b1c17438472fea5c"}},{"branch":"8.16","label":"v8.16.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.x","label":"v8.17.0","branchLabelMappingKey":"^v8.17.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> Co-authored-by: Kerry Gallagher <kerry.gallagher@elastic.co>
This commit is contained in:
parent
07ea8ebd81
commit
d92ea8356c
38 changed files with 371 additions and 409 deletions
|
@ -76,7 +76,7 @@ export function BreadcrumbsContextProvider({ children }: { children: React.React
|
|||
};
|
||||
});
|
||||
|
||||
useBreadcrumbs(formattedBreadcrumbs, { serverless });
|
||||
useBreadcrumbs(formattedBreadcrumbs, { serverless, absoluteProjectStyleBreadcrumbs: false });
|
||||
|
||||
return <BreadcrumbsContext.Provider value={api}>{children}</BreadcrumbsContext.Provider>;
|
||||
}
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
import { useCurrentRoute } from '@kbn/typed-react-router-config';
|
||||
import { useContext, useEffect, useRef } from 'react';
|
||||
import { castArray } from 'lodash';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { Breadcrumb, BreadcrumbsContext } from './context';
|
||||
import { useKibanaEnvironmentContext } from '../kibana_environment_context/use_kibana_environment_context';
|
||||
import { useKibana } from '../kibana_context/use_kibana';
|
||||
|
||||
export function useBreadcrumb(
|
||||
callback: () => Breadcrumb | Breadcrumb[],
|
||||
|
@ -17,6 +19,9 @@ export function useBreadcrumb(
|
|||
options?: { omitRootOnServerless?: boolean; omitOnServerless?: boolean }
|
||||
) {
|
||||
const { isServerlessEnv } = useKibanaEnvironmentContext();
|
||||
const {
|
||||
services: { chrome },
|
||||
} = useKibana();
|
||||
const { omitRootOnServerless = false, omitOnServerless = false } = options || {};
|
||||
|
||||
const api = useContext(BreadcrumbsContext);
|
||||
|
@ -29,8 +34,11 @@ export function useBreadcrumb(
|
|||
|
||||
const matchedRoute = useRef(match?.route);
|
||||
|
||||
const chromeStyle = useObservable(chrome.getChromeStyle$());
|
||||
|
||||
useEffect(() => {
|
||||
if (isServerlessEnv && omitOnServerless) {
|
||||
const isProjectStyle = isServerlessEnv || chromeStyle === 'project';
|
||||
if (isProjectStyle && omitOnServerless) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -42,10 +50,9 @@ export function useBreadcrumb(
|
|||
|
||||
if (matchedRoute.current) {
|
||||
const breadcrumbs = castArray(callback());
|
||||
|
||||
api.set(
|
||||
matchedRoute.current,
|
||||
isServerlessEnv && omitRootOnServerless && breadcrumbs.length >= 1
|
||||
isProjectStyle && omitRootOnServerless && breadcrumbs.length >= 1
|
||||
? breadcrumbs.slice(1)
|
||||
: breadcrumbs
|
||||
);
|
||||
|
@ -57,5 +64,5 @@ export function useBreadcrumb(
|
|||
}
|
||||
};
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [match, ...fnDeps]);
|
||||
}, [match, chromeStyle, ...fnDeps]);
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ export function ExploratoryViewPage({
|
|||
}),
|
||||
},
|
||||
],
|
||||
{ app }
|
||||
{ app, classicOnly: true }
|
||||
);
|
||||
|
||||
const kbnUrlStateStorage = useSessionStorage
|
||||
|
|
|
@ -50,18 +50,15 @@ export const Page = ({ tabs = [], links = [] }: ContentTemplateProps) => {
|
|||
|
||||
const parentBreadcrumbResolver = useParentBreadcrumbResolver();
|
||||
const breadcrumbOptions = parentBreadcrumbResolver.getBreadcrumbOptions(asset.type);
|
||||
useMetricsBreadcrumbs(
|
||||
[
|
||||
{
|
||||
...breadcrumbOptions.link,
|
||||
text: breadcrumbOptions.text,
|
||||
},
|
||||
{
|
||||
text: asset.name,
|
||||
},
|
||||
],
|
||||
{ deeperContextServerless: true }
|
||||
);
|
||||
useMetricsBreadcrumbs([
|
||||
{
|
||||
...breadcrumbOptions.link,
|
||||
text: breadcrumbOptions.text,
|
||||
},
|
||||
{
|
||||
text: asset.name,
|
||||
},
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (trackOnlyOnce.current) {
|
||||
|
|
|
@ -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
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ChromeBreadcrumb } from '@kbn/core/public';
|
||||
import { useEffect } from 'react';
|
||||
import { useLinkProps } from '@kbn/observability-shared-plugin/public';
|
||||
import { observabilityTitle } from '../translations';
|
||||
import { useKibanaContextForPlugin } from './use_kibana';
|
||||
|
||||
type AppId = 'logs' | 'metrics';
|
||||
|
||||
export const useBreadcrumbs = (app: AppId, appTitle: string, extraCrumbs: ChromeBreadcrumb[]) => {
|
||||
const {
|
||||
services: { chrome },
|
||||
} = useKibanaContextForPlugin();
|
||||
|
||||
const observabilityLinkProps = useLinkProps({ app: 'observability-overview' });
|
||||
const appLinkProps = useLinkProps({ app });
|
||||
|
||||
useEffect(() => {
|
||||
const breadcrumbs = [
|
||||
{
|
||||
...observabilityLinkProps,
|
||||
text: observabilityTitle,
|
||||
},
|
||||
{
|
||||
...appLinkProps,
|
||||
text: appTitle,
|
||||
},
|
||||
...extraCrumbs,
|
||||
];
|
||||
|
||||
const docTitle = [...breadcrumbs].reverse().map((breadcrumb) => breadcrumb.text as string);
|
||||
|
||||
chrome.docTitle.change(docTitle);
|
||||
chrome.setBreadcrumbs(breadcrumbs);
|
||||
}, [appLinkProps, appTitle, chrome, extraCrumbs, observabilityLinkProps]);
|
||||
};
|
|
@ -6,10 +6,18 @@
|
|||
*/
|
||||
|
||||
import { ChromeBreadcrumb } from '@kbn/core/public';
|
||||
import { useBreadcrumbs } from './use_breadcrumbs';
|
||||
import { useBreadcrumbs, useLinkProps } from '@kbn/observability-shared-plugin/public';
|
||||
import { LOGS_APP } from '../../common/constants';
|
||||
import { logsTitle } from '../translations';
|
||||
|
||||
export const useLogsBreadcrumbs = (extraCrumbs: ChromeBreadcrumb[]) => {
|
||||
useBreadcrumbs(LOGS_APP, logsTitle, extraCrumbs);
|
||||
const appLinkProps = useLinkProps({ app: LOGS_APP });
|
||||
const breadcrumbs = [
|
||||
{
|
||||
...appLinkProps,
|
||||
text: logsTitle,
|
||||
},
|
||||
...extraCrumbs,
|
||||
];
|
||||
useBreadcrumbs(breadcrumbs, { classicOnly: true });
|
||||
};
|
||||
|
|
|
@ -5,42 +5,25 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { ChromeBreadcrumb } from '@kbn/core/public';
|
||||
import { useBreadcrumbs, useLinkProps } from '@kbn/observability-shared-plugin/public';
|
||||
import { METRICS_APP } from '../../common/constants';
|
||||
import { metricsTitle } from '../translations';
|
||||
import { useKibanaContextForPlugin } from './use_kibana';
|
||||
|
||||
export const useMetricsBreadcrumbs = (
|
||||
extraCrumbs: ChromeBreadcrumb[],
|
||||
options?: { deeperContextServerless: boolean }
|
||||
) => {
|
||||
export const useMetricsBreadcrumbs = (extraCrumbs: ChromeBreadcrumb[]) => {
|
||||
const {
|
||||
services: { serverless },
|
||||
} = useKibanaContextForPlugin();
|
||||
const appLinkProps = useLinkProps({ app: METRICS_APP });
|
||||
|
||||
const breadcrumbs = useMemo(
|
||||
() => [
|
||||
{
|
||||
...appLinkProps,
|
||||
text: metricsTitle,
|
||||
},
|
||||
...extraCrumbs,
|
||||
],
|
||||
[appLinkProps, extraCrumbs]
|
||||
);
|
||||
const breadcrumbs = [
|
||||
{
|
||||
...appLinkProps,
|
||||
text: metricsTitle,
|
||||
},
|
||||
...extraCrumbs,
|
||||
];
|
||||
|
||||
useBreadcrumbs(breadcrumbs);
|
||||
|
||||
useEffect(() => {
|
||||
// For deeper context breadcrumbs in serveless, the `serverless` plugin provides its own breadcrumb service.
|
||||
// https://docs.elastic.dev/kibana-dev-docs/serverless-project-navigation#breadcrumbs
|
||||
if (serverless && options?.deeperContextServerless) {
|
||||
// The initial path is already set in the breadcrumbs
|
||||
const [, ...serverlessBreadcrumbs] = breadcrumbs;
|
||||
serverless.setBreadcrumbs(serverlessBreadcrumbs);
|
||||
}
|
||||
}, [breadcrumbs, options?.deeperContextServerless, serverless]);
|
||||
useBreadcrumbs(breadcrumbs, { serverless });
|
||||
};
|
||||
|
|
|
@ -54,18 +54,15 @@ export const MetricDetailPage = () => {
|
|||
});
|
||||
|
||||
const breadcrumbOptions = parentBreadcrumbResolver.getBreadcrumbOptions(nodeType);
|
||||
useMetricsBreadcrumbs(
|
||||
[
|
||||
{
|
||||
...breadcrumbOptions.link,
|
||||
text: breadcrumbOptions.text,
|
||||
},
|
||||
{
|
||||
text: name,
|
||||
},
|
||||
],
|
||||
{ deeperContextServerless: true }
|
||||
);
|
||||
useMetricsBreadcrumbs([
|
||||
{
|
||||
...breadcrumbOptions.link,
|
||||
text: breadcrumbOptions.text,
|
||||
},
|
||||
{
|
||||
text: name,
|
||||
},
|
||||
]);
|
||||
|
||||
const [sideNav, setSideNav] = useState<NavItem[]>([]);
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ export const metricsTitle = i18n.translate('xpack.infra.header.infrastructureTit
|
|||
});
|
||||
|
||||
export const inventoryTitle = i18n.translate('xpack.infra.metrics.infrastructureInventoryTitle', {
|
||||
defaultMessage: 'Infrastructure Inventory',
|
||||
defaultMessage: 'Infrastructure inventory',
|
||||
});
|
||||
|
||||
export const metricsExplorerTitle = i18n.translate('xpack.infra.metrics.metricsExplorerTitle', {
|
||||
|
|
|
@ -93,6 +93,7 @@ export function AlertDetails() {
|
|||
triggersActionsUi: { ruleTypeRegistry },
|
||||
observabilityAIAssistant,
|
||||
uiSettings,
|
||||
serverless,
|
||||
} = useKibana().services;
|
||||
|
||||
const { search } = useLocation();
|
||||
|
@ -158,20 +159,23 @@ export function AlertDetails() {
|
|||
}
|
||||
}, [alertDetail, ruleTypeRegistry]);
|
||||
|
||||
useBreadcrumbs([
|
||||
{
|
||||
href: http.basePath.prepend(paths.observability.alerts),
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.alertsLinkText', {
|
||||
defaultMessage: 'Alerts',
|
||||
}),
|
||||
deepLinkId: 'observability-overview:alerts',
|
||||
},
|
||||
{
|
||||
text: alertDetail
|
||||
? getPageTitle(alertDetail.formatted.fields[ALERT_RULE_CATEGORY])
|
||||
: defaultBreadcrumb,
|
||||
},
|
||||
]);
|
||||
useBreadcrumbs(
|
||||
[
|
||||
{
|
||||
href: http.basePath.prepend(paths.observability.alerts),
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.alertsLinkText', {
|
||||
defaultMessage: 'Alerts',
|
||||
}),
|
||||
deepLinkId: 'observability-overview:alerts',
|
||||
},
|
||||
{
|
||||
text: alertDetail
|
||||
? getPageTitle(alertDetail.formatted.fields[ALERT_RULE_CATEGORY])
|
||||
: defaultBreadcrumb,
|
||||
},
|
||||
],
|
||||
{ serverless }
|
||||
);
|
||||
|
||||
const onUntrackAlert = () => {
|
||||
setAlertStatus(ALERT_STATUS_UNTRACKED);
|
||||
|
|
|
@ -159,13 +159,18 @@ function InternalAlertsPage() {
|
|||
[alertSearchBarStateProps.rangeFrom, alertSearchBarStateProps.rangeTo, bucketSize, esQuery]
|
||||
);
|
||||
|
||||
useBreadcrumbs([
|
||||
useBreadcrumbs(
|
||||
[
|
||||
{
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.alertsLinkText', {
|
||||
defaultMessage: 'Alerts',
|
||||
}),
|
||||
},
|
||||
],
|
||||
{
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.alertsLinkText', {
|
||||
defaultMessage: 'Alerts',
|
||||
}),
|
||||
},
|
||||
]);
|
||||
classicOnly: true,
|
||||
}
|
||||
);
|
||||
|
||||
async function loadRuleStats() {
|
||||
setRuleStatsLoading(true);
|
||||
|
|
|
@ -56,13 +56,18 @@ export function OverviewPage() {
|
|||
|
||||
const { ObservabilityPageTemplate, observabilityRuleTypeRegistry } = usePluginContext();
|
||||
|
||||
useBreadcrumbs([
|
||||
useBreadcrumbs(
|
||||
[
|
||||
{
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.overviewLinkText', {
|
||||
defaultMessage: 'Overview',
|
||||
}),
|
||||
},
|
||||
],
|
||||
{
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.overviewLinkText', {
|
||||
defaultMessage: 'Overview',
|
||||
}),
|
||||
},
|
||||
]);
|
||||
classicOnly: true,
|
||||
}
|
||||
);
|
||||
|
||||
const { data: newsFeed } = useFetcher(
|
||||
() => getNewsFeed({ http, kibanaVersion }),
|
||||
|
|
|
@ -61,6 +61,7 @@ export function RuleDetailsPage() {
|
|||
getRuleDefinition: RuleDefinition,
|
||||
getRuleStatusPanel: RuleStatusPanel,
|
||||
},
|
||||
serverless,
|
||||
} = useKibana().services;
|
||||
const { ObservabilityPageTemplate } = usePluginContext();
|
||||
|
||||
|
@ -72,24 +73,27 @@ export function RuleDetailsPage() {
|
|||
filterByRuleTypeIds: filteredRuleTypes,
|
||||
});
|
||||
|
||||
useBreadcrumbs([
|
||||
{
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.alertsLinkText', {
|
||||
defaultMessage: 'Alerts',
|
||||
}),
|
||||
href: basePath.prepend(paths.observability.alerts),
|
||||
deepLinkId: 'observability-overview:alerts',
|
||||
},
|
||||
{
|
||||
href: basePath.prepend(paths.observability.rules),
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.rulesLinkText', {
|
||||
defaultMessage: 'Rules',
|
||||
}),
|
||||
},
|
||||
{
|
||||
text: rule && rule.name,
|
||||
},
|
||||
]);
|
||||
useBreadcrumbs(
|
||||
[
|
||||
{
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.alertsLinkText', {
|
||||
defaultMessage: 'Alerts',
|
||||
}),
|
||||
href: basePath.prepend(paths.observability.alerts),
|
||||
deepLinkId: 'observability-overview:alerts',
|
||||
},
|
||||
{
|
||||
href: basePath.prepend(paths.observability.rules),
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.rulesLinkText', {
|
||||
defaultMessage: 'Rules',
|
||||
}),
|
||||
},
|
||||
{
|
||||
text: rule && rule.name,
|
||||
},
|
||||
],
|
||||
{ serverless }
|
||||
);
|
||||
|
||||
const [activeTabId, setActiveTabId] = useState<TabId>(() => {
|
||||
const searchParams = new URLSearchParams(search);
|
||||
|
|
|
@ -42,6 +42,7 @@ export function RulesPage({ activeTab = RULES_TAB_NAME }: RulesPageProps) {
|
|||
getAddRuleFlyout: AddRuleFlyout,
|
||||
getRulesSettingsLink: RulesSettingsLink,
|
||||
},
|
||||
serverless,
|
||||
} = useKibana().services;
|
||||
const { ObservabilityPageTemplate } = usePluginContext();
|
||||
const history = useHistory();
|
||||
|
@ -50,20 +51,23 @@ export function RulesPage({ activeTab = RULES_TAB_NAME }: RulesPageProps) {
|
|||
const [addRuleFlyoutVisibility, setAddRuleFlyoutVisibility] = useState(false);
|
||||
const [stateRefresh, setRefresh] = useState(new Date());
|
||||
|
||||
useBreadcrumbs([
|
||||
{
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.alertsLinkText', {
|
||||
defaultMessage: 'Alerts',
|
||||
}),
|
||||
href: http.basePath.prepend('/app/observability/alerts'),
|
||||
deepLinkId: 'observability-overview:alerts',
|
||||
},
|
||||
{
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.rulesLinkText', {
|
||||
defaultMessage: 'Rules',
|
||||
}),
|
||||
},
|
||||
]);
|
||||
useBreadcrumbs(
|
||||
[
|
||||
{
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.alertsLinkText', {
|
||||
defaultMessage: 'Alerts',
|
||||
}),
|
||||
href: http.basePath.prepend('/app/observability/alerts'),
|
||||
deepLinkId: 'observability-overview:alerts',
|
||||
},
|
||||
{
|
||||
text: i18n.translate('xpack.observability.breadcrumbs.rulesLinkText', {
|
||||
defaultMessage: 'Rules',
|
||||
}),
|
||||
},
|
||||
],
|
||||
{ serverless }
|
||||
);
|
||||
|
||||
const filteredRuleTypes = useGetFilteredRuleTypes();
|
||||
const {
|
||||
|
|
|
@ -21,26 +21,17 @@ import {
|
|||
} from '../../state_machines/observability_logs_explorer/src';
|
||||
import { LazyOriginInterpreter } from '../../state_machines/origin_interpreter/src/lazy_component';
|
||||
import { ObservabilityLogsExplorerHistory } from '../../types';
|
||||
import { noBreadcrumbs, useBreadcrumbs } from '../../utils/breadcrumbs';
|
||||
import { useBreadcrumbs } from '../../utils/breadcrumbs';
|
||||
import { useKbnUrlStateStorageFromRouterContext } from '../../utils/kbn_url_state_context';
|
||||
import { useKibanaContextForPlugin } from '../../utils/use_kibana';
|
||||
|
||||
export const ObservabilityLogsExplorerMainRoute = () => {
|
||||
const { services } = useKibanaContextForPlugin();
|
||||
const {
|
||||
logsExplorer,
|
||||
serverless,
|
||||
chrome,
|
||||
notifications,
|
||||
appParams,
|
||||
analytics,
|
||||
i18n,
|
||||
theme,
|
||||
logsDataAccess,
|
||||
} = services;
|
||||
const { logsExplorer, notifications, appParams, analytics, i18n, theme, logsDataAccess } =
|
||||
services;
|
||||
const { history } = appParams;
|
||||
|
||||
useBreadcrumbs(noBreadcrumbs, chrome, serverless);
|
||||
useBreadcrumbs();
|
||||
|
||||
const urlStateStorageContainer = useKbnUrlStateStorageFromRouterContext();
|
||||
|
||||
|
|
|
@ -5,71 +5,27 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { EuiBreadcrumb } from '@elastic/eui';
|
||||
import type { ChromeStart } from '@kbn/core-chrome-browser';
|
||||
import {
|
||||
LOGS_APP_ID,
|
||||
OBSERVABILITY_LOGS_EXPLORER_APP_ID,
|
||||
OBSERVABILITY_OVERVIEW_APP_ID,
|
||||
} from '@kbn/deeplinks-observability';
|
||||
import { LOGS_APP_ID, OBSERVABILITY_LOGS_EXPLORER_APP_ID } from '@kbn/deeplinks-observability';
|
||||
import { useLinkProps } from '@kbn/observability-shared-plugin/public';
|
||||
import type { ServerlessPluginStart } from '@kbn/serverless/public';
|
||||
import { useEffect } from 'react';
|
||||
import {
|
||||
logsExplorerAppTitle,
|
||||
logsAppTitle,
|
||||
observabilityAppTitle,
|
||||
} from '../../common/translations';
|
||||
import { useMemo } from 'react';
|
||||
import { useBreadcrumbs as observabilityUseBreadcrumbs } from '@kbn/observability-shared-plugin/public';
|
||||
import { logsExplorerAppTitle, logsAppTitle } from '../../common/translations';
|
||||
|
||||
export const useBreadcrumbs = (
|
||||
breadcrumbs: EuiBreadcrumb[],
|
||||
chromeService: ChromeStart,
|
||||
serverlessService?: ServerlessPluginStart
|
||||
) => {
|
||||
const observabilityLinkProps = useLinkProps({ app: OBSERVABILITY_OVERVIEW_APP_ID });
|
||||
export const useBreadcrumbs = () => {
|
||||
const logsLinkProps = useLinkProps({ app: LOGS_APP_ID });
|
||||
const logsExplorerLinkProps = useLinkProps({ app: OBSERVABILITY_LOGS_EXPLORER_APP_ID });
|
||||
const classicCrumbs = useMemo(() => {
|
||||
return [
|
||||
{
|
||||
text: logsAppTitle,
|
||||
...logsLinkProps,
|
||||
},
|
||||
{
|
||||
text: logsExplorerAppTitle,
|
||||
...logsExplorerLinkProps,
|
||||
},
|
||||
];
|
||||
}, [logsExplorerLinkProps, logsLinkProps]);
|
||||
|
||||
useEffect(() => {
|
||||
setBreadcrumbs(
|
||||
serverlessService
|
||||
? breadcrumbs
|
||||
: [
|
||||
{
|
||||
text: observabilityAppTitle,
|
||||
...observabilityLinkProps,
|
||||
},
|
||||
{
|
||||
text: logsAppTitle,
|
||||
...logsLinkProps,
|
||||
},
|
||||
{
|
||||
text: logsExplorerAppTitle,
|
||||
...logsExplorerLinkProps,
|
||||
},
|
||||
...breadcrumbs,
|
||||
],
|
||||
chromeService,
|
||||
serverlessService
|
||||
);
|
||||
}, [breadcrumbs, chromeService, serverlessService]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
observabilityUseBreadcrumbs(classicCrumbs, { classicOnly: true });
|
||||
};
|
||||
|
||||
export function setBreadcrumbs(
|
||||
breadcrumbs: EuiBreadcrumb[],
|
||||
chromeService: ChromeStart,
|
||||
serverlessService?: ServerlessPluginStart
|
||||
) {
|
||||
chromeService.docTitle.change(getDocTitle(breadcrumbs));
|
||||
if (serverlessService) {
|
||||
serverlessService.setBreadcrumbs(breadcrumbs);
|
||||
} else if (chromeService) {
|
||||
chromeService.setBreadcrumbs(breadcrumbs);
|
||||
}
|
||||
}
|
||||
|
||||
export function getDocTitle(breadcrumbs: EuiBreadcrumb[]) {
|
||||
return breadcrumbs.map(({ text }) => text as string).reverse();
|
||||
}
|
||||
|
||||
export const noBreadcrumbs: EuiBreadcrumb[] = [];
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
"kbn_references": [
|
||||
"@kbn/config-schema",
|
||||
"@kbn/core",
|
||||
"@kbn/core-chrome-browser",
|
||||
"@kbn/core-mount-utils-browser-internal",
|
||||
"@kbn/core-notifications-browser",
|
||||
"@kbn/data-plugin",
|
||||
|
|
|
@ -11,12 +11,18 @@ import { MemoryRouter } from 'react-router-dom';
|
|||
import { CoreStart } from '@kbn/core/public';
|
||||
import { createKibanaReactContext } from '@kbn/kibana-react-plugin/public';
|
||||
import { useBreadcrumbs } from './use_breadcrumbs';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { ChromeStyle } from '@kbn/core-chrome-browser';
|
||||
|
||||
const setBreadcrumbs = jest.fn();
|
||||
const setTitle = jest.fn();
|
||||
const kibanaServices = {
|
||||
application: { getUrlForApp: () => {}, navigateToApp: () => {} },
|
||||
chrome: { setBreadcrumbs, docTitle: { change: setTitle } },
|
||||
chrome: {
|
||||
setBreadcrumbs,
|
||||
docTitle: { change: setTitle },
|
||||
getChromeStyle$: () => new BehaviorSubject<ChromeStyle>('classic').asObservable(),
|
||||
},
|
||||
uiSettings: { get: () => true },
|
||||
settings: { client: { get: () => true } },
|
||||
} as unknown as Partial<CoreStart>;
|
||||
|
@ -61,9 +67,15 @@ describe('useBreadcrumbs', () => {
|
|||
it('sets the overview breadcrumb', () => {
|
||||
renderHook(() => useBreadcrumbs([]), { wrapper: Wrapper });
|
||||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([
|
||||
{ href: '/overview', onClick: expect.any(Function), text: 'Observability' },
|
||||
]);
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith(
|
||||
[{ href: '/overview', onClick: expect.any(Function), text: 'Observability' }],
|
||||
{
|
||||
project: {
|
||||
absolute: true,
|
||||
value: [{ href: '/overview', onClick: expect.any(Function), text: 'Observability' }],
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('sets the overview title', () => {
|
||||
|
@ -86,17 +98,29 @@ describe('useBreadcrumbs', () => {
|
|||
{ wrapper: Wrapper }
|
||||
);
|
||||
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith([
|
||||
{ href: '/overview', onClick: expect.any(Function), text: 'Observability' },
|
||||
expect(setBreadcrumbs).toHaveBeenCalledWith(
|
||||
[
|
||||
{ href: '/overview', onClick: expect.any(Function), text: 'Observability' },
|
||||
{
|
||||
href: '/one',
|
||||
onClick: expect.any(Function),
|
||||
text: 'One',
|
||||
},
|
||||
{
|
||||
text: 'Two',
|
||||
},
|
||||
],
|
||||
{
|
||||
href: '/one',
|
||||
onClick: expect.any(Function),
|
||||
text: 'One',
|
||||
},
|
||||
{
|
||||
text: 'Two',
|
||||
},
|
||||
]);
|
||||
project: {
|
||||
absolute: true,
|
||||
value: [
|
||||
{ href: '/overview', onClick: expect.any(Function), text: 'Observability' },
|
||||
{ href: '/one', onClick: expect.any(Function), text: 'One' },
|
||||
{ text: 'Two' },
|
||||
],
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
it('sets the title', () => {
|
||||
|
|
|
@ -11,8 +11,16 @@ import { MouseEvent, useEffect, useMemo } from 'react';
|
|||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { ChromeBreadcrumbsAppendExtension } from '@kbn/core-chrome-browser';
|
||||
import type { ServerlessPluginStart } from '@kbn/serverless/public';
|
||||
import useObservable from 'react-use/lib/useObservable';
|
||||
import { useQueryParams } from './use_query_params';
|
||||
|
||||
const OBSERVABILITY_TEXT = i18n.translate(
|
||||
'xpack.observabilityShared.breadcrumbs.observabilityLinkText',
|
||||
{
|
||||
defaultMessage: 'Observability',
|
||||
}
|
||||
);
|
||||
|
||||
function addClickHandlers(
|
||||
breadcrumbs: ChromeBreadcrumb[],
|
||||
navigateToHref?: (url: string) => Promise<void>
|
||||
|
@ -33,23 +41,49 @@ function addClickHandlers(
|
|||
}
|
||||
|
||||
function getTitleFromBreadCrumbs(breadcrumbs: ChromeBreadcrumb[]) {
|
||||
return breadcrumbs.map(({ text }) => text?.toString() ?? '').reverse();
|
||||
return breadcrumbs
|
||||
.map(({ text }) => text?.toString() ?? '')
|
||||
.reverse()
|
||||
.concat([OBSERVABILITY_TEXT]);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* By default the breadcrumbs will be passed to either serverless.setBreadcrumbs or chrome.setBreadcrumbs depending on the
|
||||
* environment. The breadcrumbs will *also* be passed to the project style breadcrumbs for stateful project style. We will use "project style"
|
||||
* here to refer to serverless chrome and stateful project style chrome. Classic refers to stateful classic chrome.
|
||||
*
|
||||
* Project style breadcrumbs add a root crumb ("deployment" etc) and "nav crumbs" which are derived from the navigation structure. By default
|
||||
* the "absolute" mode is used which means the breadcrumbs passed here will omit the navigation derived "nav crumbs". You can pass
|
||||
* absoluteProjectStyleBreadcrumbs: false to include the 'smart' "nav crumbs".
|
||||
*
|
||||
* In classic mode (not project style) the 'Observability' crumb is added.
|
||||
*
|
||||
* You can also pass classicOnly to only set breadrumbs in the classic chrome context. This can be useful if your solution just wants to defer all project style crumbs to the "nav crumbs".
|
||||
*/
|
||||
export const useBreadcrumbs = (
|
||||
extraCrumbs: ChromeBreadcrumb[],
|
||||
options?: {
|
||||
app?: { id: string; label: string };
|
||||
breadcrumbsAppendExtension?: ChromeBreadcrumbsAppendExtension;
|
||||
serverless?: ServerlessPluginStart;
|
||||
absoluteProjectStyleBreadcrumbs?: boolean;
|
||||
classicOnly?: boolean;
|
||||
}
|
||||
) => {
|
||||
const params = useQueryParams();
|
||||
const { app, breadcrumbsAppendExtension, serverless } = options ?? {};
|
||||
const absolute = options?.absoluteProjectStyleBreadcrumbs === false ? false : true;
|
||||
const classicOnly = options?.classicOnly ?? false;
|
||||
|
||||
const {
|
||||
services: {
|
||||
chrome: { docTitle, setBreadcrumbs: chromeSetBreadcrumbs, setBreadcrumbsAppendExtension },
|
||||
chrome: {
|
||||
docTitle,
|
||||
setBreadcrumbs: chromeSetBreadcrumbs,
|
||||
setBreadcrumbsAppendExtension,
|
||||
getChromeStyle$,
|
||||
},
|
||||
application: { getUrlForApp, navigateToUrl },
|
||||
},
|
||||
} = useKibana<{
|
||||
|
@ -58,11 +92,27 @@ export const useBreadcrumbs = (
|
|||
}>();
|
||||
const setTitle = docTitle.change;
|
||||
const appPath = getUrlForApp(app?.id ?? 'observability-overview') ?? '';
|
||||
const chromeStyle = useObservable(getChromeStyle$());
|
||||
|
||||
const setBreadcrumbs = useMemo(
|
||||
() => serverless?.setBreadcrumbs ?? chromeSetBreadcrumbs,
|
||||
[serverless, chromeSetBreadcrumbs]
|
||||
);
|
||||
const setBreadcrumbs = useMemo(() => {
|
||||
if (!serverless?.setBreadcrumbs) {
|
||||
return (breadcrumbs: ChromeBreadcrumb[]) =>
|
||||
chromeSetBreadcrumbs(
|
||||
breadcrumbs,
|
||||
!classicOnly
|
||||
? {
|
||||
project: {
|
||||
value: breadcrumbs,
|
||||
absolute,
|
||||
},
|
||||
}
|
||||
: undefined
|
||||
);
|
||||
}
|
||||
if (!classicOnly)
|
||||
return (breadcrumbs: ChromeBreadcrumb[]) =>
|
||||
serverless?.setBreadcrumbs(breadcrumbs, { absolute });
|
||||
}, [serverless, classicOnly, absolute, chromeSetBreadcrumbs]);
|
||||
|
||||
useEffect(() => {
|
||||
if (breadcrumbsAppendExtension) {
|
||||
|
@ -76,15 +126,12 @@ export const useBreadcrumbs = (
|
|||
}, [breadcrumbsAppendExtension, setBreadcrumbsAppendExtension]);
|
||||
|
||||
useEffect(() => {
|
||||
const breadcrumbs = serverless
|
||||
const isProjectStyle = serverless || chromeStyle === 'project';
|
||||
const breadcrumbs = isProjectStyle
|
||||
? extraCrumbs
|
||||
: [
|
||||
{
|
||||
text:
|
||||
app?.label ??
|
||||
i18n.translate('xpack.observabilityShared.breadcrumbs.observabilityLinkText', {
|
||||
defaultMessage: 'Observability',
|
||||
}),
|
||||
text: app?.label ?? OBSERVABILITY_TEXT,
|
||||
href: appPath + '/overview',
|
||||
},
|
||||
...extraCrumbs,
|
||||
|
@ -94,11 +141,12 @@ export const useBreadcrumbs = (
|
|||
setBreadcrumbs(addClickHandlers(breadcrumbs, navigateToUrl));
|
||||
}
|
||||
if (setTitle) {
|
||||
setTitle(getTitleFromBreadCrumbs(breadcrumbs));
|
||||
setTitle(getTitleFromBreadCrumbs(extraCrumbs));
|
||||
}
|
||||
}, [
|
||||
app?.label,
|
||||
appPath,
|
||||
chromeStyle,
|
||||
extraCrumbs,
|
||||
navigateToUrl,
|
||||
params,
|
||||
|
|
|
@ -40,6 +40,7 @@ export function SloDetailsPage() {
|
|||
application: { navigateToUrl },
|
||||
http: { basePath },
|
||||
observabilityAIAssistant,
|
||||
serverless,
|
||||
} = useKibana().services;
|
||||
const { ObservabilityPageTemplate } = usePluginContext();
|
||||
const { hasAtLeast } = useLicense();
|
||||
|
@ -105,7 +106,7 @@ export function SloDetailsPage() {
|
|||
}
|
||||
}, [onPageReady, slo, isLoading]);
|
||||
|
||||
useBreadcrumbs(getBreadcrumbs(basePath, slo));
|
||||
useBreadcrumbs(getBreadcrumbs(basePath, slo), { serverless });
|
||||
|
||||
const isSloNotFound = !isLoading && slo === undefined;
|
||||
if (isSloNotFound) {
|
||||
|
|
|
@ -22,6 +22,7 @@ export function SloEditPage() {
|
|||
const {
|
||||
application: { navigateToUrl },
|
||||
http: { basePath },
|
||||
serverless,
|
||||
} = useKibana().services;
|
||||
const { sloId } = useParams<{ sloId: string | undefined }>();
|
||||
|
||||
|
@ -32,32 +33,35 @@ export function SloEditPage() {
|
|||
const hasRightLicense = hasAtLeast('platinum');
|
||||
const { data: slo } = useFetchSloDetails({ sloId });
|
||||
|
||||
useBreadcrumbs([
|
||||
{
|
||||
href: basePath.prepend(paths.slos),
|
||||
text: i18n.translate('xpack.slo.breadcrumbs.sloLabel', {
|
||||
defaultMessage: 'SLOs',
|
||||
}),
|
||||
deepLinkId: 'slo',
|
||||
},
|
||||
...(!!slo
|
||||
? [
|
||||
{
|
||||
href: basePath.prepend(paths.sloDetails(slo!.id)),
|
||||
text: slo!.name,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
text: slo
|
||||
? i18n.translate('xpack.slo.breadcrumbs.sloEditLabel', {
|
||||
defaultMessage: 'Edit',
|
||||
})
|
||||
: i18n.translate('xpack.slo.breadcrumbs.sloCreateLabel', {
|
||||
defaultMessage: 'Create',
|
||||
}),
|
||||
},
|
||||
]);
|
||||
useBreadcrumbs(
|
||||
[
|
||||
{
|
||||
href: basePath.prepend(paths.slos),
|
||||
text: i18n.translate('xpack.slo.breadcrumbs.sloLabel', {
|
||||
defaultMessage: 'SLOs',
|
||||
}),
|
||||
deepLinkId: 'slo',
|
||||
},
|
||||
...(!!slo
|
||||
? [
|
||||
{
|
||||
href: basePath.prepend(paths.sloDetails(slo!.id)),
|
||||
text: slo!.name,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
{
|
||||
text: slo
|
||||
? i18n.translate('xpack.slo.breadcrumbs.sloEditLabel', {
|
||||
defaultMessage: 'Edit',
|
||||
})
|
||||
: i18n.translate('xpack.slo.breadcrumbs.sloCreateLabel', {
|
||||
defaultMessage: 'Create',
|
||||
}),
|
||||
},
|
||||
],
|
||||
{ serverless }
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (hasRightLicense === false || permissions?.hasAllReadRequested === false) {
|
||||
|
|
|
@ -23,26 +23,30 @@ import { OutdatedSloSearchBar } from './outdated_slo_search_bar';
|
|||
export function SlosOutdatedDefinitions() {
|
||||
const {
|
||||
http: { basePath },
|
||||
serverless,
|
||||
} = useKibana().services;
|
||||
|
||||
const { data: permissions } = usePermissions();
|
||||
const { ObservabilityPageTemplate } = usePluginContext();
|
||||
const { hasAtLeast } = useLicense();
|
||||
|
||||
useBreadcrumbs([
|
||||
{
|
||||
href: basePath.prepend(paths.slos),
|
||||
text: i18n.translate('xpack.slo.breadcrumbs.slosLinkText', {
|
||||
defaultMessage: 'SLOs',
|
||||
}),
|
||||
deepLinkId: 'slo',
|
||||
},
|
||||
{
|
||||
text: i18n.translate('xpack.slo.breadcrumbs.slosOutdatedDefinitions', {
|
||||
defaultMessage: 'Outdated SLO Definitions',
|
||||
}),
|
||||
},
|
||||
]);
|
||||
useBreadcrumbs(
|
||||
[
|
||||
{
|
||||
href: basePath.prepend(paths.slos),
|
||||
text: i18n.translate('xpack.slo.breadcrumbs.slosLinkText', {
|
||||
defaultMessage: 'SLOs',
|
||||
}),
|
||||
deepLinkId: 'slo',
|
||||
},
|
||||
{
|
||||
text: i18n.translate('xpack.slo.breadcrumbs.slosOutdatedDefinitions', {
|
||||
defaultMessage: 'Outdated SLO Definitions',
|
||||
}),
|
||||
},
|
||||
],
|
||||
{ serverless }
|
||||
);
|
||||
|
||||
const [search, setSearch] = useState<string>('');
|
||||
const [activePage, setActivePage] = useState<number>(0);
|
||||
|
|
|
@ -16,17 +16,21 @@ import { HeaderMenu } from '../../components/header_menu/header_menu';
|
|||
export function SloSettingsPage() {
|
||||
const {
|
||||
http: { basePath },
|
||||
serverless,
|
||||
} = useKibana().services;
|
||||
const { ObservabilityPageTemplate } = usePluginContext();
|
||||
|
||||
useBreadcrumbs([
|
||||
{
|
||||
href: basePath.prepend(paths.slosSettings),
|
||||
text: i18n.translate('xpack.slo.breadcrumbs.slosSettingsText', {
|
||||
defaultMessage: 'SLOs Settings',
|
||||
}),
|
||||
},
|
||||
]);
|
||||
useBreadcrumbs(
|
||||
[
|
||||
{
|
||||
href: basePath.prepend(paths.slosSettings),
|
||||
text: i18n.translate('xpack.slo.breadcrumbs.slosSettingsText', {
|
||||
defaultMessage: 'SLOs Settings',
|
||||
}),
|
||||
},
|
||||
],
|
||||
{ serverless }
|
||||
);
|
||||
|
||||
return (
|
||||
<ObservabilityPageTemplate
|
||||
|
|
|
@ -29,6 +29,7 @@ export function SlosPage() {
|
|||
const {
|
||||
application: { navigateToUrl },
|
||||
http: { basePath },
|
||||
serverless,
|
||||
} = useKibana().services;
|
||||
const { ObservabilityPageTemplate } = usePluginContext();
|
||||
const { hasAtLeast } = useLicense();
|
||||
|
@ -37,15 +38,18 @@ export function SlosPage() {
|
|||
const { isLoading, isError, data: sloList } = useFetchSloList({ perPage: 0 });
|
||||
const { total } = sloList ?? { total: 0 };
|
||||
|
||||
useBreadcrumbs([
|
||||
{
|
||||
href: basePath.prepend(paths.slos),
|
||||
text: i18n.translate('xpack.slo.breadcrumbs.slosLinkText', {
|
||||
defaultMessage: 'SLOs',
|
||||
}),
|
||||
deepLinkId: 'slo',
|
||||
},
|
||||
]);
|
||||
useBreadcrumbs(
|
||||
[
|
||||
{
|
||||
href: basePath.prepend(paths.slos),
|
||||
text: i18n.translate('xpack.slo.breadcrumbs.slosLinkText', {
|
||||
defaultMessage: 'SLOs',
|
||||
}),
|
||||
deepLinkId: 'slo',
|
||||
},
|
||||
],
|
||||
{ serverless }
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if ((!isLoading && total === 0) || hasAtLeast('platinum') === false || isError) {
|
||||
|
|
|
@ -38,7 +38,6 @@ export interface SyntheticsAppProps {
|
|||
setBadge: (badge?: ChromeBadge) => void;
|
||||
renderGlobalHelpControls(): void;
|
||||
commonlyUsedRanges: CommonlyUsedDateRange[];
|
||||
setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void;
|
||||
appMountParameters: AppMountParameters;
|
||||
isDev: boolean;
|
||||
isServerless: boolean;
|
||||
|
@ -89,7 +88,6 @@ export const SyntheticsSettingsContextProvider: React.FC<PropsWithChildren<Synth
|
|||
isLogsAvailable,
|
||||
commonlyUsedRanges,
|
||||
isDev,
|
||||
setBreadcrumbs,
|
||||
isServerless,
|
||||
} = props;
|
||||
|
||||
|
@ -110,7 +108,6 @@ export const SyntheticsSettingsContextProvider: React.FC<PropsWithChildren<Synth
|
|||
commonlyUsedRanges,
|
||||
dateRangeStart: dateRangeStart ?? DATE_RANGE_START,
|
||||
dateRangeEnd: dateRangeEnd ?? DATE_RANGE_END,
|
||||
setBreadcrumbs,
|
||||
isServerless,
|
||||
};
|
||||
}, [
|
||||
|
@ -123,7 +120,6 @@ export const SyntheticsSettingsContextProvider: React.FC<PropsWithChildren<Synth
|
|||
dateRangeStart,
|
||||
dateRangeEnd,
|
||||
commonlyUsedRanges,
|
||||
setBreadcrumbs,
|
||||
isServerless,
|
||||
]);
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ export const SyntheticsSharedContext: React.FC<
|
|||
unifiedSearch: startPlugins.unifiedSearch,
|
||||
embeddable: startPlugins.embeddable,
|
||||
slo: startPlugins.slo,
|
||||
serverless: startPlugins.serverless,
|
||||
}}
|
||||
>
|
||||
<EuiThemeProvider darkMode={darkMode}>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { coreMock } from '@kbn/core/public/mocks';
|
||||
import { ChromeBreadcrumb } from '@kbn/core/public';
|
||||
import { render } from '../utils/testing';
|
||||
import React from 'react';
|
||||
|
@ -18,6 +19,8 @@ import {
|
|||
} from '../utils/url_params/get_supported_url_params';
|
||||
import { makeBaseBreadcrumb, useBreadcrumbs } from './use_breadcrumbs';
|
||||
import { SyntheticsSettingsContext } from '../contexts';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { ChromeStyle } from '@kbn/core-chrome-browser';
|
||||
|
||||
describe('useBreadcrumbs', () => {
|
||||
it('sets the given breadcrumbs', () => {
|
||||
|
@ -71,9 +74,10 @@ describe('useBreadcrumbs', () => {
|
|||
const urlParams: SyntheticsUrlParams = getSupportedUrlParams({});
|
||||
expect(JSON.stringify(getBreadcrumbs())).toEqual(
|
||||
JSON.stringify(
|
||||
makeBaseBreadcrumb('/app/synthetics', '/app/observability', urlParams, false).concat(
|
||||
expectedCrumbs
|
||||
)
|
||||
[
|
||||
{ text: 'Observability', href: '/app/observability/overview' },
|
||||
...makeBaseBreadcrumb('/app/synthetics', urlParams),
|
||||
].concat(expectedCrumbs)
|
||||
)
|
||||
);
|
||||
});
|
||||
|
@ -84,6 +88,8 @@ const mockCore: () => [() => ChromeBreadcrumb[], any] = () => {
|
|||
const get = () => {
|
||||
return breadcrumbObj;
|
||||
};
|
||||
const defaultCoreMock = coreMock.createStart();
|
||||
|
||||
const core = {
|
||||
application: {
|
||||
getUrlForApp: (app: string) =>
|
||||
|
@ -91,6 +97,8 @@ const mockCore: () => [() => ChromeBreadcrumb[], any] = () => {
|
|||
navigateToUrl: jest.fn(),
|
||||
},
|
||||
chrome: {
|
||||
...defaultCoreMock.chrome,
|
||||
getChromeStyle$: () => new BehaviorSubject<ChromeStyle>('classic').asObservable(),
|
||||
setBreadcrumbs: (newBreadcrumbs: ChromeBreadcrumb[]) => {
|
||||
breadcrumbObj = newBreadcrumbs;
|
||||
},
|
||||
|
|
|
@ -7,47 +7,20 @@
|
|||
|
||||
import { ChromeBreadcrumb } from '@kbn/core/public';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { MouseEvent, useContext, useEffect } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import { EuiBreadcrumb } from '@elastic/eui';
|
||||
import { useKibana } from '@kbn/kibana-react-plugin/public';
|
||||
import { useBreadcrumbs as useObservabilityBreadcrumbs } from '@kbn/observability-shared-plugin/public';
|
||||
import { ClientPluginsStart } from '../../../plugin';
|
||||
import { SyntheticsUrlParams, stringifyUrlParams } from '../utils/url_params';
|
||||
import { useUrlParams } from './use_url_params';
|
||||
import { PLUGIN } from '../../../../common/constants/plugin';
|
||||
import { SyntheticsSettingsContext } from '../contexts';
|
||||
|
||||
const EMPTY_QUERY = '?';
|
||||
|
||||
function handleBreadcrumbClick(
|
||||
breadcrumbs: ChromeBreadcrumb[],
|
||||
navigateToHref?: (url: string) => Promise<void>
|
||||
) {
|
||||
return breadcrumbs.map((bc) => ({
|
||||
...bc,
|
||||
...(bc.href
|
||||
? {
|
||||
onClick: (event: MouseEvent) => {
|
||||
if (navigateToHref && bc.href) {
|
||||
event.preventDefault();
|
||||
navigateToHref(bc.href);
|
||||
}
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
...(bc['data-test-subj']
|
||||
? {
|
||||
'data-test-subj': bc['data-test-subj'],
|
||||
}
|
||||
: {
|
||||
'data-test-subj': bc.href,
|
||||
}),
|
||||
}));
|
||||
}
|
||||
|
||||
export const makeBaseBreadcrumb = (
|
||||
uptimePath: string,
|
||||
observabilityPath: string,
|
||||
params?: SyntheticsUrlParams,
|
||||
isServerless?: boolean
|
||||
params?: SyntheticsUrlParams
|
||||
): EuiBreadcrumb[] => {
|
||||
if (params) {
|
||||
const crumbParams: Partial<SyntheticsUrlParams> = { ...params };
|
||||
|
@ -59,18 +32,6 @@ export const makeBaseBreadcrumb = (
|
|||
|
||||
const baseBreadcrumbs: EuiBreadcrumb[] = [];
|
||||
|
||||
// serverless Kibana has a curated UX flow, and "Observability" is already a given,
|
||||
// thus we don't need to include it explicitly in the breadcrumb trail
|
||||
if (!isServerless) {
|
||||
baseBreadcrumbs.push({
|
||||
text: i18n.translate('xpack.synthetics.breadcrumbs.observabilityText', {
|
||||
defaultMessage: 'Observability',
|
||||
}),
|
||||
href: observabilityPath,
|
||||
'data-test-subj': 'observabilityPathBreadcrumb',
|
||||
});
|
||||
}
|
||||
|
||||
baseBreadcrumbs.push({
|
||||
text: i18n.translate('xpack.synthetics.breadcrumbs.overviewBreadcrumbText', {
|
||||
defaultMessage: 'Synthetics',
|
||||
|
@ -84,32 +45,12 @@ export const makeBaseBreadcrumb = (
|
|||
|
||||
export const useBreadcrumbs = (extraCrumbs: ChromeBreadcrumb[]) => {
|
||||
const params = useUrlParams()[0]();
|
||||
const kibana = useKibana();
|
||||
const { setBreadcrumbs, isServerless } = useContext(SyntheticsSettingsContext);
|
||||
const kibana = useKibana<ClientPluginsStart>();
|
||||
const syntheticsPath =
|
||||
kibana.services.application?.getUrlForApp(PLUGIN.SYNTHETICS_PLUGIN_ID) ?? '';
|
||||
const observabilityPath =
|
||||
kibana.services.application?.getUrlForApp('observability-overview') ?? '';
|
||||
const navigate = kibana.services.application?.navigateToUrl;
|
||||
const breadcrumbs = useMemo(() => {
|
||||
return makeBaseBreadcrumb(syntheticsPath, params).concat(extraCrumbs);
|
||||
}, [extraCrumbs, params, syntheticsPath]);
|
||||
|
||||
useEffect(() => {
|
||||
if (setBreadcrumbs) {
|
||||
setBreadcrumbs(
|
||||
handleBreadcrumbClick(
|
||||
makeBaseBreadcrumb(syntheticsPath, observabilityPath, params, isServerless).concat(
|
||||
extraCrumbs
|
||||
),
|
||||
navigate
|
||||
)
|
||||
);
|
||||
}
|
||||
}, [
|
||||
syntheticsPath,
|
||||
observabilityPath,
|
||||
extraCrumbs,
|
||||
navigate,
|
||||
params,
|
||||
setBreadcrumbs,
|
||||
isServerless,
|
||||
]);
|
||||
useObservabilityBreadcrumbs(breadcrumbs, { serverless: kibana.services.serverless });
|
||||
};
|
||||
|
|
|
@ -66,7 +66,6 @@ export const getSyntheticsAppProps = (): SyntheticsAppProps => {
|
|||
setBadge,
|
||||
appMountParameters,
|
||||
isServerless,
|
||||
setBreadcrumbs: startPlugins.serverless?.setBreadcrumbs ?? coreStart.chrome.setBreadcrumbs,
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import React, { ReactElement, ReactNode } from 'react';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { of } from 'rxjs';
|
||||
import { BehaviorSubject, of } from 'rxjs';
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import {
|
||||
render as reactTestLibRender,
|
||||
|
@ -29,6 +29,7 @@ import { KibanaContextProvider, KibanaServices } from '@kbn/kibana-react-plugin/
|
|||
import { triggersActionsUiMock } from '@kbn/triggers-actions-ui-plugin/public/mocks';
|
||||
import { dataPluginMock } from '@kbn/data-plugin/public/mocks';
|
||||
import { KibanaPageTemplate } from '@kbn/shared-ux-page-kibana-template';
|
||||
import { ChromeStyle } from '@kbn/core-chrome-browser';
|
||||
import { mockState } from './__mocks__/synthetics_store.mock';
|
||||
import { MountWithReduxProvider } from './helper_with_redux';
|
||||
import { AppState } from '../../state';
|
||||
|
@ -166,6 +167,10 @@ export const mockCore: () => Partial<CoreStart> = () => {
|
|||
</div>
|
||||
),
|
||||
},
|
||||
chrome: {
|
||||
...defaultCore.chrome,
|
||||
getChromeStyle$: () => new BehaviorSubject<ChromeStyle>('classic').asObservable(),
|
||||
},
|
||||
};
|
||||
|
||||
return core;
|
||||
|
|
|
@ -104,7 +104,8 @@
|
|||
"@kbn/babel-register",
|
||||
"@kbn/slo-plugin",
|
||||
"@kbn/ebt-tools",
|
||||
"@kbn/alerting-types"
|
||||
"@kbn/alerting-types",
|
||||
"@kbn/core-chrome-browser"
|
||||
],
|
||||
"exclude": ["target/**/*"]
|
||||
}
|
||||
|
|
|
@ -17,6 +17,8 @@ import { coreMock } from '@kbn/core/public/mocks';
|
|||
import { merge } from 'lodash';
|
||||
import { UI_SETTINGS } from '@kbn/data-plugin/common';
|
||||
import { embeddablePluginMock } from '@kbn/embeddable-plugin/public/mocks';
|
||||
import { BehaviorSubject } from 'rxjs';
|
||||
import { ChromeStyle } from '@kbn/core-chrome-browser';
|
||||
|
||||
jest.mock('../services/rest/data_view', () => ({
|
||||
createStaticDataView: () => Promise.resolve(undefined),
|
||||
|
@ -122,6 +124,10 @@ const mockCore = merge({}, coreStart, {
|
|||
return uiSettings[key];
|
||||
},
|
||||
},
|
||||
chrome: {
|
||||
...coreStart.chrome,
|
||||
getChromeStyle$: () => new BehaviorSubject<ChromeStyle>('classic').asObservable(),
|
||||
},
|
||||
});
|
||||
|
||||
export const mockApmPluginContextValue = {
|
||||
|
|
|
@ -49,7 +49,8 @@
|
|||
"@kbn/react-kibana-context-render",
|
||||
"@kbn/react-kibana-context-theme",
|
||||
"@kbn/search-types",
|
||||
"@kbn/server-route-repository-utils"
|
||||
"@kbn/server-route-repository-utils",
|
||||
"@kbn/core-chrome-browser"
|
||||
],
|
||||
"exclude": ["target/**/*"]
|
||||
}
|
||||
|
|
|
@ -43696,7 +43696,6 @@
|
|||
"xpack.synthetics.badge.readOnly.text": "Lecture seule",
|
||||
"xpack.synthetics.badge.readOnly.tooltip": "Enregistrement impossible",
|
||||
"xpack.synthetics.blocked": "Bloqué",
|
||||
"xpack.synthetics.breadcrumbs.observabilityText": "Observabilité",
|
||||
"xpack.synthetics.breadcrumbs.overviewBreadcrumbText": "Synthetics",
|
||||
"xpack.synthetics.certificates.heading": "Certificats TLS ({total})",
|
||||
"xpack.synthetics.certificates.loading": "Chargement des certificats...",
|
||||
|
|
|
@ -43434,7 +43434,6 @@
|
|||
"xpack.synthetics.badge.readOnly.text": "読み取り専用",
|
||||
"xpack.synthetics.badge.readOnly.tooltip": "を保存できませんでした",
|
||||
"xpack.synthetics.blocked": "ブロック",
|
||||
"xpack.synthetics.breadcrumbs.observabilityText": "Observability",
|
||||
"xpack.synthetics.breadcrumbs.overviewBreadcrumbText": "Synthetics",
|
||||
"xpack.synthetics.certificates.heading": "TLS証明書({total})",
|
||||
"xpack.synthetics.certificates.loading": "証明書を読み込んでいます...",
|
||||
|
|
|
@ -43484,7 +43484,6 @@
|
|||
"xpack.synthetics.badge.readOnly.text": "只读",
|
||||
"xpack.synthetics.badge.readOnly.tooltip": "无法保存",
|
||||
"xpack.synthetics.blocked": "已阻止",
|
||||
"xpack.synthetics.breadcrumbs.observabilityText": "Observability",
|
||||
"xpack.synthetics.breadcrumbs.overviewBreadcrumbText": "Synthetics",
|
||||
"xpack.synthetics.certificates.heading": "TLS 证书 ({total})",
|
||||
"xpack.synthetics.certificates.loading": "正在加载证书......",
|
||||
|
|
|
@ -144,7 +144,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
|
||||
const documentTitle = await browser.getTitle();
|
||||
expect(documentTitle).to.contain(
|
||||
'Infrastructure Inventory - Infrastructure - Observability - Elastic'
|
||||
'Infrastructure inventory - Infrastructure - Observability - Elastic'
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -459,7 +459,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
await retry.tryForTime(5000, async () => {
|
||||
const documentTitle = await browser.getTitle();
|
||||
expect(documentTitle).to.contain(
|
||||
'host-5 - Infrastructure Inventory - Infrastructure - Observability - Elastic'
|
||||
'host-5 - Infrastructure inventory - Infrastructure - Observability - Elastic'
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -476,7 +476,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
await retry.tryForTime(5000, async () => {
|
||||
const documentTitle = await browser.getTitle();
|
||||
expect(documentTitle).to.contain(
|
||||
'pod-0 - Infrastructure Inventory - Infrastructure - Observability - Elastic'
|
||||
'pod-0 - Infrastructure inventory - Infrastructure - Observability - Elastic'
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -494,7 +494,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
await retry.tryForTime(5000, async () => {
|
||||
const documentTitle = await browser.getTitle();
|
||||
expect(documentTitle).to.contain(
|
||||
'container-id-4 - Infrastructure Inventory - Infrastructure - Observability - Elastic'
|
||||
'container-id-4 - Infrastructure inventory - Infrastructure - Observability - Elastic'
|
||||
);
|
||||
});
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
|
||||
const documentTitle = await browser.getTitle();
|
||||
expect(documentTitle).to.contain(
|
||||
'Infrastructure Inventory - Infrastructure - Observability - Elastic'
|
||||
'Infrastructure inventory - Infrastructure - Observability - Elastic'
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -87,7 +87,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
await retry.try(async () => {
|
||||
const documentTitle = await browser.getTitle();
|
||||
expect(documentTitle).to.contain(
|
||||
'demo-stack-redis-01 - Infrastructure Inventory - Infrastructure - Observability - Elastic'
|
||||
'demo-stack-redis-01 - Infrastructure inventory - Infrastructure - Observability - Elastic'
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -103,7 +103,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => {
|
|||
await retry.try(async () => {
|
||||
const documentTitle = await browser.getTitle();
|
||||
expect(documentTitle).to.contain(
|
||||
'pod-0 - Infrastructure Inventory - Infrastructure - Observability - Elastic'
|
||||
'pod-0 - Infrastructure inventory - Infrastructure - Observability - Elastic'
|
||||
);
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue