Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { allOrAnyString } from '../../schema/common';
const fetchSLOHealthResponseSchema = t.array(
t.type({
sloId: sloIdSchema,
sloInstanceId: allOrAnyString,
sloRevision: t.number,
sloName: t.string,
state: stateSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@ export const getSLOTransformId = (sloId: string, sloRevision: number) =>
export const getSLOSummaryTransformId = (sloId: string, sloRevision: number) =>
`slo-summary-${sloId}-${sloRevision}`;

export const getWildcardTransformId = (sloId: string, sloRevision: number) =>
`slo-*${sloId}-${sloRevision}`;

export const getSLOPipelineId = (sloId: string, sloRevision: number) =>
`.slo-observability.sli.pipeline-${sloId}-${sloRevision}`;

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ describe('SloHealthCallout', () => {
data: [
{
sloId: 'test-slo-id',
sloInstanceId: 'irrelevant',
sloRevision: 1,
sloName: 'Test SLO',
health: {
Expand All @@ -133,6 +134,7 @@ describe('SloHealthCallout', () => {
data: [
{
sloId: 'test-slo-id',
sloInstanceId: 'irrelevant',
sloRevision: 1,
sloName: 'Test SLO',
health: {
Expand All @@ -159,6 +161,7 @@ describe('SloHealthCallout', () => {
data: [
{
sloId: 'test-slo-id',
sloInstanceId: 'irrelevant',
sloRevision: 1,
sloName: 'Test SLO',
health: {
Expand All @@ -185,6 +188,7 @@ describe('SloHealthCallout', () => {
data: [
{
sloId: 'test-slo-id',
sloInstanceId: 'irrelevant',
sloRevision: 1,
sloName: 'Test SLO',
health: {
Expand All @@ -211,6 +215,7 @@ describe('SloHealthCallout', () => {
data: [
{
sloId: 'test-slo-id',
sloInstanceId: 'irrelevant',
sloRevision: 1,
sloName: 'Test SLO',
health: {
Expand All @@ -237,6 +242,7 @@ describe('SloHealthCallout', () => {
data: [
{
sloId: 'test-slo-id',
sloInstanceId: 'irrelevant',
sloRevision: 1,
sloName: 'Test SLO',
health: {
Expand All @@ -252,9 +258,7 @@ describe('SloHealthCallout', () => {
renderComponent();

expect(screen.getByText('This SLO has issues with its transforms')).toBeInTheDocument();
expect(
screen.getByText(/The following transforms are in an unhealthy or missing state/)
).toBeInTheDocument();
expect(screen.getByText(/The following transforms need attention/)).toBeInTheDocument();

// Should show both transforms
expect(screen.getByText(/slo-test-slo-id-1 \(unhealthy\)/)).toBeInTheDocument();
Expand All @@ -272,6 +276,7 @@ describe('SloHealthCallout', () => {
data: [
{
sloId: 'test-slo-id',
sloInstanceId: 'irrelevant',
sloRevision: 1,
sloName: 'Test SLO',
health: {
Expand All @@ -287,9 +292,7 @@ describe('SloHealthCallout', () => {
renderComponent();

expect(screen.getByText('This SLO has issues with its transforms')).toBeInTheDocument();
expect(
screen.getByText(/The following transforms are in an unhealthy or missing state/)
).toBeInTheDocument();
expect(screen.getByText(/The following transforms need attention/)).toBeInTheDocument();

// Should show both transforms
expect(screen.getByText(/slo-test-slo-id-1 \(missing\)/)).toBeInTheDocument();
Expand All @@ -307,6 +310,7 @@ describe('SloHealthCallout', () => {
data: [
{
sloId: 'test-slo-id',
sloInstanceId: 'irrelevant',
sloRevision: 1,
sloName: 'Test SLO',
health: {
Expand All @@ -322,9 +326,7 @@ describe('SloHealthCallout', () => {
renderComponent();

expect(screen.getByText('This SLO has issues with its transforms')).toBeInTheDocument();
expect(
screen.getByText(/The following transforms are in an unhealthy state/)
).toBeInTheDocument();
expect(screen.getByText(/The following transforms need attention/)).toBeInTheDocument();

// Should show both transforms as unhealthy
expect(screen.getByText(/slo-test-slo-id-1 \(unhealthy\)/)).toBeInTheDocument();
Expand All @@ -342,6 +344,7 @@ describe('SloHealthCallout', () => {
data: [
{
sloId: 'test-slo-id',
sloInstanceId: 'irrelevant',
sloRevision: 1,
sloName: 'Test SLO',
health: {
Expand All @@ -357,7 +360,7 @@ describe('SloHealthCallout', () => {
renderComponent();

expect(screen.getByText('This SLO has issues with its transforms')).toBeInTheDocument();
expect(screen.getByText(/The following transforms are in a missing state/)).toBeInTheDocument();
expect(screen.getByText(/The following transforms need attention/)).toBeInTheDocument();

// Should show both transforms as missing
expect(screen.getByText(/slo-test-slo-id-1 \(missing\)/)).toBeInTheDocument();
Expand All @@ -375,6 +378,7 @@ describe('SloHealthCallout', () => {
data: [
{
sloId: 'test-slo-id',
sloInstanceId: 'irrelevant',
sloRevision: 1,
sloName: 'Test SLO',
health: {
Expand Down Expand Up @@ -405,6 +409,7 @@ describe('SloHealthCallout', () => {
data: [
{
sloId: 'test-slo-id',
sloInstanceId: 'irrelevant',
sloRevision: 1,
sloName: 'Test SLO',
health: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@
*/

import { EuiCallOut, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import React, { useMemo } from 'react';
import { MANAGEMENT_APP_LOCATOR } from '@kbn/deeplinks-management/constants';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n-react';
import { MANAGEMENT_APP_LOCATOR } from '@kbn/deeplinks-management/constants';
import kbnRison from '@kbn/rison';
import type { SLOWithSummaryResponse } from '@kbn/slo-schema';
import { useKibana } from '../../../hooks/use_kibana';
import { useFetchSloHealth } from '../../../hooks/use_fetch_slo_health';
import { values } from 'lodash';
import React from 'react';
import { getSLOSummaryTransformId, getSLOTransformId } from '../../../../common/constants';
import { useActionModal } from '../../../context/action_modal';
import { getSloHealthStateText } from '../../../lib/slo_health_helpers';
import { getSLOTransformId, getSLOSummaryTransformId } from '../../../../common/constants';
import { ContentWithResetCta } from './health_callout/content_with_reset_cta';
import { useFetchSloHealth } from '../../../hooks/use_fetch_slo_health';
import { useKibana } from '../../../hooks/use_kibana';
import { ContentWithInspectCta } from './health_callout/content_with_inspect_cta';
import { ContentWithResetCta } from './health_callout/content_with_reset_cta';

export function SloHealthCallout({ slo }: { slo: SLOWithSummaryResponse }) {
const { isLoading, isError, data } = useFetchSloHealth({ list: [slo] });
Expand Down Expand Up @@ -52,19 +52,6 @@ export function SloHealthCallout({ slo }: { slo: SLOWithSummaryResponse }) {
);
};

const rollupTransformId = useMemo(
() => getSLOTransformId(slo.id, slo.revision),
[slo.id, slo.revision]
);

const summaryTransformId = useMemo(
() => getSLOSummaryTransformId(slo.id, slo.revision),
[slo.id, slo.revision]
);

const rollupUrl = getUrl(rollupTransformId);
const summaryUrl = getUrl(summaryTransformId);

if (isLoading || isError || data === undefined || data?.length !== 1) {
return null;
}
Expand All @@ -74,24 +61,24 @@ export function SloHealthCallout({ slo }: { slo: SLOWithSummaryResponse }) {
return null;
}

const unhealthyRollup = health.rollup === 'unhealthy';
const unhealthySummary = health.summary === 'unhealthy';
const missingRollup = health.rollup === 'missing';
const missingSummary = health.summary === 'missing';
const rollupTransformId = getSLOTransformId(slo.id, slo.revision);
const summaryTransformId = getSLOSummaryTransformId(slo.id, slo.revision);

const unhealthyRollupContent = `${rollupTransformId} (unhealthy)`;
const unhealthySummaryContent = `${summaryTransformId} (unhealthy)`;
const missingRollupContent = `${rollupTransformId} (missing)`;
const missingSummaryContent = `${summaryTransformId} (missing)`;
const rollupUrl = getUrl(rollupTransformId);
const summaryUrl = getUrl(summaryTransformId);

const count = [unhealthyRollup, unhealthySummary, missingRollup, missingSummary].filter(
Boolean
).length;
const rollup = {
unhealthy: health.rollup === 'unhealthy',
missing: health.rollup === 'missing',
};
const summary = {
unhealthy: health.summary === 'unhealthy',
missing: health.summary === 'missing',
};

const stateText = getSloHealthStateText(
unhealthyRollup || unhealthySummary,
missingRollup || missingSummary
);
const rollupHasIssue = values(rollup).some(Boolean);
const summaryHasIssue = values(summary).some(Boolean);
const count = [rollupHasIssue, summaryHasIssue].filter(Boolean).length;

return (
<EuiCallOut
Expand All @@ -105,42 +92,43 @@ export function SloHealthCallout({ slo }: { slo: SLOWithSummaryResponse }) {
<EuiFlexItem>
<FormattedMessage
id="xpack.slo.sloDetails.healthCallout.description"
defaultMessage="The following {count, plural, one {transform is} other {transforms are}} in {stateText} state. You can inspect {count, plural, it {one} other {each one}} here:"
values={{ count, stateText }}
defaultMessage="The following {count, plural, one {transform needs} other {transforms need}} attention. You can inspect {count, plural, it {one} other {each one}} here:"
values={{ count }}
/>
<ul>
{health.rollup === 'unhealthy' && !!rollupUrl && (
<li key={`${slo.id}-rollup-unhealthy`}>
{rollup.unhealthy && !!rollupUrl && (
<li>
<ContentWithInspectCta
textSize="s"
content={unhealthyRollupContent}
content={getUnhealthyText(rollupTransformId)}
url={rollupUrl}
/>
</li>
)}
{health.summary === 'unhealthy' && !!summaryUrl && (
<li key={`${slo.id}-summary-unhealthy`}>
<ContentWithInspectCta
{rollup.missing && (
<li>
<ContentWithResetCta
textSize="s"
content={unhealthySummaryContent}
url={summaryUrl}
content={getMissingText(rollupTransformId)}
handleReset={handleReset}
/>
</li>
)}
{health.rollup === 'missing' && (
<li key={`${slo.id}-rollup-missing`}>
<ContentWithResetCta

{summary.unhealthy && !!summaryUrl && (
<li>
<ContentWithInspectCta
textSize="s"
content={missingRollupContent}
handleReset={handleReset}
content={getUnhealthyText(summaryTransformId)}
url={summaryUrl}
/>
</li>
)}
{health.summary === 'missing' && (
<li key={`${slo.id}-summary-missing`}>
{summary.missing && (
<li>
<ContentWithResetCta
textSize="s"
content={missingSummaryContent}
content={getMissingText(summaryTransformId)}
handleReset={handleReset}
/>
</li>
Expand All @@ -151,3 +139,15 @@ export function SloHealthCallout({ slo }: { slo: SLOWithSummaryResponse }) {
</EuiCallOut>
);
}

const getUnhealthyText = (transformId: string) =>
i18n.translate('xpack.slo.sloDetails.healthCallout.unhealthyTransformText', {
defaultMessage: '{transformId} (unhealthy)',
values: { transformId },
});

const getMissingText = (transformId: string) =>
i18n.translate('xpack.slo.sloDetails.healthCallout.missingTransformText', {
defaultMessage: '{transformId} (missing)',
values: { transformId },
});
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
import { EuiButtonEmpty, EuiCallOut, EuiFlexGroup, EuiFlexItem } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n-react';
import type { SLOWithSummaryResponse } from '@kbn/slo-schema';
import { uniqBy } from 'lodash';
import React, { useState } from 'react';
import { paths } from '../../../../../common/locators/paths';
import { useFetchSloHealth } from '../../../../hooks/use_fetch_slo_health';
import { ContentWithInspectCta } from '../../../slo_details/components/health_callout/content_with_inspect_cta';
import { paths } from '../../../../../common/locators/paths';

const CALLOUT_SESSION_STORAGE_KEY = 'slo_health_callout_hidden';

Expand All @@ -30,13 +31,13 @@ export function HealthCallout({ sloList = [] }: { sloList: SLOWithSummaryRespons
return null;
}

const unhealthyAndMissingSloList = results.filter(
(result) => result.health.overall === 'unhealthy' || result.health.overall === 'missing'
);
if (unhealthyAndMissingSloList.length === 0) {
const problematicSloList = results.filter((result) => result.health.overall !== 'healthy');
if (problematicSloList.length === 0) {
return null;
}

const deduplicatedList = uniqBy(problematicSloList, (item) => item.sloId);

const dismiss = () => {
setShowCallOut(false);
sessionStorage.setItem('slo_health_callout_hidden', 'true');
Expand Down Expand Up @@ -73,17 +74,22 @@ export function HealthCallout({ sloList = [] }: { sloList: SLOWithSummaryRespons
id="xpack.slo.sloList.healthCallout.description"
defaultMessage="The following {count, plural, one {SLO is} other {SLOs are}} in an unhealthy state. Data may be missing or incomplete. You can inspect {count, plural, one {it} other {each one}} here:"
values={{
count: unhealthyAndMissingSloList.length,
count: deduplicatedList.length,
}}
/>
</span>
<ul>
{unhealthyAndMissingSloList.map((result) => (
{deduplicatedList.map((result) => (
<li key={result.sloId}>
<ContentWithInspectCta
textSize="xs"
content={result.sloName}
url={paths.sloDetails(result.sloId, '*', undefined, 'overview')}
url={paths.sloDetails(
result.sloId,
result.sloInstanceId,
undefined,
'overview'
)}
/>
</li>
))}
Expand Down
Loading