Skip to content

Commit f6f7bcf

Browse files
fix(scorecard): add threshold-based status colors to entities table (#2640)
* fix(scorecard): add threshold-based status colors to entities table * improve query provider * fix nfs mode * resolve merge conflicts with main branch * fix api reports * fix api reports * remove custome retry and refetchOnWindowFocus * revert e2e * fix nfs app * fix customized title * fix unit test * fix e2e tests * handle error on id not found
1 parent 4526035 commit f6f7bcf

32 files changed

+735
-394
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@red-hat-developer-hub/backstage-plugin-scorecard': patch
3+
---
4+
5+
add threshold-based status colors to entities table

workspaces/scorecard/packages/app-legacy/e2e-tests/pages/ScorecardDrillDownPage.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,10 +65,10 @@ export class ScorecardDrillDownPage {
6565
}
6666
}
6767

68-
async expectPageTitle(metricId: MetricId) {
68+
async expectPageTitle(metricId: MetricId, customTitle?: string) {
6969
await expect(
7070
this.page.getByRole('heading', {
71-
name: this.translations.metric[metricId].title,
71+
name: customTitle ?? this.translations.metric[metricId].title,
7272
level: 1,
7373
}),
7474
).toBeVisible();

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,10 @@ test.describe('Scorecard Plugin Tests', () => {
710710
await scorecardDrillDownPage.expectOnPage('github.open_prs', {
711711
aggregationId: AGGREGATED_CARDS_METRIC_IDS.withGithubOpenPrs,
712712
});
713-
await scorecardDrillDownPage.expectPageTitle('github.open_prs');
713+
await scorecardDrillDownPage.expectPageTitle(
714+
'github.open_prs',
715+
githubAggregatedResponse.metadata.title,
716+
);
714717
await scorecardDrillDownPage.expectDrillDownCardSnapshot(
715718
'github.open_prs',
716719
{
@@ -824,7 +827,10 @@ test.describe('Scorecard Plugin Tests', () => {
824827
await scorecardDrillDownPage.expectOnPage('jira.open_issues', {
825828
aggregationId: AGGREGATED_CARDS_METRIC_IDS.withJiraOpenIssuesKpi,
826829
});
827-
await scorecardDrillDownPage.expectPageTitle('jira.open_issues');
830+
await scorecardDrillDownPage.expectPageTitle(
831+
'jira.open_issues',
832+
jiraAggregatedResponse.metadata.title,
833+
);
828834
await scorecardDrillDownPage.expectDrillDownCardSnapshot(
829835
'jira.open_issues',
830836
{

workspaces/scorecard/plugins/scorecard/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"@mui/icons-material": "5.18.0",
6565
"@mui/material": "5.18.0",
6666
"@red-hat-developer-hub/backstage-plugin-scorecard-common": "workspace:^",
67+
"@tanstack/react-query": "^5.95.2",
6768
"date-fns": "^4.1.0",
6869
"react-use": "^17.2.4",
6970
"recharts": "^3.3.0"

workspaces/scorecard/plugins/scorecard/report.api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ export const EntityScorecardContent: () => JSX_2.Element;
1717
export { ScorecardErrorStatusIcon };
1818

1919
// @public
20-
export const ScorecardHomepageCard: (input: {
20+
export const ScorecardHomepageCard: (props: {
2121
metricId?: string;
2222
aggregationId?: string;
2323
showSubheader?: boolean;
2424
showInfo?: boolean;
25-
}) => JSX_2.Element | null;
25+
}) => JSX_2.Element;
2626

2727
// @public
2828
export const ScorecardPage: () => JSX_2.Element;

workspaces/scorecard/plugins/scorecard/src/alpha/extensions/homePageCards.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import { HomePageWidgetBlueprint } from '@backstage/plugin-home-react/alpha';
1818
import type { RendererProps } from '@backstage/plugin-home-react';
19-
import { ScorecardHomepageCard } from '../../components/ScorecardHomepageSection';
19+
import { ScorecardHomepageCardWithProvider } from '../../components/ScorecardHomepageSection';
2020

2121
const defaultCardLayout = {
2222
width: {
@@ -32,19 +32,19 @@ const defaultCardLayout = {
3232
} as const;
3333

3434
function AggregatedCardWithDeprecatedMetricIdContent() {
35-
return <ScorecardHomepageCard metricId="jira.open_issues" />;
35+
return <ScorecardHomepageCardWithProvider metricId="jira.open_issues" />;
3636
}
3737

3838
function AggregatedCardWithDefaultAggregationContent() {
39-
return <ScorecardHomepageCard aggregationId="github.open_prs" />;
39+
return <ScorecardHomepageCardWithProvider aggregationId="github.open_prs" />;
4040
}
4141

4242
function AggregatedCardWithJiraOpenIssuesContent() {
43-
return <ScorecardHomepageCard aggregationId="openIssuesKpi" />;
43+
return <ScorecardHomepageCardWithProvider aggregationId="openIssuesKpi" />;
4444
}
4545

4646
function AggregatedCardWithGithubOpenPrsContent() {
47-
return <ScorecardHomepageCard aggregationId="openPrsKpi" />;
47+
return <ScorecardHomepageCardWithProvider aggregationId="openPrsKpi" />;
4848
}
4949

5050
function BorderlessHomeWidgetRenderer({ Content }: RendererProps) {

workspaces/scorecard/plugins/scorecard/src/alpha/extensions/scorecardPage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ export const scorecardPage = PageBlueprint.make({
2626
path: '/scorecard/aggregations/:aggregationId/metrics/:metricId',
2727
routeRef: scorecardDrillDownRouteRef,
2828
loader: () =>
29-
import('../../pages/ScorecardPage').then(m => <m.ScorecardPage />),
29+
import('../../pages/ScorecardPage').then(m => (
30+
<m.ScorecardPageWithProvider />
31+
)),
3032
},
3133
});
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
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 { useMemo } from 'react';
18+
import type { ReactNode } from 'react';
19+
20+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
21+
22+
let queryClient: QueryClient | undefined;
23+
24+
function getQueryClient() {
25+
if (!queryClient) {
26+
queryClient = new QueryClient({
27+
defaultOptions: {
28+
queries: {
29+
staleTime: 5 * 60 * 1000, // 5 minutes
30+
gcTime: 5 * 60 * 1000, // 5 minutes
31+
retry: 1,
32+
refetchOnWindowFocus: false, // do not refetch when window regains focus
33+
},
34+
},
35+
});
36+
}
37+
return queryClient;
38+
}
39+
40+
/**
41+
* uses a singleton QueryClient to ensure cache is shared across all scorecard components.
42+
* @public
43+
*/
44+
export const ScorecardQueryProvider = ({
45+
children,
46+
}: {
47+
readonly children: ReactNode;
48+
}) => {
49+
const client = useMemo(() => getQueryClient(), []);
50+
51+
return <QueryClientProvider client={client}>{children}</QueryClientProvider>;
52+
};

workspaces/scorecard/plugins/scorecard/src/api/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import type {
2929

3030
import type { GetAggregatedScorecardEntitiesOptions } from '../components/types';
3131

32+
export { ScorecardQueryProvider } from './ScorecardQueryProvider';
33+
3234
import type {
3335
ScorecardApi,
3436
ScorecardApiClientOptions,

workspaces/scorecard/plugins/scorecard/src/components/ScorecardHomepageSection/ErrorStatePanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const ErrorStatePanel = ({
3939
data,
4040
isLoading,
4141
error: metadataError,
42-
} = useAggregationMetadata(aggregationId);
42+
} = useAggregationMetadata({ aggregationId });
4343

4444
const { title: cardTitle, description: cardDescription } =
4545
useMetricDisplayLabels({

0 commit comments

Comments
 (0)