Merge pull request #23592 from grantila/grantila/scorecards-card-onlyfailed-feature

Added 'onlyFailed' prop to ScorecardsCard
This commit is contained in:
Ben Lambert
2024-03-19 13:11:53 +01:00
committed by GitHub
7 changed files with 51 additions and 6 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-tech-insights': patch
---
Added `onlyFailed` prop to `ScorecardsCard`, and `isFailed` to each check type.
+3
View File
@@ -39,6 +39,7 @@ export type CheckResultRenderer = {
type: string;
component: (check: CheckResult) => React_2.ReactElement;
description?: (check: CheckResult) => string | React_2.ReactElement;
isFailed?: (check: CheckResult) => boolean;
};
// @public (undocumented)
@@ -46,6 +47,7 @@ export const EntityTechInsightsScorecardCard: (props: {
title: string;
description?: string | undefined;
checksId?: string[] | undefined;
onlyFailed?: boolean | undefined;
}) => JSX_2.Element;
// @public (undocumented)
@@ -73,6 +75,7 @@ export const ScorecardInfo: (props: {
checkResults: CheckResult[];
title: string;
description?: string | undefined;
noWarning?: boolean | undefined;
}) => JSX_2.Element;
// @public (undocumented)
@@ -29,3 +29,9 @@ export const BooleanCheck = (props: { checkResult: CheckResult }) => {
<ErrorOutlineIcon color="error" />
);
};
/**
* @public
*/
export const isBooleanCheckFailed = (checkResult: CheckResult) =>
!checkResult.result;
@@ -14,4 +14,4 @@
* limitations under the License.
*/
export { BooleanCheck } from './BooleanCheck';
export { BooleanCheck, isBooleanCheckFailed } from './BooleanCheck';
@@ -16,7 +16,7 @@
import { CheckResult } from '@backstage/plugin-tech-insights-common';
import React from 'react';
import { BooleanCheck } from './BooleanCheck';
import { BooleanCheck, isBooleanCheckFailed } from './BooleanCheck';
/**
* Defines a react component that is responsible for rendering a result of a given type.
@@ -27,6 +27,7 @@ export type CheckResultRenderer = {
type: string;
component: (check: CheckResult) => React.ReactElement;
description?: (check: CheckResult) => string | React.ReactElement;
isFailed?: (check: CheckResult) => boolean;
};
/**
@@ -39,4 +40,5 @@ export const jsonRulesEngineCheckResultRenderer: CheckResultRenderer = {
component: (checkResult: CheckResult) => (
<BooleanCheck checkResult={checkResult} />
),
isFailed: isBooleanCheckFailed,
};
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import React from 'react';
import React, { useMemo } from 'react';
import useAsync from 'react-use/lib/useAsync';
import { ErrorPanel, Progress } from '@backstage/core-components';
import { useApi } from '@backstage/core-plugin-api';
@@ -27,8 +27,9 @@ export const ScorecardsCard = (props: {
title: string;
description?: string;
checksId?: string[];
onlyFailed?: boolean;
}) => {
const { title, description, checksId } = props;
const { title, description, checksId, onlyFailed } = props;
const api = useApi(techInsightsApiRef);
const { entity } = useEntity();
const { value, loading, error } = useAsync(
@@ -36,17 +37,34 @@ export const ScorecardsCard = (props: {
[api, entity, JSON.stringify(checksId)],
);
const checkResultRenderers = useMemo(() => {
if (!onlyFailed || !value) return {};
const types = [...new Set(value.map(({ check }) => check.type))];
const renderers = api.getCheckResultRenderers(types);
return Object.fromEntries(
renderers.map(renderer => [renderer.type, renderer]),
);
}, [api, value, onlyFailed]);
if (loading) {
return <Progress />;
} else if (error) {
return <ErrorPanel error={error} />;
}
const filteredValue = !onlyFailed
? value || []
: (value || []).filter(val =>
checkResultRenderers[val.check.type]?.isFailed?.(val),
);
return (
<ScorecardInfo
title={title}
description={description}
checkResults={value || []}
checkResults={filteredValue}
noWarning={onlyFailed}
/>
);
};
@@ -54,11 +54,22 @@ export const ScorecardInfo = (props: {
checkResults: CheckResult[];
title: string;
description?: string;
noWarning?: boolean;
}) => {
const { checkResults, title, description } = props;
const { checkResults, title, description, noWarning } = props;
const classes = useStyles();
if (!checkResults.length) {
if (noWarning) {
return infoCard(
title,
description,
classes.subheader,
<Alert severity="info">
All checks passed, or no checks have been performed yet
</Alert>,
);
}
return infoCard(
title,
description,