Skip to content

Commit 52b60ee

Browse files
EswaraiahsapramHusneShabbirHusneShabbir
authored
feat(scorecard): add aggregated scorecard metrics frontend (#1859)
* feat(scorecard): add aggregated scorecard metrics frontend * change of locator Co-authored-by: HusneShabbir <husneshabbir447@gmail.com> * homepage integration to scorecard to test aggregated metrics in local * fix lock file * fix sonarqube issues * addressed review comments --------- Co-authored-by: Husne Shabbir <shabbirhusne447@gmail.com> Co-authored-by: HusneShabbir <husneshabbir447@gmail.com>
1 parent 2e866af commit 52b60ee

28 files changed

+1901
-99
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@red-hat-developer-hub/backstage-plugin-scorecard-common': minor
3+
'@red-hat-developer-hub/backstage-plugin-scorecard': minor
4+
---
5+
6+
Added aggregated metric cards frontend

workspaces/scorecard/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
"resolutions": {
5555
"@types/react": "^18",
5656
"@types/react-dom": "^18",
57-
"refractor@npm:3.6.0/prismjs": "^1.30.0"
57+
"refractor@npm:3.6.0/prismjs": "^1.30.0",
58+
"isolated-vm": "6.0.2"
5859
},
5960
"prettier": "@spotify/prettier-config",
6061
"lint-staged": {

workspaces/scorecard/packages/app/e2e-tests/pages/CatalogPage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ export class CatalogPage {
2626
const enterButton = this.page.getByRole('button', { name: 'Enter' });
2727
await expect(enterButton).toBeVisible();
2828
await enterButton.click();
29-
await expect(this.page.getByText('My Company Catalog')).toBeVisible();
29+
await expect(this.page.getByText('Welcome back!')).toBeVisible();
3030
await this.switchToLocale(this.page, locale);
3131
}
3232

workspaces/scorecard/packages/app/e2e-tests/pages/ScorecardPage.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class ScorecardPage {
4141
}
4242

4343
async openTab() {
44-
const scorecardTab = this.page.getByText('Scorecard');
44+
const scorecardTab = this.page.getByText('Scorecard', { exact: true });
4545
await expect(scorecardTab).toBeVisible();
4646
await Promise.all([
4747
waitUntilApiCallSucceeds(this.page),

workspaces/scorecard/packages/app/e2e-tests/scorecard.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ test.describe.serial('Pre-RBAC Access Tests', () => {
5151
await page.goto('/');
5252
await catalogPage.navigateToCatalog(currentLocale);
5353
await catalogPage.openComponent('Red Hat Developer Hub');
54-
await page.getByText('Scorecard').click();
54+
await page.getByText('Scorecard', { exact: true }).click();
5555

5656
await expect(
5757
page.getByText(translations.permissionRequired.title),

workspaces/scorecard/packages/app/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,13 @@
4848
"@backstage/ui": "^0.9.1",
4949
"@material-ui/core": "^4.12.2",
5050
"@material-ui/icons": "^4.9.1",
51+
"@openshift/dynamic-plugin-sdk": "^5.0.1",
52+
"@red-hat-developer-hub/backstage-plugin-dynamic-home-page": "^1.9.2",
5153
"@red-hat-developer-hub/backstage-plugin-scorecard": "workspace:^",
5254
"@red-hat-developer-hub/backstage-plugin-theme": "^0.11.0",
5355
"@roadiehq/backstage-plugin-github-pull-requests": "^3.5.1",
5456
"@roadiehq/backstage-plugin-jira": "^2.13.1",
57+
"@scalprum/react-core": "0.9.5",
5558
"react": "^18.0.2",
5659
"react-dom": "^18.0.2",
5760
"react-router": "^6.3.0",

workspaces/scorecard/packages/app/src/App.tsx

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
import { Navigate, Route } from 'react-router-dom';
16+
import { Route } from 'react-router-dom';
1717
import { apiDocsPlugin, ApiExplorerPage } from '@backstage/plugin-api-docs';
1818
import {
1919
CatalogEntityPage,
@@ -54,13 +54,59 @@ import { catalogEntityCreatePermission } from '@backstage/plugin-catalog-common/
5454
import { scorecardTranslations } from '@red-hat-developer-hub/backstage-plugin-scorecard/alpha';
5555
import { githubAuthApiRef } from '@backstage/core-plugin-api';
5656
import { getThemes } from '@red-hat-developer-hub/backstage-plugin-theme';
57+
import { ScorecardHomepageSection } from '@red-hat-developer-hub/backstage-plugin-scorecard';
58+
59+
import { ScalprumContext, ScalprumState } from '@scalprum/react-core';
60+
import { PluginStore } from '@openshift/dynamic-plugin-sdk';
61+
import {
62+
DynamicCustomizableHomePage,
63+
OnboardingSection,
64+
defaultLayouts,
65+
HomePageCardMountPoint,
66+
homepageTranslations,
67+
} from '@red-hat-developer-hub/backstage-plugin-dynamic-home-page';
68+
69+
const mountPoints: HomePageCardMountPoint[] = [
70+
{
71+
Component: OnboardingSection,
72+
config: {
73+
layouts: defaultLayouts.onboarding,
74+
},
75+
},
76+
{
77+
Component: ScorecardHomepageSection,
78+
config: {
79+
layouts: {
80+
xl: { w: 12, h: 6 },
81+
lg: { w: 12, h: 6 },
82+
md: { w: 12, h: 7 },
83+
sm: { w: 12, h: 8 },
84+
xs: { w: 12, h: 9 },
85+
xxs: { w: 12, h: 10 },
86+
},
87+
},
88+
},
89+
];
90+
91+
const scalprumState: ScalprumState = {
92+
initialized: true,
93+
api: {
94+
dynamicRootConfig: {
95+
mountPoints: {
96+
'home.page/cards': mountPoints,
97+
},
98+
},
99+
},
100+
config: {},
101+
pluginStore: new PluginStore(),
102+
};
57103

58104
const app = createApp({
59105
apis,
60106
themes: getThemes(),
61107
__experimentalTranslations: {
62108
availableLanguages: ['en', 'de', 'fr', 'es'],
63-
resources: [scorecardTranslations],
109+
resources: [scorecardTranslations, homepageTranslations],
64110
},
65111
bindRoutes({ bind }) {
66112
bind(catalogPlugin.externalRoutes, {
@@ -100,7 +146,14 @@ const app = createApp({
100146

101147
const routes = (
102148
<FlatRoutes>
103-
<Route path="/" element={<Navigate to="catalog" />} />
149+
<Route
150+
path="/"
151+
element={
152+
<ScalprumContext.Provider value={scalprumState}>
153+
<DynamicCustomizableHomePage />
154+
</ScalprumContext.Provider>
155+
}
156+
/>
104157
<Route path="/catalog" element={<CatalogIndexPage />} />
105158
<Route
106159
path="/catalog/:namespace/:kind/:name"

workspaces/scorecard/plugins/scorecard/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ permission:
5353
1. Add the Scorecard page to you Entity overview page by modifying `packages/app/src/components/catalog/EntityPage.tsx`:
5454

5555
```tsx
56-
import { ScorecardPage } from '@red-hat-developer-hub/backstage-plugin-scorecard';
56+
import { EntityScorecardContent } from '@red-hat-developer-hub/backstage-plugin-scorecard';
5757
5858
const scorecardRoute = (
5959
<EntityLayout.Route path="/scorecard" title="Scorecard">
60-
<ScorecardPage />
60+
<EntityScorecardContent />
6161
</EntityLayout.Route>
6262
);
6363
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* Copyright Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
import { AggregatedMetricResult } from '../src/utils/utils';
18+
19+
export const mockAggregatedScorecardSuccessData: AggregatedMetricResult[] = [
20+
{
21+
id: 'github.open_prs',
22+
status: 'success',
23+
metadata: {
24+
title: 'GitHub open PRs',
25+
description:
26+
'Current count of open Pull Requests for a given GitHub repository.',
27+
type: 'object',
28+
history: true,
29+
},
30+
result: {
31+
values: [
32+
{ count: 11, name: 'success' },
33+
{ count: 14, name: 'warning' },
34+
{ count: 12, name: 'error' },
35+
],
36+
total: 37,
37+
timestamp: '2024-01-15T10:30:00Z',
38+
lastUpdated: '2024-01-15T10:30:00Z',
39+
},
40+
},
41+
{
42+
id: 'jira.issues_open',
43+
status: 'success',
44+
metadata: {
45+
title: 'Jira open blocking tickets',
46+
description:
47+
'Highlights the number of critical, blocking issues that are currently open in Jira.',
48+
type: 'object',
49+
history: true,
50+
},
51+
result: {
52+
values: [
53+
{ count: 0, name: 'success' },
54+
{ count: 1, name: 'warning' },
55+
{ count: 3, name: 'error' },
56+
],
57+
total: 4,
58+
timestamp: '2024-01-15T10:30:00Z',
59+
lastUpdated: '2024-01-15T10:30:00Z',
60+
},
61+
},
62+
];

workspaces/scorecard/plugins/scorecard/dev/index.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { TestApiProvider } from '@backstage/test-utils';
2121
import { getAllThemes } from '@red-hat-developer-hub/backstage-plugin-theme';
2222
import type { Entity } from '@backstage/catalog-model';
2323
import type { MetricResult } from '@red-hat-developer-hub/backstage-plugin-scorecard-common';
24+
import type { AggregatedMetricResult } from '../src/utils/utils';
2425

2526
import { scorecardPlugin, EntityScorecardContent } from '../src/plugin';
2627
import { scorecardTranslations } from '../src/translations';
@@ -29,6 +30,7 @@ import {
2930
mockScorecardErrorData,
3031
mockScorecardSuccessData,
3132
} from '../__fixtures__/scorecardData';
33+
import { mockAggregatedScorecardSuccessData } from '../__fixtures__/aggregatedScorecardData';
3234

3335
const mockComponentEntity: Entity = {
3436
apiVersion: 'backstage.io/v1alpha1',
@@ -48,6 +50,11 @@ class MockScorecardApi implements ScorecardApi {
4850
async getScorecards(_entity: Entity): Promise<MetricResult[]> {
4951
return [...mockScorecardSuccessData, ...mockScorecardErrorData];
5052
}
53+
async getAggregatedScorecards(
54+
_metricIds?: string[],
55+
): Promise<AggregatedMetricResult[]> {
56+
return mockAggregatedScorecardSuccessData;
57+
}
5158
}
5259

5360
createDevApp()

0 commit comments

Comments
 (0)