-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[SLO] Link dashboards to SLO #233265
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SLO] Link dashboards to SLO #233265
Changes from all commits
310721a
9f06d37
aa2c98b
cea5603
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,91 @@ | ||
| /* | ||
| * 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 { EuiFlexGroup, EuiFlexItem, EuiLink, EuiLoadingSpinner, EuiText } from '@elastic/eui'; | ||
| import { DASHBOARD_APP_LOCATOR } from '@kbn/deeplinks-analytics'; | ||
| import React, { useMemo } from 'react'; | ||
| import type { DashboardLocatorParams } from '@kbn/dashboard-plugin/common'; | ||
| import { useQuery } from '@tanstack/react-query'; | ||
| import { i18n } from '@kbn/i18n'; | ||
| import type { DashboardStart } from '@kbn/dashboard-plugin/public'; | ||
| import type { SLODefinition } from '../../../../../server/domain/models'; | ||
| import { useKibana } from '../../../../hooks/use_kibana'; | ||
|
|
||
| interface Props { | ||
| dashboards: NonNullable<NonNullable<SLODefinition['artifacts']>['dashboards']>; | ||
| } | ||
|
|
||
| interface LinkedDashboard { | ||
| id: string; | ||
| title: string; | ||
| } | ||
|
|
||
| const getDashboards = async ( | ||
| dashboardsIds: string[], | ||
| dashboardStart: DashboardStart | ||
| ): Promise<LinkedDashboard[]> => { | ||
| if (dashboardsIds.length === 0) { | ||
| return []; | ||
| } | ||
|
|
||
| const findDashboardsService = await dashboardStart.findDashboardsService(); | ||
|
|
||
| const dashboards = await findDashboardsService.findByIds(dashboardsIds); | ||
|
|
||
| return dashboards.flatMap((dashboard) => | ||
| dashboard.status === 'success' ? [{ id: dashboard.id, title: dashboard.attributes.title }] : [] | ||
| ); | ||
| }; | ||
|
|
||
| export function LinkedDashboards({ dashboards }: Props) { | ||
| const { | ||
| services: { share }, | ||
| services: { dashboard: dashboardStart }, | ||
| } = useKibana(); | ||
|
|
||
| const dashboardLocator = share.url.locators.get<DashboardLocatorParams>(DASHBOARD_APP_LOCATOR); | ||
|
|
||
| const dashboardsIds = useMemo(() => dashboards.map((dashboard) => dashboard.id), [dashboards]); | ||
|
|
||
| const { data, isLoading } = useQuery({ | ||
| queryKey: ['SLO-dashboards', ...dashboardsIds], | ||
| queryFn: () => getDashboards(dashboardsIds, dashboardStart), | ||
| refetchOnWindowFocus: false, | ||
| }); | ||
|
|
||
| if (isLoading) { | ||
| return <EuiLoadingSpinner size="m" />; | ||
| } | ||
|
|
||
| if (!data || data.length === 0) { | ||
| return ( | ||
| <EuiText size="s"> | ||
| {i18n.translate('xpack.slo.sloDetails.overview.noDashboards', { | ||
| defaultMessage: 'No linked dashboards', | ||
| })} | ||
| </EuiText> | ||
| ); | ||
| } | ||
|
|
||
| return ( | ||
| <EuiFlexGroup direction="column" gutterSize="xs"> | ||
| {data.map((dashboardAsset) => { | ||
| return ( | ||
| <EuiFlexItem grow={false} key={dashboardAsset.id}> | ||
| <EuiLink | ||
| data-test-subj="dashboardAssetLink" | ||
| href={dashboardLocator?.getRedirectUrl({ dashboardId: dashboardAsset.id })} | ||
| target="_blank" | ||
| > | ||
| {dashboardAsset.title} | ||
| </EuiLink> | ||
| </EuiFlexItem> | ||
| ); | ||
| })} | ||
| </EuiFlexGroup> | ||
| ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,6 +54,7 @@ import type { | |
| import type { SecurityPluginSetup, SecurityPluginStart } from '@kbn/security-plugin-types-public'; | ||
| import type { FieldsMetadataPublicStart } from '@kbn/fields-metadata-plugin/public'; | ||
| import type { ApmSourceAccessPluginStart } from '@kbn/apm-sources-access-plugin/public'; | ||
| import type { ContentManagementPublicStart } from '@kbn/content-management-plugin/public'; | ||
| import type { SLORouteRepository } from '../server/routes/get_slo_server_route_repository'; | ||
| import type { SLOPlugin } from './plugin'; | ||
|
|
||
|
|
@@ -106,6 +107,7 @@ export interface SLOPublicPluginsStart { | |
| security?: SecurityPluginStart; | ||
| fieldsMetadata: FieldsMetadataPublicStart; | ||
| apmSourcesAccess: ApmSourceAccessPluginStart; | ||
| contentManagement: ContentManagementPublicStart; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Linking with this issue, where we can remove the dependency to the contentManagement plugin
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to clarify, this comment of mine regarding removing dependency to the contentManagement plugin, is something that does NOT need to be addressed in current PR. I put it here as a reminder for when addressing this issue. I also just read Dominique's here, so it might be that we don't need to replace anything (I need to refresh what it is about). @cesco-f Can you weigh in here if we can replace the use of dashboardServiceProvider with the api in the rules form?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I left a comment there!
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, we discussed about it! With the new abstract dashboards selector component you introduce in this PR, there is no need to use the linked dashboards api in the rule form. |
||
| } | ||
|
|
||
| export type SLOPublicSetup = ReturnType<SLOPlugin['setup']>; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great for creating this reusable component!