@red-hat-developer-hub/backstage-plugin-scorecard 2.7.6 → 2.7.7
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 +7 -0
- package/dist/components/AggregatedMetricCards/AverageCard/DonutChartTooltipContent.esm.js +4 -8
- package/dist/components/AggregatedMetricCards/AverageCard/DonutChartTooltipContent.esm.js.map +1 -1
- package/dist/components/Scorecard/CustomLegend.esm.js +2 -5
- package/dist/components/Scorecard/CustomLegend.esm.js.map +1 -1
- package/dist/components/ScorecardHomepageSection/CustomLegend.esm.js +4 -5
- package/dist/components/ScorecardHomepageSection/CustomLegend.esm.js.map +1 -1
- package/dist/components/ScorecardHomepageSection/CustomTooltip.esm.js +5 -2
- package/dist/components/ScorecardHomepageSection/CustomTooltip.esm.js.map +1 -1
- package/dist/components/ScorecardPage/EntitiesTable/cells/MetricStatusCell.esm.js +2 -5
- package/dist/components/ScorecardPage/EntitiesTable/cells/MetricStatusCell.esm.js.map +1 -1
- package/dist/utils/statusUtils.esm.js +12 -1
- package/dist/utils/statusUtils.esm.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @red-hat-developer-hub/backstage-plugin-scorecard
|
|
2
2
|
|
|
3
|
+
## 2.7.7
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8414dbe: Fixes severity threshold category translation for custom thresholds
|
|
8
|
+
- @red-hat-developer-hub/backstage-plugin-scorecard-common@2.7.7
|
|
9
|
+
|
|
3
10
|
## 2.7.6
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
|
@@ -4,6 +4,9 @@ import Stack from '@mui/material/Stack';
|
|
|
4
4
|
import Typography from '@mui/material/Typography';
|
|
5
5
|
import { TooltipContent, formatAggregationScoreDetail } from './TooltipContent.esm.js';
|
|
6
6
|
import { useTranslation } from '../../../hooks/useTranslation.esm.js';
|
|
7
|
+
import 'date-fns';
|
|
8
|
+
import { getTranslatedStatus } from '../../../utils/statusUtils.esm.js';
|
|
9
|
+
import '@red-hat-developer-hub/backstage-plugin-scorecard-common';
|
|
7
10
|
|
|
8
11
|
const DonutChartTooltipContent = ({
|
|
9
12
|
weightedSum,
|
|
@@ -11,13 +14,6 @@ const DonutChartTooltipContent = ({
|
|
|
11
14
|
statusValues = []
|
|
12
15
|
}) => {
|
|
13
16
|
const { t } = useTranslation();
|
|
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
17
|
return /* @__PURE__ */ jsxs(Stack, { spacing: 0.5, sx: { minWidth: 220 }, children: [
|
|
22
18
|
/* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: 3, children: [
|
|
23
19
|
/* @__PURE__ */ jsx(
|
|
@@ -50,7 +46,7 @@ const DonutChartTooltipContent = ({
|
|
|
50
46
|
sx: { color: "text.primary", fontWeight: 500 },
|
|
51
47
|
children: t("metric.averageCenterTooltipBreakdownRow", {
|
|
52
48
|
count: row.count,
|
|
53
|
-
status:
|
|
49
|
+
status: getTranslatedStatus(row.name, t),
|
|
54
50
|
score: formatAggregationScoreDetail(row.score ?? 0)
|
|
55
51
|
})
|
|
56
52
|
},
|
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 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
|
|
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';\nimport { getTranslatedStatus } from '../../../utils';\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 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: getTranslatedStatus(row.name, t),\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":";;;;;;;;;;AAyBO,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,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,MAAQ,EAAA,mBAAA,CAAoB,GAAI,CAAA,IAAA,EAAM,CAAC,CAAA;AAAA,cACvC,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;;;;"}
|
|
@@ -5,7 +5,7 @@ import { useTheme, styled } from '@mui/material/styles';
|
|
|
5
5
|
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
6
6
|
import { SCORECARD_ERROR_STATE_COLOR } from '../../utils/constants.esm.js';
|
|
7
7
|
import 'date-fns';
|
|
8
|
-
import { resolveStatusColor } from '../../utils/statusUtils.esm.js';
|
|
8
|
+
import { resolveStatusColor, getTranslatedStatus } from '../../utils/statusUtils.esm.js';
|
|
9
9
|
import { getThresholdRuleColor } from '../../utils/thresholdUtils.esm.js';
|
|
10
10
|
|
|
11
11
|
const StyledLegend = styled(Box)(({ theme }) => ({
|
|
@@ -57,10 +57,7 @@ const CustomLegend = (props) => {
|
|
|
57
57
|
variant: "body2",
|
|
58
58
|
sx: { fontSize: "0.875rem", fontWeight: 400 },
|
|
59
59
|
children: [
|
|
60
|
-
(
|
|
61
|
-
const translated = t(`thresholds.${ruleKey}`, {});
|
|
62
|
-
return translated === `thresholds.${ruleKey}` ? ruleKey.charAt(0).toUpperCase() + ruleKey.slice(1) : translated;
|
|
63
|
-
})(),
|
|
60
|
+
getTranslatedStatus(ruleKey, t),
|
|
64
61
|
ruleExpression && !/^==(?:true|false)$/.test(ruleExpression) && ` ${ruleExpression}`
|
|
65
62
|
]
|
|
66
63
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomLegend.esm.js","sources":["../../../src/components/Scorecard/CustomLegend.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 ThresholdResult,\n ThresholdRule,\n} from '@red-hat-developer-hub/backstage-plugin-scorecard-common';\n\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport { styled, useTheme } from '@mui/material/styles';\n\nimport { useTranslation } from '../../hooks/useTranslation';\nimport {\n getThresholdRuleColor,\n resolveStatusColor,\n SCORECARD_ERROR_STATE_COLOR,\n} from '../../utils';\n\nconst StyledLegend = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1),\n paddingLeft: theme.spacing(3.2),\n}));\n\nconst StyledLegendItem = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n}));\n\nconst StyledLegendColorBox = styled(Box)<{ color: string }>(({ color }) => ({\n width: '10px',\n height: '10px',\n backgroundColor: color,\n flexShrink: 0,\n}));\n\ntype CustomLegendProps = {\n thresholds?: ThresholdResult;\n};\n\nconst CustomLegend = (props: CustomLegendProps) => {\n const { thresholds } = props;\n const theme = useTheme();\n const { t } = useTranslation();\n\n if (\n !thresholds ||\n thresholds?.definition?.rules?.length === 0 ||\n thresholds?.definition?.rules === undefined\n ) {\n return (\n <StyledLegend>\n <StyledLegendItem>\n <StyledLegendColorBox color={theme.palette.grey['400']} /> --\n </StyledLegendItem>\n </StyledLegend>\n );\n }\n\n return (\n <StyledLegend>\n {thresholds?.definition?.rules?.map(\n ({ key: ruleKey, expression: ruleExpression }: ThresholdRule) => {\n return (\n <StyledLegendItem key={`legend-${ruleKey}`}>\n <StyledLegendColorBox\n data-testid={`legend-colorbox-${ruleKey}`}\n color={resolveStatusColor(\n theme,\n getThresholdRuleColor(\n thresholds.definition?.rules ?? [],\n ruleKey,\n ) ?? SCORECARD_ERROR_STATE_COLOR,\n )}\n />\n <Typography\n variant=\"body2\"\n sx={{ fontSize: '0.875rem', fontWeight: 400 }}\n >\n {(
|
|
1
|
+
{"version":3,"file":"CustomLegend.esm.js","sources":["../../../src/components/Scorecard/CustomLegend.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 ThresholdResult,\n ThresholdRule,\n} from '@red-hat-developer-hub/backstage-plugin-scorecard-common';\n\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport { styled, useTheme } from '@mui/material/styles';\n\nimport { useTranslation } from '../../hooks/useTranslation';\nimport {\n getTranslatedStatus,\n getThresholdRuleColor,\n resolveStatusColor,\n SCORECARD_ERROR_STATE_COLOR,\n} from '../../utils';\n\nconst StyledLegend = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1),\n paddingLeft: theme.spacing(3.2),\n}));\n\nconst StyledLegendItem = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n}));\n\nconst StyledLegendColorBox = styled(Box)<{ color: string }>(({ color }) => ({\n width: '10px',\n height: '10px',\n backgroundColor: color,\n flexShrink: 0,\n}));\n\ntype CustomLegendProps = {\n thresholds?: ThresholdResult;\n};\n\nconst CustomLegend = (props: CustomLegendProps) => {\n const { thresholds } = props;\n const theme = useTheme();\n const { t } = useTranslation();\n\n if (\n !thresholds ||\n thresholds?.definition?.rules?.length === 0 ||\n thresholds?.definition?.rules === undefined\n ) {\n return (\n <StyledLegend>\n <StyledLegendItem>\n <StyledLegendColorBox color={theme.palette.grey['400']} /> --\n </StyledLegendItem>\n </StyledLegend>\n );\n }\n\n return (\n <StyledLegend>\n {thresholds?.definition?.rules?.map(\n ({ key: ruleKey, expression: ruleExpression }: ThresholdRule) => {\n return (\n <StyledLegendItem key={`legend-${ruleKey}`}>\n <StyledLegendColorBox\n data-testid={`legend-colorbox-${ruleKey}`}\n color={resolveStatusColor(\n theme,\n getThresholdRuleColor(\n thresholds.definition?.rules ?? [],\n ruleKey,\n ) ?? SCORECARD_ERROR_STATE_COLOR,\n )}\n />\n <Typography\n variant=\"body2\"\n sx={{ fontSize: '0.875rem', fontWeight: 400 }}\n >\n {getTranslatedStatus(ruleKey, t)}\n {ruleExpression &&\n !/^==(?:true|false)$/.test(ruleExpression) &&\n ` ${ruleExpression}`}\n </Typography>\n </StyledLegendItem>\n );\n },\n )}\n </StyledLegend>\n );\n};\n\nexport default CustomLegend;\n"],"names":[],"mappings":";;;;;;;;;;AAiCA,MAAM,eAAe,MAAO,CAAA,GAAG,EAAE,CAAC,EAAE,OAAa,MAAA;AAAA,EAC/C,OAAS,EAAA,MAAA;AAAA,EACT,aAAe,EAAA,QAAA;AAAA,EACf,GAAA,EAAK,KAAM,CAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,EACpB,WAAA,EAAa,KAAM,CAAA,OAAA,CAAQ,GAAG;AAChC,CAAE,CAAA,CAAA;AAEF,MAAM,mBAAmB,MAAO,CAAA,GAAG,EAAE,CAAC,EAAE,OAAa,MAAA;AAAA,EACnD,OAAS,EAAA,MAAA;AAAA,EACT,UAAY,EAAA,QAAA;AAAA,EACZ,GAAA,EAAK,KAAM,CAAA,OAAA,CAAQ,CAAC;AACtB,CAAE,CAAA,CAAA;AAEF,MAAM,uBAAuB,MAAO,CAAA,GAAG,EAAqB,CAAC,EAAE,OAAa,MAAA;AAAA,EAC1E,KAAO,EAAA,MAAA;AAAA,EACP,MAAQ,EAAA,MAAA;AAAA,EACR,eAAiB,EAAA,KAAA;AAAA,EACjB,UAAY,EAAA;AACd,CAAE,CAAA,CAAA;AAMI,MAAA,YAAA,GAAe,CAAC,KAA6B,KAAA;AACjD,EAAM,MAAA,EAAE,YAAe,GAAA,KAAA;AACvB,EAAA,MAAM,QAAQ,QAAS,EAAA;AACvB,EAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAE7B,EACE,IAAA,CAAC,UACD,IAAA,UAAA,EAAY,UAAY,EAAA,KAAA,EAAO,WAAW,CAC1C,IAAA,UAAA,EAAY,UAAY,EAAA,KAAA,KAAU,MAClC,EAAA;AACA,IACE,uBAAA,GAAA,CAAC,YACC,EAAA,EAAA,QAAA,kBAAA,IAAA,CAAC,gBACC,EAAA,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,wBAAqB,KAAO,EAAA,KAAA,CAAM,OAAQ,CAAA,IAAA,CAAK,KAAK,CAAG,EAAA,CAAA;AAAA,MAAE;AAAA,KAAA,EAC5D,CACF,EAAA,CAAA;AAAA;AAIJ,EAAA,uBACG,GAAA,CAAA,YAAA,EAAA,EACE,QAAY,EAAA,UAAA,EAAA,UAAA,EAAY,KAAO,EAAA,GAAA;AAAA,IAC9B,CAAC,EAAE,GAAA,EAAK,OAAS,EAAA,UAAA,EAAY,gBAAoC,KAAA;AAC/D,MAAA,4BACG,gBACC,EAAA,EAAA,QAAA,EAAA;AAAA,wBAAA,GAAA;AAAA,UAAC,oBAAA;AAAA,UAAA;AAAA,YACC,aAAA,EAAa,mBAAmB,OAAO,CAAA,CAAA;AAAA,YACvC,KAAO,EAAA,kBAAA;AAAA,cACL,KAAA;AAAA,cACA,qBAAA;AAAA,gBACE,UAAA,CAAW,UAAY,EAAA,KAAA,IAAS,EAAC;AAAA,gBACjC;AAAA,eACG,IAAA;AAAA;AACP;AAAA,SACF;AAAA,wBACA,IAAA;AAAA,UAAC,UAAA;AAAA,UAAA;AAAA,YACC,OAAQ,EAAA,OAAA;AAAA,YACR,EAAI,EAAA,EAAE,QAAU,EAAA,UAAA,EAAY,YAAY,GAAI,EAAA;AAAA,YAE3C,QAAA,EAAA;AAAA,cAAA,mBAAA,CAAoB,SAAS,CAAC,CAAA;AAAA,cAC9B,kBACC,CAAC,oBAAA,CAAqB,KAAK,cAAc,CAAA,IACzC,IAAI,cAAc,CAAA;AAAA;AAAA;AAAA;AACtB,OAnBqB,EAAA,EAAA,CAAA,OAAA,EAAU,OAAO,CAoBxC,CAAA,CAAA;AAAA;AAEJ,GAEJ,EAAA,CAAA;AAEJ;;;;"}
|
|
@@ -3,6 +3,9 @@ import Box from '@mui/material/Box';
|
|
|
3
3
|
import Typography from '@mui/material/Typography';
|
|
4
4
|
import { styled } from '@mui/material/styles';
|
|
5
5
|
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
6
|
+
import 'date-fns';
|
|
7
|
+
import { getTranslatedStatus } from '../../utils/statusUtils.esm.js';
|
|
8
|
+
import '@red-hat-developer-hub/backstage-plugin-scorecard-common';
|
|
6
9
|
|
|
7
10
|
const StyledLegend = styled(Box)(({ theme }) => ({
|
|
8
11
|
display: "flex",
|
|
@@ -77,11 +80,7 @@ const CustomLegend = (props) => {
|
|
|
77
80
|
{
|
|
78
81
|
variant: "body2",
|
|
79
82
|
sx: { fontSize: "0.875rem", fontWeight: 400 },
|
|
80
|
-
children: (
|
|
81
|
-
const translated = t(`thresholds.${category.name}`, {});
|
|
82
|
-
const label = typeof translated === "string" && translated.startsWith("thresholds.") ? category.name : translated;
|
|
83
|
-
return label.charAt(0).toUpperCase() + label.slice(1);
|
|
84
|
-
})()
|
|
83
|
+
children: getTranslatedStatus(category.name, t)
|
|
85
84
|
}
|
|
86
85
|
)
|
|
87
86
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomLegend.esm.js","sources":["../../../src/components/ScorecardHomepageSection/CustomLegend.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 Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport { styled } from '@mui/material/styles';\n\nimport type { PieData as PieDataProps } from '../types';\nimport { useTranslation } from '../../hooks/useTranslation';\n\nconst StyledLegend = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1),\n paddingLeft: theme.spacing(3.2),\n}));\n\nconst StyledLegendItem = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n cursor: 'pointer',\n}));\n\nconst StyledLegendColorBox = styled(Box)<{ color?: string }>(\n ({ color = 'success.main' }) => ({\n width: '10px',\n height: '10px',\n backgroundColor: color,\n flexShrink: 0,\n }),\n);\n\ntype CustomLegendProps = {\n pieData: PieDataProps[];\n activeIndex: number | null;\n setActiveIndex: (index: number | null) => void;\n setTooltipPosition: (position: { left: number; top: number } | null) => void;\n};\n\nconst CustomLegend = (props: CustomLegendProps) => {\n const { pieData, activeIndex, setActiveIndex, setTooltipPosition } = props;\n const { t } = useTranslation();\n if (!pieData || pieData.length === 0) return null;\n\n return (\n <StyledLegend\n onMouseLeave={() => {\n setActiveIndex(null);\n setTooltipPosition(null);\n }}\n >\n {pieData.map((category: PieDataProps, index: number) => {\n return (\n <StyledLegendItem\n key={`legend-${category.name}`}\n onMouseEnter={e => {\n if (activeIndex === index) return;\n setActiveIndex(index);\n const rect = e.currentTarget.getBoundingClientRect();\n setTooltipPosition({\n left: rect.left + rect.width / 2,\n top: rect.top,\n });\n }}\n onMouseMove={e => {\n if (activeIndex === index) return;\n const rect = e.currentTarget.getBoundingClientRect();\n setTooltipPosition({\n left: rect.left + rect.width / 2,\n top: rect.top,\n });\n }}\n onMouseLeave={e => {\n const relatedTarget = e.relatedTarget as Node | null;\n const currentTarget = e.currentTarget;\n\n if (\n !relatedTarget ||\n !(relatedTarget instanceof Node) ||\n !currentTarget.contains(relatedTarget)\n ) {\n setActiveIndex(null);\n setTooltipPosition(null);\n }\n }}\n >\n <StyledLegendColorBox\n data-testid={`legend-colorbox-${category.name}`}\n color={category?.color}\n />\n <Typography\n variant=\"body2\"\n sx={{ fontSize: '0.875rem', fontWeight: 400 }}\n >\n {(
|
|
1
|
+
{"version":3,"file":"CustomLegend.esm.js","sources":["../../../src/components/ScorecardHomepageSection/CustomLegend.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 Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport { styled } from '@mui/material/styles';\n\nimport type { PieData as PieDataProps } from '../types';\nimport { useTranslation } from '../../hooks/useTranslation';\nimport { getTranslatedStatus } from '../../utils';\n\nconst StyledLegend = styled(Box)(({ theme }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1),\n paddingLeft: theme.spacing(3.2),\n}));\n\nconst StyledLegendItem = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n cursor: 'pointer',\n}));\n\nconst StyledLegendColorBox = styled(Box)<{ color?: string }>(\n ({ color = 'success.main' }) => ({\n width: '10px',\n height: '10px',\n backgroundColor: color,\n flexShrink: 0,\n }),\n);\n\ntype CustomLegendProps = {\n pieData: PieDataProps[];\n activeIndex: number | null;\n setActiveIndex: (index: number | null) => void;\n setTooltipPosition: (position: { left: number; top: number } | null) => void;\n};\n\nconst CustomLegend = (props: CustomLegendProps) => {\n const { pieData, activeIndex, setActiveIndex, setTooltipPosition } = props;\n const { t } = useTranslation();\n if (!pieData || pieData.length === 0) return null;\n\n return (\n <StyledLegend\n onMouseLeave={() => {\n setActiveIndex(null);\n setTooltipPosition(null);\n }}\n >\n {pieData.map((category: PieDataProps, index: number) => {\n return (\n <StyledLegendItem\n key={`legend-${category.name}`}\n onMouseEnter={e => {\n if (activeIndex === index) return;\n setActiveIndex(index);\n const rect = e.currentTarget.getBoundingClientRect();\n setTooltipPosition({\n left: rect.left + rect.width / 2,\n top: rect.top,\n });\n }}\n onMouseMove={e => {\n if (activeIndex === index) return;\n const rect = e.currentTarget.getBoundingClientRect();\n setTooltipPosition({\n left: rect.left + rect.width / 2,\n top: rect.top,\n });\n }}\n onMouseLeave={e => {\n const relatedTarget = e.relatedTarget as Node | null;\n const currentTarget = e.currentTarget;\n\n if (\n !relatedTarget ||\n !(relatedTarget instanceof Node) ||\n !currentTarget.contains(relatedTarget)\n ) {\n setActiveIndex(null);\n setTooltipPosition(null);\n }\n }}\n >\n <StyledLegendColorBox\n data-testid={`legend-colorbox-${category.name}`}\n color={category?.color}\n />\n <Typography\n variant=\"body2\"\n sx={{ fontSize: '0.875rem', fontWeight: 400 }}\n >\n {getTranslatedStatus(category.name, t)}\n </Typography>\n </StyledLegendItem>\n );\n })}\n </StyledLegend>\n );\n};\n\nexport default CustomLegend;\n"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,9 @@ import Box from '@mui/material/Box';
|
|
|
3
3
|
import Paper from '@mui/material/Paper';
|
|
4
4
|
import Typography from '@mui/material/Typography';
|
|
5
5
|
import { useTranslation } from '../../hooks/useTranslation.esm.js';
|
|
6
|
+
import 'date-fns';
|
|
7
|
+
import { getTranslatedStatus } from '../../utils/statusUtils.esm.js';
|
|
8
|
+
import '@red-hat-developer-hub/backstage-plugin-scorecard-common';
|
|
6
9
|
|
|
7
10
|
const CustomTooltip = ({
|
|
8
11
|
payload,
|
|
@@ -31,8 +34,8 @@ const CustomTooltip = ({
|
|
|
31
34
|
contentElement = /* @__PURE__ */ jsx(Box, { sx: { m: 0 }, children: customContent });
|
|
32
35
|
}
|
|
33
36
|
} else if (payload?.[0]?.value === 0 || payload?.[0]?.value === void 0) {
|
|
34
|
-
const
|
|
35
|
-
contentElement = /* @__PURE__ */ jsx(Typography, { sx: { fontSize: "0.875rem", margin: 0, fontWeight: "500" }, children: t("thresholds.noEntities", { category:
|
|
37
|
+
const translatedStatus = getTranslatedStatus(payload?.[0]?.name, t);
|
|
38
|
+
contentElement = /* @__PURE__ */ jsx(Typography, { sx: { fontSize: "0.875rem", margin: 0, fontWeight: "500" }, children: t("thresholds.noEntities", { category: translatedStatus }) });
|
|
36
39
|
} else {
|
|
37
40
|
contentElement = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
38
41
|
/* @__PURE__ */ jsx(Typography, { sx: { fontSize: "0.875rem", margin: 0, fontWeight: "500" }, children: t("thresholds.entities", { count: payload?.[0]?.value }) }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomTooltip.esm.js","sources":["../../../src/components/ScorecardHomepageSection/CustomTooltip.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 { ReactNode } from 'react';\nimport type { TooltipProps } from 'recharts';\n\nimport Box from '@mui/material/Box';\nimport Paper from '@mui/material/Paper';\nimport Typography from '@mui/material/Typography';\n\nimport type { PieData } from '../types';\nimport { useTranslation } from '../../hooks/useTranslation';\n\nexport type CustomTooltipPayload = {\n name?: string;\n value?: number;\n payload?: PieData;\n};\n\ntype CustomTooltipProps = TooltipProps<number, string> & {\n payload?: readonly CustomTooltipPayload[];\n pieData: PieData[];\n customContent?: string | React.ReactNode;\n};\n\nexport const CustomTooltip = ({\n payload,\n pieData,\n customContent,\n}: CustomTooltipProps) => {\n const { t } = useTranslation();\n\n const getPercentage = () => {\n if (!Array.isArray(pieData) || pieData.length === 0) return 0;\n if (!payload || payload.length === 0) return 0;\n\n const total = pieData.reduce(\n (acc: number, curr: PieData) => acc + (curr.value || 0),\n 0,\n );\n const threshold = pieData.find(\n (item: PieData) => item.name === payload?.[0]?.name,\n );\n\n const thresholdValue = threshold?.value || 0;\n\n return total > 0 ? Math.round((thresholdValue / total) * 100) : 0;\n };\n\n let contentElement = null;\n\n if (\n customContent !== undefined &&\n customContent !== null &&\n customContent !== ''\n ) {\n if (typeof customContent === 'string') {\n contentElement = (\n <Typography sx={{ fontSize: '0.875rem', margin: 0, fontWeight: '500' }}>\n {customContent}\n </Typography>\n );\n } else {\n contentElement = <Box sx={{ m: 0 }}>{customContent as ReactNode}</Box>;\n }\n } else if (payload?.[0]?.value === 0 || payload?.[0]?.value === undefined) {\n const
|
|
1
|
+
{"version":3,"file":"CustomTooltip.esm.js","sources":["../../../src/components/ScorecardHomepageSection/CustomTooltip.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 { ReactNode } from 'react';\nimport type { TooltipProps } from 'recharts';\n\nimport Box from '@mui/material/Box';\nimport Paper from '@mui/material/Paper';\nimport Typography from '@mui/material/Typography';\n\nimport type { PieData } from '../types';\nimport { useTranslation } from '../../hooks/useTranslation';\nimport { getTranslatedStatus } from '../../utils';\n\nexport type CustomTooltipPayload = {\n name?: string;\n value?: number;\n payload?: PieData;\n};\n\ntype CustomTooltipProps = TooltipProps<number, string> & {\n payload?: readonly CustomTooltipPayload[];\n pieData: PieData[];\n customContent?: string | React.ReactNode;\n};\n\nexport const CustomTooltip = ({\n payload,\n pieData,\n customContent,\n}: CustomTooltipProps) => {\n const { t } = useTranslation();\n\n const getPercentage = () => {\n if (!Array.isArray(pieData) || pieData.length === 0) return 0;\n if (!payload || payload.length === 0) return 0;\n\n const total = pieData.reduce(\n (acc: number, curr: PieData) => acc + (curr.value || 0),\n 0,\n );\n const threshold = pieData.find(\n (item: PieData) => item.name === payload?.[0]?.name,\n );\n\n const thresholdValue = threshold?.value || 0;\n\n return total > 0 ? Math.round((thresholdValue / total) * 100) : 0;\n };\n\n let contentElement = null;\n\n if (\n customContent !== undefined &&\n customContent !== null &&\n customContent !== ''\n ) {\n if (typeof customContent === 'string') {\n contentElement = (\n <Typography sx={{ fontSize: '0.875rem', margin: 0, fontWeight: '500' }}>\n {customContent}\n </Typography>\n );\n } else {\n contentElement = <Box sx={{ m: 0 }}>{customContent as ReactNode}</Box>;\n }\n } else if (payload?.[0]?.value === 0 || payload?.[0]?.value === undefined) {\n const translatedStatus = getTranslatedStatus(payload?.[0]?.name, t);\n contentElement = (\n <Typography sx={{ fontSize: '0.875rem', margin: 0, fontWeight: '500' }}>\n {t('thresholds.noEntities', { category: translatedStatus } as any)}\n </Typography>\n );\n } else {\n contentElement = (\n <>\n <Typography sx={{ fontSize: '0.875rem', margin: 0, fontWeight: '500' }}>\n {t('thresholds.entities', { count: payload?.[0]?.value })}\n </Typography>\n <Typography\n sx={{\n fontSize: '2.5rem',\n margin: 0,\n color: '#37a3a3',\n fontWeight: 500,\n }}\n >\n {getPercentage()}%\n </Typography>\n </>\n );\n }\n\n return (\n <Paper\n elevation={1}\n sx={{\n width:\n payload?.[0]?.value === 0 || payload?.[0]?.value === undefined\n ? '220px'\n : 'auto',\n padding: '16px',\n borderRadius: '12px',\n boxShadow: '0 1px 2px 0 rgba(0, 0, 0, 0.50)',\n border: theme => `1px solid ${theme.palette.grey[300]}`,\n }}\n >\n {contentElement}\n </Paper>\n );\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import { jsxs, jsx } from 'react/jsx-runtime';
|
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
import Box from '@mui/material/Box';
|
|
4
4
|
import 'date-fns';
|
|
5
|
-
import { resolveStatusColor } from '../../../../utils/statusUtils.esm.js';
|
|
5
|
+
import { getTranslatedStatus, resolveStatusColor } from '../../../../utils/statusUtils.esm.js';
|
|
6
6
|
import '@red-hat-developer-hub/backstage-plugin-scorecard-common';
|
|
7
7
|
import { useTranslation } from '../../../../hooks/useTranslation.esm.js';
|
|
8
8
|
|
|
@@ -13,10 +13,7 @@ const MetricStatusCell = memo(
|
|
|
13
13
|
statusColor
|
|
14
14
|
}) => {
|
|
15
15
|
const { t } = useTranslation();
|
|
16
|
-
|
|
17
|
-
if (translatedStatus === `thresholds.${status}` && status) {
|
|
18
|
-
translatedStatus = status?.charAt(0).toUpperCase() + status?.slice(1);
|
|
19
|
-
}
|
|
16
|
+
const translatedStatus = getTranslatedStatus(status, t);
|
|
20
17
|
return /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
|
|
21
18
|
/* @__PURE__ */ jsx(
|
|
22
19
|
Box,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetricStatusCell.esm.js","sources":["../../../../../src/components/ScorecardPage/EntitiesTable/cells/MetricStatusCell.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 { memo } from 'react';\n\nimport Box from '@mui/material/Box';\nimport { resolveStatusColor } from '../../../../utils';\nimport { useTranslation } from '../../../../hooks/useTranslation';\n\nexport const MetricStatusCell = memo(\n ({\n status,\n theme,\n statusColor,\n }: {\n status: string | undefined;\n theme: any;\n statusColor: string;\n }) => {\n const { t } = useTranslation();\n
|
|
1
|
+
{"version":3,"file":"MetricStatusCell.esm.js","sources":["../../../../../src/components/ScorecardPage/EntitiesTable/cells/MetricStatusCell.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 { memo } from 'react';\n\nimport Box from '@mui/material/Box';\nimport { getTranslatedStatus, resolveStatusColor } from '../../../../utils';\nimport { useTranslation } from '../../../../hooks/useTranslation';\n\nexport const MetricStatusCell = memo(\n ({\n status,\n theme,\n statusColor,\n }: {\n status: string | undefined;\n theme: any;\n statusColor: string;\n }) => {\n const { t } = useTranslation();\n const translatedStatus = getTranslatedStatus(status, t);\n\n return (\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <Box\n sx={{\n width: 10,\n height: 10,\n backgroundColor: resolveStatusColor(theme, statusColor),\n flexShrink: 0,\n }}\n />\n {(status && translatedStatus) || '--'}\n </Box>\n );\n },\n);\n"],"names":[],"mappings":";;;;;;;;AAsBO,MAAM,gBAAmB,GAAA,IAAA;AAAA,EAC9B,CAAC;AAAA,IACC,MAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GAKI,KAAA;AACJ,IAAM,MAAA,EAAE,CAAE,EAAA,GAAI,cAAe,EAAA;AAC7B,IAAM,MAAA,gBAAA,GAAmB,mBAAoB,CAAA,MAAA,EAAQ,CAAC,CAAA;AAEtD,IACE,uBAAA,IAAA,CAAC,GAAI,EAAA,EAAA,EAAA,EAAI,EAAE,OAAA,EAAS,QAAQ,UAAY,EAAA,QAAA,EAAU,GAAK,EAAA,CAAA,EACrD,EAAA,QAAA,EAAA;AAAA,sBAAA,GAAA;AAAA,QAAC,GAAA;AAAA,QAAA;AAAA,UACC,EAAI,EAAA;AAAA,YACF,KAAO,EAAA,EAAA;AAAA,YACP,MAAQ,EAAA,EAAA;AAAA,YACR,eAAA,EAAiB,kBAAmB,CAAA,KAAA,EAAO,WAAW,CAAA;AAAA,YACtD,UAAY,EAAA;AAAA;AACd;AAAA,OACF;AAAA,MACE,UAAU,gBAAqB,IAAA;AAAA,KACnC,EAAA,CAAA;AAAA;AAGN;;;;"}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import { SCORECARD_ERROR_STATE_COLOR } from './constants.esm.js';
|
|
2
2
|
import { getThresholdRuleColor, getThresholdRuleIcon } from './thresholdUtils.esm.js';
|
|
3
3
|
|
|
4
|
+
const getTranslatedStatus = (status, t) => {
|
|
5
|
+
if (!status) {
|
|
6
|
+
return "";
|
|
7
|
+
}
|
|
8
|
+
const translationKey = `thresholds.${status}`;
|
|
9
|
+
const translatedStatus = t(translationKey, {});
|
|
10
|
+
if (translatedStatus === translationKey) {
|
|
11
|
+
return status.charAt(0).toUpperCase() + status.slice(1);
|
|
12
|
+
}
|
|
13
|
+
return translatedStatus;
|
|
14
|
+
};
|
|
4
15
|
const getStatusConfig = ({
|
|
5
16
|
evaluation,
|
|
6
17
|
thresholdStatus,
|
|
@@ -36,5 +47,5 @@ const resolveStatusColor = (theme, statusColor) => {
|
|
|
36
47
|
return theme.palette?.rhdh?.general?.cardBorderColor ?? theme.palette.error.main;
|
|
37
48
|
};
|
|
38
49
|
|
|
39
|
-
export { getStatusConfig, resolveStatusColor };
|
|
50
|
+
export { getStatusConfig, getTranslatedStatus, resolveStatusColor };
|
|
40
51
|
//# sourceMappingURL=statusUtils.esm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statusUtils.esm.js","sources":["../../src/utils/statusUtils.ts"],"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 { Theme } from '@mui/material/styles';\nimport type { ThresholdRule } from '@red-hat-developer-hub/backstage-plugin-scorecard-common';\nimport type { ThemeConfig } from '@red-hat-developer-hub/backstage-plugin-theme';\n\nimport { SCORECARD_ERROR_STATE_COLOR } from './constants';\nimport { getThresholdRuleColor, getThresholdRuleIcon } from './thresholdUtils';\n\nexport type StatusConfig = {\n color: string;\n icon?: string;\n};\n\n/**\n * @param evaluation - The evaluation status of the metric.\n * colors are mapped to MUI palette strings (e.g., 'error.main', 'warning.main', 'success.main').\n * @returns StatusConfig\n */\nexport const getStatusConfig = ({\n evaluation,\n thresholdStatus,\n metricStatus,\n thresholdRules,\n}: {\n evaluation: string | null;\n thresholdStatus?: 'success' | 'error';\n metricStatus?: 'success' | 'error';\n thresholdRules?: ThresholdRule[];\n}): StatusConfig => {\n // If threshold or metric has an error, return error state color\n if (thresholdStatus === 'error' || metricStatus === 'error') {\n return { color: SCORECARD_ERROR_STATE_COLOR };\n }\n\n let evaluationColor: string | undefined;\n if (thresholdRules && evaluation) {\n evaluationColor = getThresholdRuleColor(thresholdRules, evaluation);\n }\n const color = evaluationColor ?? SCORECARD_ERROR_STATE_COLOR;\n const icon =\n thresholdRules && evaluation\n ? getThresholdRuleIcon(thresholdRules, evaluation)\n : undefined;\n return { color, icon };\n};\n\n/**\n * Resolves a color value from the theme palette or returns a custom color.\n * Supports theme palette paths (e.g., 'error.main', 'rhdh.general.cardBorderColor')\n * and direct color values (e.g., '#FF5733', 'blue', 'rgb(255,0,0)').\n *\n * @param theme - The theme configuration object\n * @param statusColor - Either a theme palette path or a direct color value\n * @returns The resolved color string\n */\nexport const resolveStatusColor = (\n theme: Theme,\n statusColor: string,\n): string => {\n // Theme palette paths are dot-separated; rgba(...) may include '.' in its alpha value.\n if (!statusColor.includes('.') || statusColor.includes('rgba')) {\n return statusColor;\n }\n\n // Resolve theme palette reference\n const parts = statusColor.split('.');\n let value: any = theme.palette;\n\n for (const part of parts) {\n value = value?.[part];\n if (value === undefined) {\n break;\n }\n }\n\n if (typeof value === 'string') {\n return value;\n }\n\n // Fallback to error state color, then error.main\n return (\n (theme as ThemeConfig).palette?.rhdh?.general?.cardBorderColor ??\n theme.palette.error.main\n );\n};\n"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"statusUtils.esm.js","sources":["../../src/utils/statusUtils.ts"],"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 { Theme } from '@mui/material/styles';\nimport type { TranslationFunction } from '@backstage/core-plugin-api/alpha';\nimport type { ThresholdRule } from '@red-hat-developer-hub/backstage-plugin-scorecard-common';\nimport type { ThemeConfig } from '@red-hat-developer-hub/backstage-plugin-theme';\n\nimport { scorecardTranslationRef } from '../translations';\nimport { SCORECARD_ERROR_STATE_COLOR } from './constants';\nimport { getThresholdRuleColor, getThresholdRuleIcon } from './thresholdUtils';\n\nexport type StatusConfig = {\n color: string;\n icon?: string;\n};\n\nexport const getTranslatedStatus = (\n status: string | undefined,\n t: TranslationFunction<typeof scorecardTranslationRef.T>,\n): string => {\n if (!status) {\n return '';\n }\n\n const translationKey = `thresholds.${status}`;\n const translatedStatus = t(translationKey as any, {});\n if (translatedStatus === translationKey) {\n return status.charAt(0).toUpperCase() + status.slice(1);\n }\n\n return translatedStatus;\n};\n\n/**\n * @param evaluation - The evaluation status of the metric.\n * colors are mapped to MUI palette strings (e.g., 'error.main', 'warning.main', 'success.main').\n * @returns StatusConfig\n */\nexport const getStatusConfig = ({\n evaluation,\n thresholdStatus,\n metricStatus,\n thresholdRules,\n}: {\n evaluation: string | null;\n thresholdStatus?: 'success' | 'error';\n metricStatus?: 'success' | 'error';\n thresholdRules?: ThresholdRule[];\n}): StatusConfig => {\n // If threshold or metric has an error, return error state color\n if (thresholdStatus === 'error' || metricStatus === 'error') {\n return { color: SCORECARD_ERROR_STATE_COLOR };\n }\n\n let evaluationColor: string | undefined;\n if (thresholdRules && evaluation) {\n evaluationColor = getThresholdRuleColor(thresholdRules, evaluation);\n }\n const color = evaluationColor ?? SCORECARD_ERROR_STATE_COLOR;\n const icon =\n thresholdRules && evaluation\n ? getThresholdRuleIcon(thresholdRules, evaluation)\n : undefined;\n return { color, icon };\n};\n\n/**\n * Resolves a color value from the theme palette or returns a custom color.\n * Supports theme palette paths (e.g., 'error.main', 'rhdh.general.cardBorderColor')\n * and direct color values (e.g., '#FF5733', 'blue', 'rgb(255,0,0)').\n *\n * @param theme - The theme configuration object\n * @param statusColor - Either a theme palette path or a direct color value\n * @returns The resolved color string\n */\nexport const resolveStatusColor = (\n theme: Theme,\n statusColor: string,\n): string => {\n // Theme palette paths are dot-separated; rgba(...) may include '.' in its alpha value.\n if (!statusColor.includes('.') || statusColor.includes('rgba')) {\n return statusColor;\n }\n\n // Resolve theme palette reference\n const parts = statusColor.split('.');\n let value: any = theme.palette;\n\n for (const part of parts) {\n value = value?.[part];\n if (value === undefined) {\n break;\n }\n }\n\n if (typeof value === 'string') {\n return value;\n }\n\n // Fallback to error state color, then error.main\n return (\n (theme as ThemeConfig).palette?.rhdh?.general?.cardBorderColor ??\n theme.palette.error.main\n );\n};\n"],"names":[],"mappings":";;;AA8Ba,MAAA,mBAAA,GAAsB,CACjC,MAAA,EACA,CACW,KAAA;AACX,EAAA,IAAI,CAAC,MAAQ,EAAA;AACX,IAAO,OAAA,EAAA;AAAA;AAGT,EAAM,MAAA,cAAA,GAAiB,cAAc,MAAM,CAAA,CAAA;AAC3C,EAAA,MAAM,gBAAmB,GAAA,CAAA,CAAE,cAAuB,EAAA,EAAE,CAAA;AACpD,EAAA,IAAI,qBAAqB,cAAgB,EAAA;AACvC,IAAO,OAAA,MAAA,CAAO,OAAO,CAAC,CAAA,CAAE,aAAgB,GAAA,MAAA,CAAO,MAAM,CAAC,CAAA;AAAA;AAGxD,EAAO,OAAA,gBAAA;AACT;AAOO,MAAM,kBAAkB,CAAC;AAAA,EAC9B,UAAA;AAAA,EACA,eAAA;AAAA,EACA,YAAA;AAAA,EACA;AACF,CAKoB,KAAA;AAElB,EAAI,IAAA,eAAA,KAAoB,OAAW,IAAA,YAAA,KAAiB,OAAS,EAAA;AAC3D,IAAO,OAAA,EAAE,OAAO,2BAA4B,EAAA;AAAA;AAG9C,EAAI,IAAA,eAAA;AACJ,EAAA,IAAI,kBAAkB,UAAY,EAAA;AAChC,IAAkB,eAAA,GAAA,qBAAA,CAAsB,gBAAgB,UAAU,CAAA;AAAA;AAEpE,EAAA,MAAM,QAAQ,eAAmB,IAAA,2BAAA;AACjC,EAAA,MAAM,OACJ,cAAkB,IAAA,UAAA,GACd,oBAAqB,CAAA,cAAA,EAAgB,UAAU,CAC/C,GAAA,MAAA;AACN,EAAO,OAAA,EAAE,OAAO,IAAK,EAAA;AACvB;AAWa,MAAA,kBAAA,GAAqB,CAChC,KAAA,EACA,WACW,KAAA;AAEX,EAAI,IAAA,CAAC,YAAY,QAAS,CAAA,GAAG,KAAK,WAAY,CAAA,QAAA,CAAS,MAAM,CAAG,EAAA;AAC9D,IAAO,OAAA,WAAA;AAAA;AAIT,EAAM,MAAA,KAAA,GAAQ,WAAY,CAAA,KAAA,CAAM,GAAG,CAAA;AACnC,EAAA,IAAI,QAAa,KAAM,CAAA,OAAA;AAEvB,EAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,IAAA,KAAA,GAAQ,QAAQ,IAAI,CAAA;AACpB,IAAA,IAAI,UAAU,MAAW,EAAA;AACvB,MAAA;AAAA;AACF;AAGF,EAAI,IAAA,OAAO,UAAU,QAAU,EAAA;AAC7B,IAAO,OAAA,KAAA;AAAA;AAIT,EAAA,OACG,MAAsB,OAAS,EAAA,IAAA,EAAM,SAAS,eAC/C,IAAA,KAAA,CAAM,QAAQ,KAAM,CAAA,IAAA;AAExB;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@red-hat-developer-hub/backstage-plugin-scorecard",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.7",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"main": "./dist/index.esm.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
"@backstage/theme": "^0.7.2",
|
|
76
76
|
"@mui/icons-material": "5.18.0",
|
|
77
77
|
"@mui/material": "5.18.0",
|
|
78
|
-
"@red-hat-developer-hub/backstage-plugin-scorecard-common": "^2.7.
|
|
78
|
+
"@red-hat-developer-hub/backstage-plugin-scorecard-common": "^2.7.7",
|
|
79
79
|
"@tanstack/react-query": "^5.95.2",
|
|
80
80
|
"date-fns": "^4.1.0",
|
|
81
81
|
"react-use": "^17.2.4",
|