diff --git a/.changeset/cool-mice-sit.md b/.changeset/cool-mice-sit.md
new file mode 100644
index 0000000000..321b5fcf0b
--- /dev/null
+++ b/.changeset/cool-mice-sit.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-tech-insights': patch
+---
+
+Add new component `EntityTechInsightsScorecardCard`, which can be used in the overview of the `EntityPage` page or display multiple individual `EntityTechInsightsScorecardCard` in `EntityLayout.Route`.
diff --git a/plugins/tech-insights/README.md b/plugins/tech-insights/README.md
index a305ef5dc7..6c13622e1f 100644
--- a/plugins/tech-insights/README.md
+++ b/plugins/tech-insights/README.md
@@ -38,10 +38,6 @@ const serviceEntityPage = (
title="Customized title for the scorecard"
description="Small description about scorecards"
/>
-
...
@@ -50,8 +46,45 @@ const serviceEntityPage = (
It is not obligatory to pass title and description props to `EntityTechInsightsScorecardContent`. If those are left out, default values from `defaultCheckResultRenderers` in `CheckResultRenderer` will be taken, hence `Boolean scorecard` and `This card represents an overview of default boolean Backstage checks`.
+If you like to display multiple cards in a `EntityLayout.Route` use `EntityTechInsightsScorecardCard`.
+
You can pass an array `checksId` as a prop with the [Fact Retrievers ids](../tech-insights-backend#creating-fact-retrievers) to limit which checks you want to show in this card, If you don't pass, the default value is show all checks.
+```tsx
+
+```
+
+If you want to show checks in the overview of an entity use `EntityTechInsightsScorecardCard`.
+
+```tsx
+// packages/app/src/components/catalog/EntityPage.tsx
+
+import { EntityTechInsightsScorecardCard } from '@backstage/plugin-tech-insights';
+
+const overviewContent = (
+
+ {entityWarningContent}
+
+
+
+
+
+
+ ...
+
+
+
+
+);
+```
+
## Boolean Scorecard Example
If you follow the [Backend Example](https://github.com/backstage/backstage/tree/master/plugins/tech-insights-backend#backend-example), once the needed facts have been generated the boolean scorecard will look like this:
diff --git a/plugins/tech-insights/api-report.md b/plugins/tech-insights/api-report.md
index 9574efca28..3e099493b6 100644
--- a/plugins/tech-insights/api-report.md
+++ b/plugins/tech-insights/api-report.md
@@ -30,6 +30,17 @@ export type CheckResultRenderer = {
component: React_2.ReactElement;
};
+// @public (undocumented)
+export const EntityTechInsightsScorecardCard: ({
+ title,
+ description,
+ checksId,
+}: {
+ title?: string | undefined;
+ description?: string | undefined;
+ checksId?: string[] | undefined;
+}) => JSX.Element;
+
// @public (undocumented)
export const EntityTechInsightsScorecardContent: ({
title,
diff --git a/plugins/tech-insights/src/components/ScorecardsOverview/ScorecardsOverview.tsx b/plugins/tech-insights/src/components/ScorecardsCard/ScorecardsCard.tsx
similarity index 93%
rename from plugins/tech-insights/src/components/ScorecardsOverview/ScorecardsOverview.tsx
rename to plugins/tech-insights/src/components/ScorecardsCard/ScorecardsCard.tsx
index 53cf826e78..f6bc4b0cb5 100644
--- a/plugins/tech-insights/src/components/ScorecardsOverview/ScorecardsOverview.tsx
+++ b/plugins/tech-insights/src/components/ScorecardsCard/ScorecardsCard.tsx
@@ -19,11 +19,11 @@ import { useParams } from 'react-router-dom';
import useAsync from 'react-use/lib/useAsync';
import { Progress } from '@backstage/core-components';
import { useApi } from '@backstage/core-plugin-api';
-import { ChecksOverview } from './ChecksOverview';
+import { ScorecardInfo } from '../ScorecardsInfo';
import Alert from '@material-ui/lab/Alert';
import { techInsightsApiRef } from '../../api/TechInsightsApi';
-export const ScorecardsOverview = ({
+export const ScorecardsCard = ({
title,
description,
checksId,
@@ -45,7 +45,7 @@ export const ScorecardsOverview = ({
}
return (
- ({
+ contentScorecards: {
+ paddingLeft: 0,
+ paddingRight: 0,
+ },
+}));
+
+export const ScorecardsContent = ({
+ title,
+ description,
+ checksId,
+}: {
+ title?: string;
+ description?: string;
+ checksId?: string[];
+}) => {
+ const classes = useStyles();
+ const api = useApi(techInsightsApiRef);
+ const { namespace, kind, name } = useParams();
+ const { value, loading, error } = useAsync(
+ async () => await api.runChecks({ namespace, kind, name }, checksId),
+ );
+
+ if (loading) {
+ return ;
+ } else if (error) {
+ return {error.message};
+ }
+
+ return (
+
+
+
+
+
+ );
+};
diff --git a/plugins/tech-insights/src/components/ScorecardsContent/index.ts b/plugins/tech-insights/src/components/ScorecardsContent/index.ts
new file mode 100644
index 0000000000..fcdfb0b694
--- /dev/null
+++ b/plugins/tech-insights/src/components/ScorecardsContent/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { ScorecardsContent } from './ScorecardContent';
diff --git a/plugins/tech-insights/src/components/ScorecardsOverview/ChecksOverview.tsx b/plugins/tech-insights/src/components/ScorecardsInfo/ScorecardInfo.tsx
similarity index 64%
rename from plugins/tech-insights/src/components/ScorecardsOverview/ChecksOverview.tsx
rename to plugins/tech-insights/src/components/ScorecardsInfo/ScorecardInfo.tsx
index d153c690eb..2c5abb3596 100644
--- a/plugins/tech-insights/src/components/ScorecardsOverview/ChecksOverview.tsx
+++ b/plugins/tech-insights/src/components/ScorecardsInfo/ScorecardInfo.tsx
@@ -17,17 +17,13 @@
import React from 'react';
import { makeStyles, Grid, Typography } from '@material-ui/core';
import { useApi } from '@backstage/core-plugin-api';
-import { Content, Page, InfoCard } from '@backstage/core-components';
+import { InfoCard } from '@backstage/core-components';
import { CheckResult } from '@backstage/plugin-tech-insights-common';
import { techInsightsApiRef } from '../../api/TechInsightsApi';
import { BackstageTheme } from '@backstage/theme';
import { Alert } from '@material-ui/lab';
const useStyles = makeStyles((theme: BackstageTheme) => ({
- contentScorecards: {
- paddingLeft: 0,
- paddingRight: 0,
- },
subheader: {
fontWeight: 'bold',
paddingLeft: theme.spacing(0.5),
@@ -40,12 +36,37 @@ type Checks = {
description?: string;
};
-export const ChecksOverview = ({ checks, title, description }: Checks) => {
+const infoCard = (
+ title: Checks['title'],
+ description: Checks['description'],
+ className: string,
+ element: JSX.Element,
+) => (
+
+
+
+ {description}
+
+
+ {element}
+
+
+
+);
+
+export const ScorecardInfo = ({ checks, title, description }: Checks) => {
const classes = useStyles();
const api = useApi(techInsightsApiRef);
+
if (!checks.length) {
- return No checks have any data yet.;
+ return infoCard(
+ title,
+ description,
+ classes.subheader,
+ No checks have any data yet.,
+ );
}
+
const checkRenderType = api.getScorecardsDefinition(
checks[0].check.type,
checks,
@@ -54,21 +75,11 @@ export const ChecksOverview = ({ checks, title, description }: Checks) => {
);
if (checkRenderType) {
- return (
-
-
-
-
-
- {checkRenderType.description}
-
-
- {checkRenderType.component}
-
-
-
-
-
+ return infoCard(
+ checkRenderType.title,
+ checkRenderType.description,
+ classes.subheader,
+ checkRenderType.component,
);
}
diff --git a/plugins/tech-insights/src/components/ScorecardsInfo/index.ts b/plugins/tech-insights/src/components/ScorecardsInfo/index.ts
new file mode 100644
index 0000000000..21928465e0
--- /dev/null
+++ b/plugins/tech-insights/src/components/ScorecardsInfo/index.ts
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2021 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+export { ScorecardInfo } from './ScorecardInfo';
diff --git a/plugins/tech-insights/src/index.ts b/plugins/tech-insights/src/index.ts
index b59ac453ce..bc7c2ce26c 100644
--- a/plugins/tech-insights/src/index.ts
+++ b/plugins/tech-insights/src/index.ts
@@ -16,6 +16,7 @@
export {
techInsightsPlugin,
EntityTechInsightsScorecardContent,
+ EntityTechInsightsScorecardCard,
} from './plugin';
export { techInsightsApiRef } from './api/TechInsightsApi';
diff --git a/plugins/tech-insights/src/plugin.ts b/plugins/tech-insights/src/plugin.ts
index 0c2da63670..961519cd97 100644
--- a/plugins/tech-insights/src/plugin.ts
+++ b/plugins/tech-insights/src/plugin.ts
@@ -49,7 +49,19 @@ export const EntityTechInsightsScorecardContent = techInsightsPlugin.provide(
createRoutableExtension({
name: 'EntityTechInsightsScorecardContent',
component: () =>
- import('./components/ScorecardsOverview').then(m => m.ScorecardsOverview),
+ import('./components/ScorecardsContent').then(m => m.ScorecardsContent),
+ mountPoint: rootRouteRef,
+ }),
+);
+
+/**
+ * @public
+ */
+export const EntityTechInsightsScorecardCard = techInsightsPlugin.provide(
+ createRoutableExtension({
+ name: 'EntityTechInsightsScorecardCard',
+ component: () =>
+ import('./components/ScorecardsCard').then(m => m.ScorecardsCard),
mountPoint: rootRouteRef,
}),
);