@red-hat-developer-hub/backstage-plugin-scorecard 2.7.4 → 2.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/README.md +2 -0
- package/dist/alpha.d.ts +1 -1
- package/dist/components/AggregatedMetricCards/AverageCard/AverageCardComponent.esm.js +6 -52
- package/dist/components/AggregatedMetricCards/AverageCard/AverageCardComponent.esm.js.map +1 -1
- package/dist/components/AggregatedMetricCards/AverageCard/AverageCardPieCenterLabel.esm.js +0 -4
- package/dist/components/AggregatedMetricCards/AverageCard/AverageCardPieCenterLabel.esm.js.map +1 -1
- package/dist/components/AggregatedMetricCards/AverageCard/DonutChartTooltipContent.esm.js +50 -15
- package/dist/components/AggregatedMetricCards/AverageCard/DonutChartTooltipContent.esm.js.map +1 -1
- package/dist/components/ScorecardHomepageSection/ResponsivePieChart.esm.js +5 -4
- package/dist/components/ScorecardHomepageSection/ResponsivePieChart.esm.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/translations/de.esm.js +89 -96
- package/dist/translations/de.esm.js.map +1 -1
- package/dist/translations/es.esm.js +85 -92
- package/dist/translations/es.esm.js.map +1 -1
- package/dist/translations/fr.esm.js +87 -94
- package/dist/translations/fr.esm.js.map +1 -1
- package/dist/translations/it.esm.js +86 -93
- package/dist/translations/it.esm.js.map +1 -1
- package/dist/translations/ja.esm.js +88 -95
- package/dist/translations/ja.esm.js.map +1 -1
- package/dist/translations/ref.esm.js +2 -0
- package/dist/translations/ref.esm.js.map +1 -1
- package/dist/types/{index.d-Bzst_d5c.d.ts → index.d-LfNMVZwd.d.ts} +2 -0
- package/package.json +2 -2
- package/dist/components/AggregatedMetricCards/AverageCard/LegendTooltipContent.esm.js +0 -39
- package/dist/components/AggregatedMetricCards/AverageCard/LegendTooltipContent.esm.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @red-hat-developer-hub/backstage-plugin-scorecard
|
|
2
2
|
|
|
3
|
+
## 2.7.6
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 4b07772: Translations updated for de/es/fr/it/ja
|
|
8
|
+
- @red-hat-developer-hub/backstage-plugin-scorecard-common@2.7.6
|
|
9
|
+
|
|
10
|
+
## 2.7.5
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- 5115044: ### Threshold validation
|
|
15
|
+
|
|
16
|
+
Implemented threshold interval validation for Scorecard: joint coverage on the real line, gap detection and error messages, and overlap handling versus rule order (including aggregation KPI `options.thresholds` for `average`).
|
|
17
|
+
|
|
18
|
+
### Aggregation
|
|
19
|
+
|
|
20
|
+
For **`type: average`** aggregations, **`result.averageScore`** returned by **`GET /aggregations/:aggregationId`** (and the same shape wherever it appears) is a **portfolio percentage in \[0, 100\]** with **one decimal place** — the same scale used for **`options.thresholds`** evaluation and the homepage donut.
|
|
21
|
+
|
|
22
|
+
Previously **`averageScore`** was a **normalized ratio in \[0, 1\]** (rounded to **three** decimal places). Any consumer that treated the old value as a fraction and multiplied by **100** for display, or compared it to thresholds on a 0–100 scale without converting, must **stop scaling**: use **`averageScore`** directly as the percentage. If you stored historical API payloads, recompute or re-fetch rather than assuming the old fractional scale.
|
|
23
|
+
|
|
24
|
+
- 942a9ae: Fix average score card donut tooltip behavior and align pie chart tooltips
|
|
25
|
+
- @red-hat-developer-hub/backstage-plugin-scorecard-common@2.7.5
|
|
26
|
+
|
|
3
27
|
## 2.7.4
|
|
4
28
|
|
|
5
29
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -345,6 +345,8 @@ Define KPI ids and optional labels under **`scorecard.aggregationKPIs`** so each
|
|
|
345
345
|
|
|
346
346
|
**`type: average`** KPIs require **`options.statusScores`** (weights per threshold rule key). Optionally set **`options.thresholds`** so the API returns **`aggregationChartDisplayColor`** for the headline percentage. Behavior, validation, and drill-down notes are described in [aggregation.md](../scorecard-backend/docs/aggregation.md).
|
|
347
347
|
|
|
348
|
+
For **`type: average`**, the homepage card shows a **centered donut** with the headline percentage. Hovering the **center** opens a tooltip with **total score**, **max possible score**, and a **per-status breakdown** (from aggregation **`result.values`**). There is **no side status legend**; **`statusGrouped`** cards use a multi-slice pie with a legend instead.
|
|
349
|
+
|
|
348
350
|
#### Card props
|
|
349
351
|
|
|
350
352
|
The supported model is **a single `aggregationId` string** whose value is either:
|
package/dist/alpha.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import * as _backstage_frontend_plugin_api from '@backstage/frontend-plugin-api';
|
|
3
3
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
4
|
-
export { a as scorecardTranslationRef, s as scorecardTranslations } from './types/index.d-
|
|
4
|
+
export { a as scorecardTranslationRef, s as scorecardTranslations } from './types/index.d-LfNMVZwd.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* The primary Scorecard frontend plugin.
|
|
@@ -2,18 +2,15 @@ import { jsx, jsxs } from 'react/jsx-runtime';
|
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { useTheme } from '@mui/material/styles';
|
|
4
4
|
import { CardWrapper } from '../../Common/CardWrapper.esm.js';
|
|
5
|
-
import { SCORECARD_ERROR_STATE_COLOR } from '../../../utils/constants.esm.js';
|
|
6
5
|
import 'date-fns';
|
|
7
6
|
import { resolveStatusColor } from '../../../utils/statusUtils.esm.js';
|
|
8
|
-
import
|
|
7
|
+
import '@red-hat-developer-hub/backstage-plugin-scorecard-common';
|
|
9
8
|
import { ResponsivePieChart } from '../../ScorecardHomepageSection/ResponsivePieChart.esm.js';
|
|
10
9
|
import { CardInfoButton } from '../components/CardInfoButton.esm.js';
|
|
11
10
|
import { CardSubheader } from '../components/CardSubheader.esm.js';
|
|
12
11
|
import { CardChartContainer } from '../components/CardChartContainer.esm.js';
|
|
13
12
|
import { CardTooltip } from '../components/CardTooltip.esm.js';
|
|
14
|
-
import { LegendTooltipContent } from './LegendTooltipContent.esm.js';
|
|
15
13
|
import { DonutChartTooltipContent } from './DonutChartTooltipContent.esm.js';
|
|
16
|
-
import { CardLegendContent } from '../components/CardLegendContent.esm.js';
|
|
17
14
|
import { AverageCardPieCenterLabel } from './AverageCardPieCenterLabel.esm.js';
|
|
18
15
|
import { formatPercentage } from '../../../utils/formatPercentage.esm.js';
|
|
19
16
|
|
|
@@ -33,8 +30,6 @@ const AverageCardComponent = ({
|
|
|
33
30
|
dataTestId
|
|
34
31
|
}) => {
|
|
35
32
|
const theme = useTheme();
|
|
36
|
-
const [activeIndex, setActiveIndex] = useState(null);
|
|
37
|
-
const [tooltipPosition, setTooltipPosition] = useState(null);
|
|
38
33
|
const [centerTooltipPosition, setCenterTooltipPosition] = useState(null);
|
|
39
34
|
const updateCenterTooltipPosition = (e) => {
|
|
40
35
|
const rect = e.currentTarget.getBoundingClientRect();
|
|
@@ -43,9 +38,9 @@ const AverageCardComponent = ({
|
|
|
43
38
|
top: rect.top
|
|
44
39
|
});
|
|
45
40
|
};
|
|
46
|
-
const
|
|
47
|
-
const { fill: chartFillPercent, remainder: chartRemainderPercent } = clampPercentForDonut(
|
|
48
|
-
const centerPercentLabel = `${formatPercentage(
|
|
41
|
+
const averageScorePercent = scorecard.result.averageScore;
|
|
42
|
+
const { fill: chartFillPercent, remainder: chartRemainderPercent } = clampPercentForDonut(averageScorePercent);
|
|
43
|
+
const centerPercentLabel = `${formatPercentage(averageScorePercent)}%`;
|
|
49
44
|
const arcResolvedColor = resolveStatusColor(
|
|
50
45
|
theme,
|
|
51
46
|
scorecard.result.aggregationChartDisplayColor
|
|
@@ -62,15 +57,6 @@ const AverageCardComponent = ({
|
|
|
62
57
|
color: theme.palette.grey[300]
|
|
63
58
|
}
|
|
64
59
|
];
|
|
65
|
-
const statusPieData = scorecard.result.values?.map((value) => ({
|
|
66
|
-
name: value.name,
|
|
67
|
-
value: value.count,
|
|
68
|
-
score: value.score,
|
|
69
|
-
color: resolveStatusColor(
|
|
70
|
-
theme,
|
|
71
|
-
getThresholdRuleColor(scorecard.result.thresholds.rules, value.name) ?? SCORECARD_ERROR_STATE_COLOR
|
|
72
|
-
)
|
|
73
|
-
})) ?? [];
|
|
74
60
|
const subheader = showSubheader ? /* @__PURE__ */ jsx(
|
|
75
61
|
CardSubheader,
|
|
76
62
|
{
|
|
@@ -101,21 +87,9 @@ const AverageCardComponent = ({
|
|
|
101
87
|
...props,
|
|
102
88
|
centerPercentLabel,
|
|
103
89
|
arcResolvedColor,
|
|
104
|
-
setActiveIndex,
|
|
105
|
-
setTooltipPosition,
|
|
106
90
|
updateCenterTooltipPosition,
|
|
107
91
|
setCenterTooltipPosition
|
|
108
92
|
}
|
|
109
|
-
),
|
|
110
|
-
legendContent: (props) => /* @__PURE__ */ jsx(
|
|
111
|
-
CardLegendContent,
|
|
112
|
-
{
|
|
113
|
-
...props,
|
|
114
|
-
activeIndex,
|
|
115
|
-
setActiveIndex,
|
|
116
|
-
setTooltipPosition,
|
|
117
|
-
pieData: statusPieData
|
|
118
|
-
}
|
|
119
93
|
)
|
|
120
94
|
}
|
|
121
95
|
),
|
|
@@ -135,28 +109,8 @@ const AverageCardComponent = ({
|
|
|
135
109
|
DonutChartTooltipContent,
|
|
136
110
|
{
|
|
137
111
|
weightedSum: scorecard.result.averageWeightedSum,
|
|
138
|
-
maxPossible: scorecard.result.averageMaxPossible
|
|
139
|
-
|
|
140
|
-
)
|
|
141
|
-
}
|
|
142
|
-
),
|
|
143
|
-
activeIndex !== null && tooltipPosition && statusPieData[activeIndex] && /* @__PURE__ */ jsx(
|
|
144
|
-
CardTooltip,
|
|
145
|
-
{
|
|
146
|
-
tooltipPosition,
|
|
147
|
-
pieData: statusPieData,
|
|
148
|
-
payload: [
|
|
149
|
-
{
|
|
150
|
-
name: statusPieData[activeIndex].name,
|
|
151
|
-
value: statusPieData[activeIndex].value || 1,
|
|
152
|
-
payload: statusPieData[activeIndex]
|
|
153
|
-
}
|
|
154
|
-
],
|
|
155
|
-
customContent: /* @__PURE__ */ jsx(
|
|
156
|
-
LegendTooltipContent,
|
|
157
|
-
{
|
|
158
|
-
row: statusPieData[activeIndex],
|
|
159
|
-
maxPossible: scorecard.result.averageMaxPossible
|
|
112
|
+
maxPossible: scorecard.result.averageMaxPossible,
|
|
113
|
+
statusValues: scorecard.result.values
|
|
160
114
|
}
|
|
161
115
|
)
|
|
162
116
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AverageCardComponent.esm.js","sources":["../../../../src/components/AggregatedMetricCards/AverageCard/AverageCardComponent.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState } from 'react';\nimport type { MouseEvent } from 'react';\n\nimport { useTheme } from '@mui/material/styles';\n\nimport { CardWrapper } from '../../Common/CardWrapper';\nimport type { PieData } from '../../types';\nimport {\n getThresholdRuleColor,\n resolveStatusColor,\n SCORECARD_ERROR_STATE_COLOR,\n} from '../../../utils';\nimport { ResponsivePieChart } from '../../ScorecardHomepageSection/ResponsivePieChart';\nimport { CardInfoButton } from '../components/CardInfoButton';\nimport { CardSubheader } from '../components/CardSubheader';\nimport { CardChartContainer } from '../components/CardChartContainer';\nimport { CardTooltip } from '../components/CardTooltip';\nimport { LegendTooltipContent } from './LegendTooltipContent';\nimport { DonutChartTooltipContent } from './DonutChartTooltipContent';\nimport type { AverageCardComponentProps, TooltipPosition } from './types';\nimport { CardLegendContent } from '../components/CardLegendContent';\nimport { AverageCardPieCenterLabel } from './AverageCardPieCenterLabel';\nimport { formatPercentage } from '../../../utils/formatPercentage';\n\nconst AVERAGE_SCORE_SLICE = 'averageScoreFill';\nconst AVERAGE_REMAINDER_SLICE = 'averageScoreRemainder';\n\nfunction clampPercentForDonut(rawPercent: number): {\n fill: number;\n remainder: number;\n} {\n const fill = Math.min(100, Math.max(0, rawPercent));\n return { fill, remainder: 100 - fill };\n}\n\nexport const AverageCardComponent = ({\n scorecard,\n cardTitle,\n description,\n aggregationId,\n showSubheader = true,\n showInfo = true,\n dataTestId,\n}: AverageCardComponentProps) => {\n const theme = useTheme();\n\n const [activeIndex, setActiveIndex] = useState<number | null>(null);\n const [tooltipPosition, setTooltipPosition] =\n useState<TooltipPosition | null>(null);\n const [centerTooltipPosition, setCenterTooltipPosition] =\n useState<TooltipPosition | null>(null);\n\n const updateCenterTooltipPosition = (e: MouseEvent<SVGCircleElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n setCenterTooltipPosition({\n left: rect.left + rect.width / 2,\n top: rect.top,\n });\n };\n\n const rawPercent = scorecard.result.averageScore * 100;\n const { fill: chartFillPercent, remainder: chartRemainderPercent } =\n clampPercentForDonut(rawPercent);\n\n const centerPercentLabel = `${formatPercentage(rawPercent)}%`;\n\n const arcResolvedColor = resolveStatusColor(\n theme,\n scorecard.result.aggregationChartDisplayColor,\n );\n\n const averagePieData: PieData[] = [\n {\n name: AVERAGE_SCORE_SLICE,\n value: chartFillPercent,\n color: arcResolvedColor,\n },\n {\n name: AVERAGE_REMAINDER_SLICE,\n value: chartRemainderPercent,\n color: theme.palette.grey[300],\n },\n ];\n\n const statusPieData: PieData[] =\n scorecard.result.values?.map(value => ({\n name: value.name,\n value: value.count,\n score: value.score,\n color: resolveStatusColor(\n theme,\n getThresholdRuleColor(scorecard.result.thresholds.rules, value.name) ??\n SCORECARD_ERROR_STATE_COLOR,\n ),\n })) ?? [];\n\n const subheader = showSubheader ? (\n <CardSubheader\n aggregationId={aggregationId}\n scorecardId={scorecard.id}\n entitiesCount={scorecard.result.total}\n entitiesConsidered={scorecard.result.entitiesConsidered}\n calculationErrorCount={scorecard.result.calculationErrorCount}\n />\n ) : null;\n\n const info = showInfo ? (\n <CardInfoButton timestamp={scorecard.result.timestamp} />\n ) : null;\n\n return (\n <CardWrapper\n title={cardTitle}\n dataTestId={dataTestId}\n subheader={subheader}\n description={description}\n info={info}\n >\n <CardChartContainer>\n <ResponsivePieChart\n pieData={averagePieData}\n LabelContent={props => (\n <AverageCardPieCenterLabel\n {...props}\n centerPercentLabel={centerPercentLabel}\n arcResolvedColor={arcResolvedColor}\n setActiveIndex={setActiveIndex}\n setTooltipPosition={setTooltipPosition}\n updateCenterTooltipPosition={updateCenterTooltipPosition}\n setCenterTooltipPosition={setCenterTooltipPosition}\n />\n )}\n legendContent={props => (\n <CardLegendContent\n {...props}\n activeIndex={activeIndex}\n setActiveIndex={setActiveIndex}\n setTooltipPosition={setTooltipPosition}\n pieData={statusPieData}\n />\n )}\n />\n\n {centerTooltipPosition && (\n <CardTooltip\n tooltipPosition={centerTooltipPosition}\n pieData={averagePieData}\n payload={[\n {\n name: AVERAGE_SCORE_SLICE,\n value: 1,\n payload: averagePieData[0],\n },\n ]}\n customContent={\n <DonutChartTooltipContent\n weightedSum={scorecard.result.averageWeightedSum}\n maxPossible={scorecard.result.averageMaxPossible}\n />\n }\n />\n )}\n\n {activeIndex !== null &&\n tooltipPosition &&\n statusPieData[activeIndex] && (\n <CardTooltip\n tooltipPosition={tooltipPosition}\n pieData={statusPieData}\n payload={[\n {\n name: statusPieData[activeIndex].name,\n value: statusPieData[activeIndex].value || 1,\n payload: statusPieData[activeIndex],\n },\n ]}\n customContent={\n <LegendTooltipContent\n row={statusPieData[activeIndex]}\n maxPossible={scorecard.result.averageMaxPossible}\n />\n }\n />\n )}\n </CardChartContainer>\n </CardWrapper>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AverageCardComponent.esm.js","sources":["../../../../src/components/AggregatedMetricCards/AverageCard/AverageCardComponent.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { useState } from 'react';\nimport type { MouseEvent } from 'react';\n\nimport { useTheme } from '@mui/material/styles';\n\nimport { CardWrapper } from '../../Common/CardWrapper';\nimport type { PieData } from '../../types';\nimport { resolveStatusColor } from '../../../utils';\nimport { ResponsivePieChart } from '../../ScorecardHomepageSection/ResponsivePieChart';\nimport { CardInfoButton } from '../components/CardInfoButton';\nimport { CardSubheader } from '../components/CardSubheader';\nimport { CardChartContainer } from '../components/CardChartContainer';\nimport { CardTooltip } from '../components/CardTooltip';\nimport { DonutChartTooltipContent } from './DonutChartTooltipContent';\nimport type { AverageCardComponentProps, TooltipPosition } from './types';\nimport { AverageCardPieCenterLabel } from './AverageCardPieCenterLabel';\nimport { formatPercentage } from '../../../utils/formatPercentage';\n\nconst AVERAGE_SCORE_SLICE = 'averageScoreFill';\nconst AVERAGE_REMAINDER_SLICE = 'averageScoreRemainder';\n\nfunction clampPercentForDonut(rawPercent: number): {\n fill: number;\n remainder: number;\n} {\n const fill = Math.min(100, Math.max(0, rawPercent));\n return { fill, remainder: 100 - fill };\n}\n\nexport const AverageCardComponent = ({\n scorecard,\n cardTitle,\n description,\n aggregationId,\n showSubheader = true,\n showInfo = true,\n dataTestId,\n}: AverageCardComponentProps) => {\n const theme = useTheme();\n\n const [centerTooltipPosition, setCenterTooltipPosition] =\n useState<TooltipPosition | null>(null);\n\n const updateCenterTooltipPosition = (e: MouseEvent<SVGCircleElement>) => {\n const rect = e.currentTarget.getBoundingClientRect();\n setCenterTooltipPosition({\n left: rect.left + rect.width / 2,\n top: rect.top,\n });\n };\n\n const averageScorePercent = scorecard.result.averageScore;\n\n const { fill: chartFillPercent, remainder: chartRemainderPercent } =\n clampPercentForDonut(averageScorePercent);\n\n const centerPercentLabel = `${formatPercentage(averageScorePercent)}%`;\n\n const arcResolvedColor = resolveStatusColor(\n theme,\n scorecard.result.aggregationChartDisplayColor,\n );\n\n const averagePieData: PieData[] = [\n {\n name: AVERAGE_SCORE_SLICE,\n value: chartFillPercent,\n color: arcResolvedColor,\n },\n {\n name: AVERAGE_REMAINDER_SLICE,\n value: chartRemainderPercent,\n color: theme.palette.grey[300],\n },\n ];\n\n const subheader = showSubheader ? (\n <CardSubheader\n aggregationId={aggregationId}\n scorecardId={scorecard.id}\n entitiesCount={scorecard.result.total}\n entitiesConsidered={scorecard.result.entitiesConsidered}\n calculationErrorCount={scorecard.result.calculationErrorCount}\n />\n ) : null;\n\n const info = showInfo ? (\n <CardInfoButton timestamp={scorecard.result.timestamp} />\n ) : null;\n\n return (\n <CardWrapper\n title={cardTitle}\n dataTestId={dataTestId}\n subheader={subheader}\n description={description}\n info={info}\n >\n <CardChartContainer>\n <ResponsivePieChart\n pieData={averagePieData}\n LabelContent={props => (\n <AverageCardPieCenterLabel\n {...props}\n centerPercentLabel={centerPercentLabel}\n arcResolvedColor={arcResolvedColor}\n updateCenterTooltipPosition={updateCenterTooltipPosition}\n setCenterTooltipPosition={setCenterTooltipPosition}\n />\n )}\n />\n\n {centerTooltipPosition && (\n <CardTooltip\n tooltipPosition={centerTooltipPosition}\n pieData={averagePieData}\n payload={[\n {\n name: AVERAGE_SCORE_SLICE,\n value: 1,\n payload: averagePieData[0],\n },\n ]}\n customContent={\n <DonutChartTooltipContent\n weightedSum={scorecard.result.averageWeightedSum}\n maxPossible={scorecard.result.averageMaxPossible}\n statusValues={scorecard.result.values}\n />\n }\n />\n )}\n </CardChartContainer>\n </CardWrapper>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -6,8 +6,6 @@ function AverageCardPieCenterLabel({
|
|
|
6
6
|
index,
|
|
7
7
|
centerPercentLabel,
|
|
8
8
|
arcResolvedColor,
|
|
9
|
-
setActiveIndex,
|
|
10
|
-
setTooltipPosition,
|
|
11
9
|
updateCenterTooltipPosition,
|
|
12
10
|
setCenterTooltipPosition
|
|
13
11
|
}) {
|
|
@@ -28,8 +26,6 @@ function AverageCardPieCenterLabel({
|
|
|
28
26
|
pointerEvents: "all",
|
|
29
27
|
"data-testid": "average-card-center-percent-hit-area",
|
|
30
28
|
onMouseEnter: (e) => {
|
|
31
|
-
setActiveIndex(null);
|
|
32
|
-
setTooltipPosition(null);
|
|
33
29
|
updateCenterTooltipPosition(e);
|
|
34
30
|
},
|
|
35
31
|
onMouseMove: updateCenterTooltipPosition,
|
package/dist/components/AggregatedMetricCards/AverageCard/AverageCardPieCenterLabel.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AverageCardPieCenterLabel.esm.js","sources":["../../../../src/components/AggregatedMetricCards/AverageCard/AverageCardPieCenterLabel.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PieLabelRenderProps } from 'recharts';\nimport { TooltipPosition } from './types';\n\ntype AverageCardPieCenterLabelProps = PieLabelRenderProps & {\n centerPercentLabel: string;\n arcResolvedColor: string;\n
|
|
1
|
+
{"version":3,"file":"AverageCardPieCenterLabel.esm.js","sources":["../../../../src/components/AggregatedMetricCards/AverageCard/AverageCardPieCenterLabel.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PieLabelRenderProps } from 'recharts';\n\nimport { TooltipPosition } from './types';\n\ntype AverageCardPieCenterLabelProps = PieLabelRenderProps & {\n centerPercentLabel: string;\n arcResolvedColor: string;\n updateCenterTooltipPosition: (e: React.MouseEvent<SVGCircleElement>) => void;\n setCenterTooltipPosition: (position: TooltipPosition | null) => void;\n};\n\nexport function AverageCardPieCenterLabel({\n cx,\n cy,\n index,\n centerPercentLabel,\n arcResolvedColor,\n updateCenterTooltipPosition,\n setCenterTooltipPosition,\n}: AverageCardPieCenterLabelProps) {\n if (\n cx === undefined ||\n cx === null ||\n cy === undefined ||\n cy === null ||\n index === undefined ||\n index !== 0\n ) {\n return null;\n }\n const cxNum = Number(cx);\n const cyNum = Number(cy);\n return (\n <g style={{ cursor: 'pointer' }}>\n <circle\n cx={cxNum}\n cy={cyNum}\n r={52}\n fill=\"transparent\"\n stroke=\"none\"\n pointerEvents=\"all\"\n data-testid=\"average-card-center-percent-hit-area\"\n onMouseEnter={e => {\n updateCenterTooltipPosition(e);\n }}\n onMouseMove={updateCenterTooltipPosition}\n onMouseLeave={() => setCenterTooltipPosition(null)}\n />\n <text\n x={cxNum}\n y={cyNum}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n fill={arcResolvedColor}\n fontSize={24}\n fontWeight={500}\n pointerEvents=\"none\"\n data-testid=\"average-card-center-percent\"\n >\n {centerPercentLabel}\n </text>\n </g>\n );\n}\n"],"names":[],"mappings":";;AA2BO,SAAS,yBAA0B,CAAA;AAAA,EACxC,EAAA;AAAA,EACA,EAAA;AAAA,EACA,KAAA;AAAA,EACA,kBAAA;AAAA,EACA,gBAAA;AAAA,EACA,2BAAA;AAAA,EACA;AACF,CAAmC,EAAA;AACjC,EACE,IAAA,EAAA,KAAO,MACP,IAAA,EAAA,KAAO,IACP,IAAA,EAAA,KAAO,MACP,IAAA,EAAA,KAAO,IACP,IAAA,KAAA,KAAU,MACV,IAAA,KAAA,KAAU,CACV,EAAA;AACA,IAAO,OAAA,IAAA;AAAA;AAET,EAAM,MAAA,KAAA,GAAQ,OAAO,EAAE,CAAA;AACvB,EAAM,MAAA,KAAA,GAAQ,OAAO,EAAE,CAAA;AACvB,EAAA,4BACG,GAAE,EAAA,EAAA,KAAA,EAAO,EAAE,MAAA,EAAQ,WAClB,EAAA,QAAA,EAAA;AAAA,oBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,EAAI,EAAA,KAAA;AAAA,QACJ,EAAI,EAAA,KAAA;AAAA,QACJ,CAAG,EAAA,EAAA;AAAA,QACH,IAAK,EAAA,aAAA;AAAA,QACL,MAAO,EAAA,MAAA;AAAA,QACP,aAAc,EAAA,KAAA;AAAA,QACd,aAAY,EAAA,sCAAA;AAAA,QACZ,cAAc,CAAK,CAAA,KAAA;AACjB,UAAA,2BAAA,CAA4B,CAAC,CAAA;AAAA,SAC/B;AAAA,QACA,WAAa,EAAA,2BAAA;AAAA,QACb,YAAA,EAAc,MAAM,wBAAA,CAAyB,IAAI;AAAA;AAAA,KACnD;AAAA,oBACA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,CAAG,EAAA,KAAA;AAAA,QACH,CAAG,EAAA,KAAA;AAAA,QACH,UAAW,EAAA,QAAA;AAAA,QACX,gBAAiB,EAAA,QAAA;AAAA,QACjB,IAAM,EAAA,gBAAA;AAAA,QACN,QAAU,EAAA,EAAA;AAAA,QACV,UAAY,EAAA,GAAA;AAAA,QACZ,aAAc,EAAA,MAAA;AAAA,QACd,aAAY,EAAA,6BAAA;AAAA,QAEX,QAAA,EAAA;AAAA;AAAA;AACH,GACF,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -1,28 +1,63 @@
|
|
|
1
1
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import Box from '@mui/material/Box';
|
|
2
3
|
import Stack from '@mui/material/Stack';
|
|
3
|
-
import
|
|
4
|
+
import Typography from '@mui/material/Typography';
|
|
5
|
+
import { TooltipContent, formatAggregationScoreDetail } from './TooltipContent.esm.js';
|
|
4
6
|
import { useTranslation } from '../../../hooks/useTranslation.esm.js';
|
|
5
7
|
|
|
6
8
|
const DonutChartTooltipContent = ({
|
|
7
9
|
weightedSum,
|
|
8
|
-
maxPossible
|
|
10
|
+
maxPossible,
|
|
11
|
+
statusValues = []
|
|
9
12
|
}) => {
|
|
10
13
|
const { t } = useTranslation();
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
const getStatus = (status) => {
|
|
15
|
+
const translatedStatus = t(`thresholds.${status}`, {});
|
|
16
|
+
if (translatedStatus === `thresholds.${status}` && status) {
|
|
17
|
+
return status.charAt(0).toUpperCase() + status.slice(1);
|
|
18
|
+
}
|
|
19
|
+
return translatedStatus;
|
|
20
|
+
};
|
|
21
|
+
return /* @__PURE__ */ jsxs(Stack, { spacing: 0.5, sx: { minWidth: 220 }, children: [
|
|
22
|
+
/* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 3, children: [
|
|
23
|
+
/* @__PURE__ */ jsx(
|
|
24
|
+
TooltipContent,
|
|
25
|
+
{
|
|
26
|
+
label: t("metric.averageCenterTooltipTotalLabel"),
|
|
27
|
+
value: weightedSum
|
|
28
|
+
}
|
|
29
|
+
),
|
|
30
|
+
/* @__PURE__ */ jsx(
|
|
31
|
+
TooltipContent,
|
|
32
|
+
{
|
|
33
|
+
label: t("metric.averageCenterTooltipMaxLabel"),
|
|
34
|
+
value: maxPossible
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
] }),
|
|
38
|
+
statusValues.length > 0 ? /* @__PURE__ */ jsx(
|
|
39
|
+
Box,
|
|
14
40
|
{
|
|
15
|
-
|
|
16
|
-
|
|
41
|
+
sx: {
|
|
42
|
+
borderTop: 1,
|
|
43
|
+
borderColor: "divider",
|
|
44
|
+
pt: 1.5
|
|
45
|
+
},
|
|
46
|
+
children: /* @__PURE__ */ jsx(Stack, { spacing: 0.75, children: statusValues.map((row) => /* @__PURE__ */ jsx(
|
|
47
|
+
Typography,
|
|
48
|
+
{
|
|
49
|
+
variant: "body2",
|
|
50
|
+
sx: { color: "text.primary", fontWeight: 500 },
|
|
51
|
+
children: t("metric.averageCenterTooltipBreakdownRow", {
|
|
52
|
+
count: row.count,
|
|
53
|
+
status: getStatus(row.name),
|
|
54
|
+
score: formatAggregationScoreDetail(row.score ?? 0)
|
|
55
|
+
})
|
|
56
|
+
},
|
|
57
|
+
row.name
|
|
58
|
+
)) })
|
|
17
59
|
}
|
|
18
|
-
)
|
|
19
|
-
/* @__PURE__ */ jsx(
|
|
20
|
-
TooltipContent,
|
|
21
|
-
{
|
|
22
|
-
label: t("metric.averageCenterTooltipMaxLabel"),
|
|
23
|
-
value: maxPossible
|
|
24
|
-
}
|
|
25
|
-
)
|
|
60
|
+
) : null
|
|
26
61
|
] });
|
|
27
62
|
};
|
|
28
63
|
|
package/dist/components/AggregatedMetricCards/AverageCard/DonutChartTooltipContent.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DonutChartTooltipContent.esm.js","sources":["../../../../src/components/AggregatedMetricCards/AverageCard/DonutChartTooltipContent.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport Stack from '@mui/material/Stack';\nimport { TooltipContent } from './TooltipContent';\nimport { useTranslation } from '../../../hooks/useTranslation';\n\nexport const DonutChartTooltipContent = ({\n weightedSum,\n maxPossible,\n}: {\n weightedSum: number | undefined;\n maxPossible: number | undefined;\n}) => {\n const { t } = useTranslation();\n\n return (\n <Stack direction=\"row\" spacing={3}>\n
|
|
1
|
+
{"version":3,"file":"DonutChartTooltipContent.esm.js","sources":["../../../../src/components/AggregatedMetricCards/AverageCard/DonutChartTooltipContent.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { AggregatedMetricValue } from '@red-hat-developer-hub/backstage-plugin-scorecard-common';\nimport Box from '@mui/material/Box';\nimport Stack from '@mui/material/Stack';\nimport Typography from '@mui/material/Typography';\n\nimport { TooltipContent, formatAggregationScoreDetail } from './TooltipContent';\nimport { useTranslation } from '../../../hooks/useTranslation';\n\nexport const DonutChartTooltipContent = ({\n weightedSum,\n maxPossible,\n statusValues = [],\n}: {\n weightedSum: number | undefined;\n maxPossible: number | undefined;\n statusValues?: AggregatedMetricValue[];\n}) => {\n const { t } = useTranslation();\n\n const getStatus = (status: string) => {\n const translatedStatus = t(`thresholds.${status}` as any, {});\n\n if (translatedStatus === `thresholds.${status}` && status) {\n return status.charAt(0).toUpperCase() + status.slice(1);\n }\n\n return translatedStatus;\n };\n\n return (\n <Stack spacing={0.5} sx={{ minWidth: 220 }}>\n <Stack direction=\"row\" spacing={3}>\n <TooltipContent\n label={t('metric.averageCenterTooltipTotalLabel')}\n value={weightedSum}\n />\n <TooltipContent\n label={t('metric.averageCenterTooltipMaxLabel')}\n value={maxPossible}\n />\n </Stack>\n {statusValues.length > 0 ? (\n <Box\n sx={{\n borderTop: 1,\n borderColor: 'divider',\n pt: 1.5,\n }}\n >\n <Stack spacing={0.75}>\n {statusValues.map(row => (\n <Typography\n key={row.name}\n variant=\"body2\"\n sx={{ color: 'text.primary', fontWeight: 500 }}\n >\n {t('metric.averageCenterTooltipBreakdownRow', {\n count: row.count,\n status: getStatus(row.name),\n score: formatAggregationScoreDetail(row.score ?? 0),\n } as any)}\n </Typography>\n ))}\n </Stack>\n </Box>\n ) : null}\n </Stack>\n );\n};\n"],"names":[],"mappings":";;;;;;;AAwBO,MAAM,2BAA2B,CAAC;AAAA,EACvC,WAAA;AAAA,EACA,WAAA;AAAA,EACA,eAAe;AACjB,CAIM,KAAA;AACJ,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EAAM,MAAA,SAAA,GAAY,CAAC,MAAmB,KAAA;AACpC,IAAA,MAAM,mBAAmB,CAAE,CAAA,CAAA,WAAA,EAAc,MAAM,CAAA,CAAA,EAAW,EAAE,CAAA;AAE5D,IAAA,IAAI,gBAAqB,KAAA,CAAA,WAAA,EAAc,MAAM,CAAA,CAAA,IAAM,MAAQ,EAAA;AACzD,MAAO,OAAA,MAAA,CAAO,OAAO,CAAC,CAAA,CAAE,aAAgB,GAAA,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA;AAGxD,IAAO,OAAA,gBAAA;AAAA,GACT;AAEA,EACE,uBAAA,IAAA,CAAC,SAAM,OAAS,EAAA,GAAA,EAAK,IAAI,EAAE,QAAA,EAAU,KACnC,EAAA,QAAA,EAAA;AAAA,oBAAA,IAAA,CAAC,KAAM,EAAA,EAAA,SAAA,EAAU,KAAM,EAAA,OAAA,EAAS,CAC9B,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,EAAE,uCAAuC,CAAA;AAAA,UAChD,KAAO,EAAA;AAAA;AAAA,OACT;AAAA,sBACA,GAAA;AAAA,QAAC,cAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO,EAAE,qCAAqC,CAAA;AAAA,UAC9C,KAAO,EAAA;AAAA;AAAA;AACT,KACF,EAAA,CAAA;AAAA,IACC,YAAA,CAAa,SAAS,CACrB,mBAAA,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,EAAI,EAAA;AAAA,UACF,SAAW,EAAA,CAAA;AAAA,UACX,WAAa,EAAA,SAAA;AAAA,UACb,EAAI,EAAA;AAAA,SACN;AAAA,QAEA,8BAAC,KAAM,EAAA,EAAA,OAAA,EAAS,IACb,EAAA,QAAA,EAAA,YAAA,CAAa,IAAI,CAChB,GAAA,qBAAA,GAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YAEC,OAAQ,EAAA,OAAA;AAAA,YACR,EAAI,EAAA,EAAE,KAAO,EAAA,cAAA,EAAgB,YAAY,GAAI,EAAA;AAAA,YAE5C,YAAE,yCAA2C,EAAA;AAAA,cAC5C,OAAO,GAAI,CAAA,KAAA;AAAA,cACX,MAAA,EAAQ,SAAU,CAAA,GAAA,CAAI,IAAI,CAAA;AAAA,cAC1B,KAAO,EAAA,4BAAA,CAA6B,GAAI,CAAA,KAAA,IAAS,CAAC;AAAA,aAC5C;AAAA,WAAA;AAAA,UARH,GAAI,CAAA;AAAA,SAUZ,CACH,EAAA;AAAA;AAAA,KAEA,GAAA;AAAA,GACN,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -10,11 +10,12 @@ const ResponsivePieChart = ({
|
|
|
10
10
|
setIsInsidePieCircle
|
|
11
11
|
}) => {
|
|
12
12
|
const isTooltipEnabled = Boolean(tooltipContent);
|
|
13
|
+
const pieCx = legendContent ? "30%" : "50%";
|
|
13
14
|
return /* @__PURE__ */ jsx(ResponsiveContainer, { style: { outline: "none" }, children: /* @__PURE__ */ jsxs(PieChart, { responsive: true, children: [
|
|
14
15
|
isErrorState && /* @__PURE__ */ jsx("g", { children: /* @__PURE__ */ jsx(
|
|
15
16
|
"circle",
|
|
16
17
|
{
|
|
17
|
-
cx:
|
|
18
|
+
cx: pieCx,
|
|
18
19
|
cy: "50%",
|
|
19
20
|
r: 90,
|
|
20
21
|
fill: "transparent",
|
|
@@ -35,7 +36,7 @@ const ResponsivePieChart = ({
|
|
|
35
36
|
data: pieData,
|
|
36
37
|
dataKey: "value",
|
|
37
38
|
nameKey: "name",
|
|
38
|
-
cx:
|
|
39
|
+
cx: pieCx,
|
|
39
40
|
cy: "50%",
|
|
40
41
|
innerRadius: "78%",
|
|
41
42
|
outerRadius: "90%",
|
|
@@ -56,7 +57,7 @@ const ResponsivePieChart = ({
|
|
|
56
57
|
children: pieData.map((category) => /* @__PURE__ */ jsx(Cell, { fill: category.color }, category.name))
|
|
57
58
|
}
|
|
58
59
|
),
|
|
59
|
-
/* @__PURE__ */ jsx(
|
|
60
|
+
legendContent ? /* @__PURE__ */ jsx(
|
|
60
61
|
Legend,
|
|
61
62
|
{
|
|
62
63
|
layout: "vertical",
|
|
@@ -67,7 +68,7 @@ const ResponsivePieChart = ({
|
|
|
67
68
|
},
|
|
68
69
|
content: legendContent
|
|
69
70
|
}
|
|
70
|
-
),
|
|
71
|
+
) : null,
|
|
71
72
|
/* @__PURE__ */ jsx(Tooltip, { content: isTooltipEnabled ? tooltipContent : () => null })
|
|
72
73
|
] }) });
|
|
73
74
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResponsivePieChart.esm.js","sources":["../../../src/components/ScorecardHomepageSection/ResponsivePieChart.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n PieChart,\n Pie,\n ResponsiveContainer,\n Cell,\n Legend,\n Tooltip,\n PieLabelRenderProps,\n} from 'recharts';\nimport type { PieData } from '../types';\n\nexport interface PieTooltipPayload {\n name?: string;\n value?: number;\n payload?: {\n name: string;\n value: number;\n color?: string;\n };\n}\n\nexport interface PieLegendItem {\n value?: string;\n color?: string;\n}\n\nexport interface PieLegendContentProps {\n payload?: readonly PieLegendItem[];\n}\n\ninterface PieTooltipContentProps {\n active?: boolean;\n coordinate?: { x: number; y: number };\n payload?: readonly PieTooltipPayload[];\n label?: string | number;\n}\ninterface ResponsivePieChartProps {\n pieData: PieData[];\n LabelContent?: (props: PieLabelRenderProps) => React.ReactNode;\n legendContent
|
|
1
|
+
{"version":3,"file":"ResponsivePieChart.esm.js","sources":["../../../src/components/ScorecardHomepageSection/ResponsivePieChart.tsx"],"sourcesContent":["/*\n * Copyright Red Hat, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n PieChart,\n Pie,\n ResponsiveContainer,\n Cell,\n Legend,\n Tooltip,\n PieLabelRenderProps,\n} from 'recharts';\nimport type { PieData } from '../types';\n\nexport interface PieTooltipPayload {\n name?: string;\n value?: number;\n payload?: {\n name: string;\n value: number;\n color?: string;\n };\n}\n\nexport interface PieLegendItem {\n value?: string;\n color?: string;\n}\n\nexport interface PieLegendContentProps {\n payload?: readonly PieLegendItem[];\n}\n\ninterface PieTooltipContentProps {\n active?: boolean;\n coordinate?: { x: number; y: number };\n payload?: readonly PieTooltipPayload[];\n label?: string | number;\n}\ninterface ResponsivePieChartProps {\n pieData: PieData[];\n LabelContent?: (props: PieLabelRenderProps) => React.ReactNode;\n legendContent?: (props: PieLegendContentProps) => React.ReactNode;\n tooltipContent?: (props: PieTooltipContentProps) => React.ReactNode;\n isErrorState?: boolean;\n setIsInsidePieCircle?: (isInside: boolean) => void;\n}\n\nexport const ResponsivePieChart = ({\n pieData,\n LabelContent,\n legendContent,\n tooltipContent,\n isErrorState,\n setIsInsidePieCircle,\n}: ResponsivePieChartProps) => {\n const isTooltipEnabled = Boolean(tooltipContent);\n const pieCx = legendContent ? '30%' : '50%';\n\n return (\n <ResponsiveContainer style={{ outline: 'none' }}>\n <PieChart responsive>\n {/* This is the circle that is used to trigger the tooltip */}\n {isErrorState && (\n <g>\n <circle\n cx={pieCx}\n cy=\"50%\"\n r={90}\n fill=\"transparent\"\n style={{ cursor: 'pointer' }}\n onMouseEnter={e => {\n setIsInsidePieCircle?.(true);\n e.stopPropagation?.();\n }}\n onMouseLeave={e => {\n setIsInsidePieCircle?.(false);\n e.stopPropagation();\n }}\n />\n </g>\n )}\n\n <Pie\n data={pieData}\n dataKey=\"value\"\n nameKey=\"name\"\n cx={pieCx}\n cy=\"50%\"\n innerRadius=\"78%\"\n outerRadius=\"90%\"\n startAngle={90}\n endAngle={-270}\n stroke=\"none\"\n cursor={isTooltipEnabled ? 'pointer' : undefined}\n isAnimationActive={false}\n labelLine={false}\n label={LabelContent}\n style={{ outline: 'none' }}\n onMouseEnter={() => {\n setIsInsidePieCircle?.(true);\n }}\n onMouseLeave={() => {\n setIsInsidePieCircle?.(false);\n }}\n >\n {pieData.map(category => (\n <Cell key={category.name} fill={category.color} />\n ))}\n </Pie>\n\n {legendContent ? (\n <Legend\n layout=\"vertical\"\n verticalAlign=\"middle\"\n wrapperStyle={{\n position: 'absolute',\n left: '60%',\n }}\n content={legendContent}\n />\n ) : null}\n\n <Tooltip content={isTooltipEnabled ? tooltipContent : () => null} />\n </PieChart>\n </ResponsiveContainer>\n );\n};\n"],"names":[],"mappings":";;;AA6DO,MAAM,qBAAqB,CAAC;AAAA,EACjC,OAAA;AAAA,EACA,YAAA;AAAA,EACA,aAAA;AAAA,EACA,cAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAA+B,KAAA;AAC7B,EAAM,MAAA,gBAAA,GAAmB,QAAQ,cAAc,CAAA;AAC/C,EAAM,MAAA,KAAA,GAAQ,gBAAgB,KAAQ,GAAA,KAAA;AAEtC,EACE,uBAAA,GAAA,CAAC,mBAAoB,EAAA,EAAA,KAAA,EAAO,EAAE,OAAA,EAAS,QACrC,EAAA,QAAA,kBAAA,IAAA,CAAC,QAAS,EAAA,EAAA,UAAA,EAAU,IAEjB,EAAA,QAAA,EAAA;AAAA,IAAA,YAAA,wBACE,GACC,EAAA,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,EAAI,EAAA,KAAA;AAAA,QACJ,EAAG,EAAA,KAAA;AAAA,QACH,CAAG,EAAA,EAAA;AAAA,QACH,IAAK,EAAA,aAAA;AAAA,QACL,KAAA,EAAO,EAAE,MAAA,EAAQ,SAAU,EAAA;AAAA,QAC3B,cAAc,CAAK,CAAA,KAAA;AACjB,UAAA,oBAAA,GAAuB,IAAI,CAAA;AAC3B,UAAA,CAAA,CAAE,eAAkB,IAAA;AAAA,SACtB;AAAA,QACA,cAAc,CAAK,CAAA,KAAA;AACjB,UAAA,oBAAA,GAAuB,KAAK,CAAA;AAC5B,UAAA,CAAA,CAAE,eAAgB,EAAA;AAAA;AACpB;AAAA,KAEJ,EAAA,CAAA;AAAA,oBAGF,GAAA;AAAA,MAAC,GAAA;AAAA,MAAA;AAAA,QACC,IAAM,EAAA,OAAA;AAAA,QACN,OAAQ,EAAA,OAAA;AAAA,QACR,OAAQ,EAAA,MAAA;AAAA,QACR,EAAI,EAAA,KAAA;AAAA,QACJ,EAAG,EAAA,KAAA;AAAA,QACH,WAAY,EAAA,KAAA;AAAA,QACZ,WAAY,EAAA,KAAA;AAAA,QACZ,UAAY,EAAA,EAAA;AAAA,QACZ,QAAU,EAAA,IAAA;AAAA,QACV,MAAO,EAAA,MAAA;AAAA,QACP,MAAA,EAAQ,mBAAmB,SAAY,GAAA,MAAA;AAAA,QACvC,iBAAmB,EAAA,KAAA;AAAA,QACnB,SAAW,EAAA,KAAA;AAAA,QACX,KAAO,EAAA,YAAA;AAAA,QACP,KAAA,EAAO,EAAE,OAAA,EAAS,MAAO,EAAA;AAAA,QACzB,cAAc,MAAM;AAClB,UAAA,oBAAA,GAAuB,IAAI,CAAA;AAAA,SAC7B;AAAA,QACA,cAAc,MAAM;AAClB,UAAA,oBAAA,GAAuB,KAAK,CAAA;AAAA,SAC9B;AAAA,QAEC,QAAA,EAAA,OAAA,CAAQ,GAAI,CAAA,CAAA,QAAA,qBACV,GAAA,CAAA,IAAA,EAAA,EAAyB,MAAM,QAAS,CAAA,KAAA,EAAA,EAA9B,QAAS,CAAA,IAA4B,CACjD;AAAA;AAAA,KACH;AAAA,IAEC,aACC,mBAAA,GAAA;AAAA,MAAC,MAAA;AAAA,MAAA;AAAA,QACC,MAAO,EAAA,UAAA;AAAA,QACP,aAAc,EAAA,QAAA;AAAA,QACd,YAAc,EAAA;AAAA,UACZ,QAAU,EAAA,UAAA;AAAA,UACV,IAAM,EAAA;AAAA,SACR;AAAA,QACA,OAAS,EAAA;AAAA;AAAA,KAET,GAAA,IAAA;AAAA,wBAEH,OAAQ,EAAA,EAAA,OAAA,EAAS,gBAAmB,GAAA,cAAA,GAAiB,MAAM,IAAM,EAAA;AAAA,GAAA,EACpE,CACF,EAAA,CAAA;AAEJ;;;;"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
3
|
-
export { a as scorecardTranslationRef, s as scorecardTranslations } from './types/index.d-
|
|
3
|
+
export { a as scorecardTranslationRef, s as scorecardTranslations } from './types/index.d-LfNMVZwd.js';
|
|
4
4
|
export { default as ScorecardSuccessStatusIcon } from '@mui/icons-material/CheckCircleOutline';
|
|
5
5
|
export { default as ScorecardWarningStatusIcon } from '@mui/icons-material/WarningAmber';
|
|
6
6
|
export { default as ScorecardErrorStatusIcon } from '@mui/icons-material/DangerousOutlined';
|