@backstage-community/plugin-tech-insights-maturity 0.2.0
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 +21 -0
- package/README.md +177 -0
- package/dist/ScoreRouter.esm.js +8 -0
- package/dist/ScoreRouter.esm.js.map +1 -0
- package/dist/SummaryRouter.esm.js +8 -0
- package/dist/SummaryRouter.esm.js.map +1 -0
- package/dist/api/MaturityApi.esm.js +8 -0
- package/dist/api/MaturityApi.esm.js.map +1 -0
- package/dist/api/MaturityClient.esm.js +128 -0
- package/dist/api/MaturityClient.esm.js.map +1 -0
- package/dist/api/ScoringDataFormatter.esm.js +142 -0
- package/dist/api/ScoringDataFormatter.esm.js.map +1 -0
- package/dist/components/MaturityChartCard/MaturityChartCard.esm.js +79 -0
- package/dist/components/MaturityChartCard/MaturityChartCard.esm.js.map +1 -0
- package/dist/components/MaturityChartCard/index.esm.js +2 -0
- package/dist/components/MaturityChartCard/index.esm.js.map +1 -0
- package/dist/components/MaturityPage/MaturityPage.esm.js +21 -0
- package/dist/components/MaturityPage/MaturityPage.esm.js.map +1 -0
- package/dist/components/MaturityPage/index.esm.js +2 -0
- package/dist/components/MaturityPage/index.esm.js.map +1 -0
- package/dist/components/MaturityRankAvatar/MaturityRankAvatar.esm.js +100 -0
- package/dist/components/MaturityRankAvatar/MaturityRankAvatar.esm.js.map +1 -0
- package/dist/components/MaturityRankInfoCard/MaturityRankInfoCard.esm.js +80 -0
- package/dist/components/MaturityRankInfoCard/MaturityRankInfoCard.esm.js.map +1 -0
- package/dist/components/MaturityRankWidget/MaturityRankWidget.esm.js +22 -0
- package/dist/components/MaturityRankWidget/MaturityRankWidget.esm.js.map +1 -0
- package/dist/components/MaturityRankWidget/index.esm.js +2 -0
- package/dist/components/MaturityRankWidget/index.esm.js.map +1 -0
- package/dist/components/MaturityScorePage/MaturityScorePage.esm.js +85 -0
- package/dist/components/MaturityScorePage/MaturityScorePage.esm.js.map +1 -0
- package/dist/components/MaturityScorePage/maturityTableRows.esm.js +124 -0
- package/dist/components/MaturityScorePage/maturityTableRows.esm.js.map +1 -0
- package/dist/components/MaturitySummaryInfoCard/MaturitySummaryCardContent.esm.js +17 -0
- package/dist/components/MaturitySummaryInfoCard/MaturitySummaryCardContent.esm.js.map +1 -0
- package/dist/components/MaturitySummaryInfoCard/MaturitySummaryInfoCard.esm.js +34 -0
- package/dist/components/MaturitySummaryInfoCard/MaturitySummaryInfoCard.esm.js.map +1 -0
- package/dist/components/MaturitySummaryInfoCard/index.esm.js +2 -0
- package/dist/components/MaturitySummaryInfoCard/index.esm.js.map +1 -0
- package/dist/components/MaturitySummaryPage/MaturitySummaryPage.esm.js +35 -0
- package/dist/components/MaturitySummaryPage/MaturitySummaryPage.esm.js.map +1 -0
- package/dist/components/MaturitySummaryTable/MaturitySummaryTable.esm.js +206 -0
- package/dist/components/MaturitySummaryTable/MaturitySummaryTable.esm.js.map +1 -0
- package/dist/helpers/AreaProgress.esm.js +47 -0
- package/dist/helpers/AreaProgress.esm.js.map +1 -0
- package/dist/helpers/MaturityHelp.esm.js +9 -0
- package/dist/helpers/MaturityHelp.esm.js.map +1 -0
- package/dist/helpers/MaturityLink.esm.js +25 -0
- package/dist/helpers/MaturityLink.esm.js.map +1 -0
- package/dist/helpers/Rank.esm.js +33 -0
- package/dist/helpers/Rank.esm.js.map +1 -0
- package/dist/helpers/utils.esm.js +41 -0
- package/dist/helpers/utils.esm.js.map +1 -0
- package/dist/img/bronze.png +0 -0
- package/dist/img/gold.png +0 -0
- package/dist/img/silver.png +0 -0
- package/dist/img/stone.png +0 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.esm.js +4 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/plugin.esm.js +80 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/routes.esm.js +8 -0
- package/dist/routes.esm.js.map +1 -0
- package/package.json +104 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaturitySummaryInfoCard.esm.js","sources":["../../../src/components/MaturitySummaryInfoCard/MaturitySummaryInfoCard.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\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 */\nimport React from 'react';\nimport useAsyncRetry from 'react-use/lib/useAsync';\n\nimport { InfoCard } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useEntity } from '@backstage/plugin-catalog-react';\nimport Grid from '@mui/material/Grid';\nimport CardContent from '@mui/material/CardContent';\nimport { MaturitySummaryCardContent } from './MaturitySummaryCardContent';\nimport { MaturityHelp } from '../../helpers/MaturityHelp';\nimport { MaturityRankAvatar } from '../MaturityRankAvatar';\nimport { maturityApiRef } from '../../api';\n\nexport const MaturitySummaryInfoCard = () => {\n const { entity } = useEntity();\n\n const api = useApi(maturityApiRef);\n const { value, loading } = useAsyncRetry(\n async () => api.getMaturitySummary(entity),\n [api, entity],\n );\n\n if (!value || loading) return <></>;\n\n return (\n <InfoCard\n title={\n <Grid container>\n <Grid item md={7}>\n Maturity\n <MaturityHelp />\n </Grid>\n <Grid item md={5}>\n <MaturityRankAvatar value={value} entity={entity} variant=\"chip\" />\n </Grid>\n </Grid>\n }\n >\n <CardContent>\n <MaturitySummaryCardContent summary={value} variant=\"infoCard\" />\n </CardContent>\n </InfoCard>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA4BO,MAAM,0BAA0B,MAAM;AAC3C,EAAM,MAAA,EAAE,MAAO,EAAA,GAAI,SAAU,EAAA;AAE7B,EAAM,MAAA,GAAA,GAAM,OAAO,cAAc,CAAA;AACjC,EAAM,MAAA,EAAE,KAAO,EAAA,OAAA,EAAY,GAAA,aAAA;AAAA,IACzB,YAAY,GAAI,CAAA,kBAAA,CAAmB,MAAM,CAAA;AAAA,IACzC,CAAC,KAAK,MAAM;AAAA,GACd;AAEA,EAAA,IAAI,CAAC,KAAA,IAAS,OAAS,EAAA,uBAAS,KAAA,CAAA,aAAA,CAAA,KAAA,CAAA,QAAA,EAAA,IAAA,CAAA;AAEhC,EACE,uBAAA,KAAA,CAAA,aAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KACE,kBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAS,IACb,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAI,IAAC,EAAA,EAAA,EAAI,CAAG,EAAA,EAAA,UAAA,kBAEf,KAAA,CAAA,aAAA,CAAA,YAAA,EAAA,IAAa,CAChB,CAAA,kBACC,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,IAAI,EAAA,IAAA,EAAC,EAAI,EAAA,CAAA,EAAA,kBACZ,KAAA,CAAA,aAAA,CAAA,kBAAA,EAAA,EAAmB,KAAc,EAAA,MAAA,EAAgB,OAAQ,EAAA,MAAA,EAAO,CACnE,CACF;AAAA,KAAA;AAAA,oBAGF,KAAA,CAAA,aAAA,CAAC,mCACE,KAAA,CAAA,aAAA,CAAA,0BAAA,EAAA,EAA2B,SAAS,KAAO,EAAA,OAAA,EAAQ,YAAW,CACjE;AAAA,GACF;AAEJ;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import useAsyncRetry from 'react-use/lib/useAsync';
|
|
3
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
4
|
+
import { useEntity, useRelatedEntities } from '@backstage/plugin-catalog-react';
|
|
5
|
+
import { Progress, EmptyState } from '@backstage/core-components';
|
|
6
|
+
import Alert from '@mui/material/Alert';
|
|
7
|
+
import Grid from '@mui/material/Grid';
|
|
8
|
+
import { MaturityRankInfoCard } from '../MaturityRankInfoCard/MaturityRankInfoCard.esm.js';
|
|
9
|
+
import { MaturitySummaryTable } from '../MaturitySummaryTable/MaturitySummaryTable.esm.js';
|
|
10
|
+
import { getSubEntityFilter } from '../../helpers/utils.esm.js';
|
|
11
|
+
import { maturityApiRef } from '../../api/MaturityApi.esm.js';
|
|
12
|
+
import '@backstage/catalog-model';
|
|
13
|
+
import '@backstage-community/plugin-tech-insights';
|
|
14
|
+
import '@backstage-community/plugin-tech-insights-maturity-common';
|
|
15
|
+
|
|
16
|
+
const MaturitySummaryPage = () => {
|
|
17
|
+
const { entity } = useEntity();
|
|
18
|
+
const { entities } = useRelatedEntities(entity, getSubEntityFilter(entity));
|
|
19
|
+
const api = useApi(maturityApiRef);
|
|
20
|
+
const { value, loading, error } = useAsyncRetry(
|
|
21
|
+
async () => api.getMaturitySummary(entity),
|
|
22
|
+
[api, entity]
|
|
23
|
+
);
|
|
24
|
+
if (loading) {
|
|
25
|
+
return /* @__PURE__ */ React.createElement(Progress, null);
|
|
26
|
+
} else if (error) {
|
|
27
|
+
return /* @__PURE__ */ React.createElement(Alert, { severity: "error" }, error.message);
|
|
28
|
+
} else if (!value) {
|
|
29
|
+
return /* @__PURE__ */ React.createElement(EmptyState, { missing: "info", title: "No information to display" });
|
|
30
|
+
}
|
|
31
|
+
return /* @__PURE__ */ React.createElement(Grid, { container: true }, /* @__PURE__ */ React.createElement(Grid, { item: true, md: 3 }, /* @__PURE__ */ React.createElement(MaturityRankInfoCard, { summary: value })), /* @__PURE__ */ React.createElement(Grid, { item: true, md: 9 }, entities && /* @__PURE__ */ React.createElement(MaturitySummaryTable, { entities })));
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export { MaturitySummaryPage };
|
|
35
|
+
//# sourceMappingURL=MaturitySummaryPage.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaturitySummaryPage.esm.js","sources":["../../../src/components/MaturitySummaryPage/MaturitySummaryPage.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\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 */\nimport React from 'react';\nimport useAsyncRetry from 'react-use/lib/useAsync';\n\nimport { useApi } from '@backstage/core-plugin-api';\nimport { useEntity, useRelatedEntities } from '@backstage/plugin-catalog-react';\nimport { EmptyState, Progress } from '@backstage/core-components';\nimport Alert from '@mui/material/Alert';\nimport Grid from '@mui/material/Grid';\nimport { MaturityRankInfoCard } from '../MaturityRankInfoCard';\nimport { MaturitySummaryTable } from '../MaturitySummaryTable';\nimport { getSubEntityFilter } from '../../helpers/utils';\nimport { maturityApiRef } from '../../api';\n\nexport const MaturitySummaryPage = () => {\n const { entity } = useEntity();\n const { entities } = useRelatedEntities(entity, getSubEntityFilter(entity));\n\n const api = useApi(maturityApiRef);\n const { value, loading, error } = useAsyncRetry(\n async () => api.getMaturitySummary(entity),\n [api, entity],\n );\n\n if (loading) {\n return <Progress />;\n } else if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n } else if (!value) {\n return <EmptyState missing=\"info\" title=\"No information to display\" />;\n }\n\n return (\n <Grid container>\n <Grid item md={3}>\n <MaturityRankInfoCard summary={value} />\n </Grid>\n <Grid item md={9}>\n {entities && <MaturitySummaryTable entities={entities} />}\n </Grid>\n </Grid>\n );\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;AA4BO,MAAM,sBAAsB,MAAM;AACvC,EAAM,MAAA,EAAE,MAAO,EAAA,GAAI,SAAU,EAAA;AAC7B,EAAA,MAAM,EAAE,QAAS,EAAA,GAAI,mBAAmB,MAAQ,EAAA,kBAAA,CAAmB,MAAM,CAAC,CAAA;AAE1E,EAAM,MAAA,GAAA,GAAM,OAAO,cAAc,CAAA;AACjC,EAAA,MAAM,EAAE,KAAA,EAAO,OAAS,EAAA,KAAA,EAAU,GAAA,aAAA;AAAA,IAChC,YAAY,GAAI,CAAA,kBAAA,CAAmB,MAAM,CAAA;AAAA,IACzC,CAAC,KAAK,MAAM;AAAA,GACd;AAEA,EAAA,IAAI,OAAS,EAAA;AACX,IAAA,2CAAQ,QAAS,EAAA,IAAA,CAAA;AAAA,aACR,KAAO,EAAA;AAChB,IAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAM,QAAS,EAAA,OAAA,EAAA,EAAS,MAAM,OAAQ,CAAA;AAAA,GAChD,MAAA,IAAW,CAAC,KAAO,EAAA;AACjB,IAAA,uBAAQ,KAAA,CAAA,aAAA,CAAA,UAAA,EAAA,EAAW,OAAQ,EAAA,MAAA,EAAO,OAAM,2BAA4B,EAAA,CAAA;AAAA;AAGtE,EACE,uBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,SAAA,EAAS,IACb,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAI,IAAC,EAAA,EAAA,EAAI,CACb,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,oBAAqB,EAAA,EAAA,OAAA,EAAS,KAAO,EAAA,CACxC,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,IAAK,EAAA,EAAA,IAAA,EAAI,IAAC,EAAA,EAAA,EAAI,CACZ,EAAA,EAAA,QAAA,oBAAa,KAAA,CAAA,aAAA,CAAA,oBAAA,EAAA,EAAqB,QAAoB,EAAA,CACzD,CACF,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { Table } from '@backstage/core-components';
|
|
2
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
3
|
+
import { Rank } from '@backstage-community/plugin-tech-insights-maturity-common';
|
|
4
|
+
import Stack from '@mui/material/Stack';
|
|
5
|
+
import { useTheme } from '@mui/material/styles';
|
|
6
|
+
import Tooltip from '@mui/material/Tooltip';
|
|
7
|
+
import Typography from '@mui/material/Typography';
|
|
8
|
+
import { Circle, Line } from 'rc-progress';
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import useAsyncRetry from 'react-use/lib/useAsync';
|
|
11
|
+
import { maturityApiRef } from '../../api/MaturityApi.esm.js';
|
|
12
|
+
import '@backstage/catalog-model';
|
|
13
|
+
import '@backstage/plugin-catalog-react';
|
|
14
|
+
import '@backstage-community/plugin-tech-insights';
|
|
15
|
+
import { getNextRankColor, pluralize } from '../../helpers/utils.esm.js';
|
|
16
|
+
import { MaturityLink } from '../../helpers/MaturityLink.esm.js';
|
|
17
|
+
import { MaturityRankAvatar } from '../MaturityRankAvatar/MaturityRankAvatar.esm.js';
|
|
18
|
+
|
|
19
|
+
const OverallCell = ({
|
|
20
|
+
areaSummary
|
|
21
|
+
}) => {
|
|
22
|
+
const { area, rank, maxRank, progress } = areaSummary;
|
|
23
|
+
return /* @__PURE__ */ React.createElement(
|
|
24
|
+
Stack,
|
|
25
|
+
{
|
|
26
|
+
direction: "row",
|
|
27
|
+
spacing: 1,
|
|
28
|
+
alignItems: "center",
|
|
29
|
+
style: { padding: "0.6rem 0" }
|
|
30
|
+
},
|
|
31
|
+
/* @__PURE__ */ React.createElement(
|
|
32
|
+
Circle,
|
|
33
|
+
{
|
|
34
|
+
key: area,
|
|
35
|
+
strokeColor: getNextRankColor(rank, maxRank),
|
|
36
|
+
trailColor: "rgba(0, 0, 0, 0.1)",
|
|
37
|
+
strokeWidth: 10,
|
|
38
|
+
trailWidth: 10,
|
|
39
|
+
percent: progress.percentage,
|
|
40
|
+
style: { width: "25pt" }
|
|
41
|
+
}
|
|
42
|
+
),
|
|
43
|
+
/* @__PURE__ */ React.createElement(Typography, { variant: "button" }, `${progress.percentage}%`)
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
const NextRankCell = ({
|
|
47
|
+
areaSummary
|
|
48
|
+
}) => {
|
|
49
|
+
const { rank, maxRank, isMaxRank, rankProgress } = areaSummary;
|
|
50
|
+
const nextRankName = isMaxRank ? Rank[maxRank] : Rank[rank + 1];
|
|
51
|
+
const incompleteTasks = rankProgress.totalChecks - rankProgress.passedChecks;
|
|
52
|
+
const taskCaption = `${incompleteTasks} ${nextRankName} task${pluralize(
|
|
53
|
+
incompleteTasks
|
|
54
|
+
)} left`;
|
|
55
|
+
const taskTooltip = `${rankProgress.percentage}% to ${nextRankName} (${rankProgress.passedChecks}/${rankProgress.totalChecks} task${pluralize(
|
|
56
|
+
rankProgress.totalChecks
|
|
57
|
+
)} completed)`;
|
|
58
|
+
const progressCaption = isMaxRank ? "Max rank!" : taskCaption;
|
|
59
|
+
const progressTooltip = isMaxRank ? "Max rank!" : taskTooltip;
|
|
60
|
+
return /* @__PURE__ */ React.createElement(Tooltip, { title: progressTooltip, arrow: true }, /* @__PURE__ */ React.createElement(Stack, null, /* @__PURE__ */ React.createElement(Typography, { variant: "caption", color: "textSecondary" }, progressCaption), /* @__PURE__ */ React.createElement(
|
|
61
|
+
Line,
|
|
62
|
+
{
|
|
63
|
+
strokeColor: getNextRankColor(rank, maxRank),
|
|
64
|
+
trailColor: "rgba(0, 0, 0, 0.1)",
|
|
65
|
+
strokeWidth: 2,
|
|
66
|
+
trailWidth: 2,
|
|
67
|
+
percent: rankProgress.percentage,
|
|
68
|
+
style: { padding: "0.4rem 0" },
|
|
69
|
+
"data-testid": "progressbar"
|
|
70
|
+
}
|
|
71
|
+
)));
|
|
72
|
+
};
|
|
73
|
+
const ProgressCell = ({
|
|
74
|
+
areaSummary
|
|
75
|
+
}) => {
|
|
76
|
+
if (!areaSummary) return /* @__PURE__ */ React.createElement(React.Fragment, null);
|
|
77
|
+
return /* @__PURE__ */ React.createElement(
|
|
78
|
+
MaturityRankAvatar,
|
|
79
|
+
{
|
|
80
|
+
value: areaSummary,
|
|
81
|
+
size: 25,
|
|
82
|
+
progress: areaSummary.rankProgress
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
};
|
|
86
|
+
function MaturitySummaryTable({
|
|
87
|
+
entities
|
|
88
|
+
}) {
|
|
89
|
+
const theme = useTheme();
|
|
90
|
+
const api = useApi(maturityApiRef);
|
|
91
|
+
const { value } = useAsyncRetry(
|
|
92
|
+
async () => api.getBulkMaturitySummary(entities),
|
|
93
|
+
[api, entities]
|
|
94
|
+
);
|
|
95
|
+
const style = {
|
|
96
|
+
sorting: false,
|
|
97
|
+
cellStyle: {
|
|
98
|
+
fontSize: "1.2rem",
|
|
99
|
+
paddingTop: "0.4rem",
|
|
100
|
+
paddingBottom: "0.4rem",
|
|
101
|
+
verticalAlign: "center"
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
const columns = [
|
|
105
|
+
{
|
|
106
|
+
title: "Rank",
|
|
107
|
+
field: "summary.rank",
|
|
108
|
+
hiddenByColumnsButton: true,
|
|
109
|
+
defaultSort: "asc",
|
|
110
|
+
customSort: (a, b) => {
|
|
111
|
+
const isNotSameRank = a.summary.rank !== b.summary.rank;
|
|
112
|
+
const progA = a.summary.isMaxRank ? 100 : a.summary.progress.percentage;
|
|
113
|
+
const progB = b.summary.isMaxRank ? 100 : b.summary.progress.percentage;
|
|
114
|
+
return isNotSameRank ? a.summary.rank - b.summary.rank : progA - progB;
|
|
115
|
+
},
|
|
116
|
+
hidden: true
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
title: "Name",
|
|
120
|
+
field: "displayName",
|
|
121
|
+
hiddenByColumnsButton: true,
|
|
122
|
+
width: "22%",
|
|
123
|
+
...style,
|
|
124
|
+
render: (row) => /* @__PURE__ */ React.createElement("b", null, /* @__PURE__ */ React.createElement(MaturityLink, { entity: row.entity }))
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
title: "Overall",
|
|
128
|
+
tooltip: "Progress toward achieving full maturity",
|
|
129
|
+
field: "summary.progress.percentage",
|
|
130
|
+
width: "13%",
|
|
131
|
+
...style,
|
|
132
|
+
hidden: true,
|
|
133
|
+
render: (row) => /* @__PURE__ */ React.createElement(
|
|
134
|
+
OverallCell,
|
|
135
|
+
{
|
|
136
|
+
areaSummary: {
|
|
137
|
+
area: "",
|
|
138
|
+
...row.summary
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
)
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
title: "Rank",
|
|
145
|
+
tooltip: "Current overall rank",
|
|
146
|
+
field: "summary.rank",
|
|
147
|
+
width: "10%",
|
|
148
|
+
...style,
|
|
149
|
+
render: (row) => /* @__PURE__ */ React.createElement(MaturityRankAvatar, { value: row.summary, size: 25, variant: "chip" })
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
title: "Next Rank",
|
|
153
|
+
tooltip: "Progress toward achieving next rank",
|
|
154
|
+
field: "summary.rankProgress.percentage",
|
|
155
|
+
width: "15%",
|
|
156
|
+
...style,
|
|
157
|
+
render: (row) => /* @__PURE__ */ React.createElement(
|
|
158
|
+
NextRankCell,
|
|
159
|
+
{
|
|
160
|
+
areaSummary: {
|
|
161
|
+
area: "",
|
|
162
|
+
...row.summary
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
];
|
|
168
|
+
const categories = value?.flatMap((x) => x.summary.areaSummaries).map((x) => x.area).filter((x, i, a) => a.indexOf(x) === i);
|
|
169
|
+
categories?.forEach((category) => {
|
|
170
|
+
const column = {
|
|
171
|
+
title: category,
|
|
172
|
+
field: `summary.areaSummaries.${category}`,
|
|
173
|
+
width: "10%",
|
|
174
|
+
...style,
|
|
175
|
+
render: (row) => /* @__PURE__ */ React.createElement(
|
|
176
|
+
ProgressCell,
|
|
177
|
+
{
|
|
178
|
+
areaSummary: row.summary.areaSummaries.find((x) => x.area === category)
|
|
179
|
+
}
|
|
180
|
+
)
|
|
181
|
+
};
|
|
182
|
+
columns.push(column);
|
|
183
|
+
});
|
|
184
|
+
if (!value) return /* @__PURE__ */ React.createElement(React.Fragment, null);
|
|
185
|
+
return /* @__PURE__ */ React.createElement(
|
|
186
|
+
Table,
|
|
187
|
+
{
|
|
188
|
+
title: "Component Maturity",
|
|
189
|
+
subtitle: "View this entity's children in order of lowest to highest Maturity.",
|
|
190
|
+
columns,
|
|
191
|
+
data: value ?? [],
|
|
192
|
+
options: {
|
|
193
|
+
pageSize: 10,
|
|
194
|
+
columnsButton: true,
|
|
195
|
+
rowStyle: {
|
|
196
|
+
backgroundColor: theme.palette.background.paper,
|
|
197
|
+
borderTop: `1px solid ${theme.palette.background.default}`,
|
|
198
|
+
borderBottom: `1px solid ${theme.palette.background.default}`
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export { MaturitySummaryTable };
|
|
206
|
+
//# sourceMappingURL=MaturitySummaryTable.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaturitySummaryTable.esm.js","sources":["../../../src/components/MaturitySummaryTable/MaturitySummaryTable.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\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 */\nimport { Entity } from '@backstage/catalog-model';\nimport { Table, TableColumn } from '@backstage/core-components';\nimport { useApi } from '@backstage/core-plugin-api';\nimport {\n EntityMaturitySummary,\n MaturitySummaryByArea,\n Rank,\n} from '@backstage-community/plugin-tech-insights-maturity-common';\nimport Stack from '@mui/material/Stack';\nimport { useTheme } from '@mui/material/styles';\n\nimport Tooltip from '@mui/material/Tooltip';\nimport Typography from '@mui/material/Typography';\nimport { Circle, Line } from 'rc-progress';\nimport React from 'react';\n\nimport useAsyncRetry from 'react-use/lib/useAsync';\nimport { maturityApiRef } from '../../api';\nimport { getNextRankColor, pluralize } from '../../helpers/utils';\nimport { MaturityLink } from '../../helpers/MaturityLink';\nimport { MaturityRankAvatar } from '../MaturityRankAvatar';\n\nconst OverallCell = ({\n areaSummary,\n}: {\n areaSummary: MaturitySummaryByArea;\n}) => {\n const { area, rank, maxRank, progress } = areaSummary;\n\n return (\n <Stack\n direction=\"row\"\n spacing={1}\n alignItems=\"center\"\n style={{ padding: '0.6rem 0' }}\n >\n <Circle\n key={area}\n strokeColor={getNextRankColor(rank, maxRank)}\n trailColor=\"rgba(0, 0, 0, 0.1)\"\n strokeWidth={10}\n trailWidth={10}\n percent={progress.percentage}\n style={{ width: '25pt' }}\n />\n <Typography variant=\"button\">{`${progress.percentage}%`}</Typography>\n </Stack>\n );\n};\n\nconst NextRankCell = ({\n areaSummary,\n}: {\n areaSummary: MaturitySummaryByArea;\n}) => {\n const { rank, maxRank, isMaxRank, rankProgress } = areaSummary;\n\n const nextRankName = isMaxRank ? Rank[maxRank] : Rank[rank + 1];\n const incompleteTasks = rankProgress.totalChecks - rankProgress.passedChecks;\n const taskCaption = `${incompleteTasks} ${nextRankName} task${pluralize(\n incompleteTasks,\n )} left`;\n const taskTooltip = `${rankProgress.percentage}% to ${nextRankName} (${\n rankProgress.passedChecks\n }/${rankProgress.totalChecks} task${pluralize(\n rankProgress.totalChecks,\n )} completed)`;\n\n const progressCaption = isMaxRank ? 'Max rank!' : taskCaption;\n const progressTooltip = isMaxRank ? 'Max rank!' : taskTooltip;\n\n return (\n <Tooltip title={progressTooltip} arrow>\n <Stack>\n <Typography variant=\"caption\" color=\"textSecondary\">\n {progressCaption}\n </Typography>\n <Line\n strokeColor={getNextRankColor(rank, maxRank)}\n trailColor=\"rgba(0, 0, 0, 0.1)\"\n strokeWidth={2}\n trailWidth={2}\n percent={rankProgress.percentage}\n style={{ padding: '0.4rem 0' }}\n data-testid=\"progressbar\"\n />\n </Stack>\n </Tooltip>\n );\n};\n\nconst ProgressCell = ({\n areaSummary,\n}: {\n areaSummary?: MaturitySummaryByArea;\n}) => {\n if (!areaSummary) return <></>;\n\n return (\n <MaturityRankAvatar\n value={areaSummary}\n size={25}\n progress={areaSummary.rankProgress}\n />\n );\n};\n\nexport function MaturitySummaryTable({\n entities,\n}: Readonly<{ entities: Entity[] }>) {\n const theme = useTheme();\n\n const api = useApi(maturityApiRef);\n const { value } = useAsyncRetry(\n async () => api.getBulkMaturitySummary(entities),\n [api, entities],\n );\n\n const style = {\n sorting: false,\n cellStyle: {\n fontSize: '1.2rem',\n paddingTop: '0.4rem',\n paddingBottom: '0.4rem',\n verticalAlign: 'center',\n },\n };\n\n const columns: TableColumn<EntityMaturitySummary>[] = [\n {\n title: 'Rank',\n field: 'summary.rank',\n hiddenByColumnsButton: true,\n defaultSort: 'asc',\n customSort: (a, b) => {\n const isNotSameRank = a.summary.rank !== b.summary.rank;\n const progA = a.summary.isMaxRank ? 100 : a.summary.progress.percentage;\n const progB = b.summary.isMaxRank ? 100 : b.summary.progress.percentage;\n\n // Sort by rank, or by overall progress within same rank.\n return isNotSameRank ? a.summary.rank - b.summary.rank : progA - progB;\n },\n hidden: true,\n },\n {\n title: 'Name',\n field: 'displayName',\n hiddenByColumnsButton: true,\n width: '22%',\n ...style,\n render: row => (\n <b>\n <MaturityLink entity={row.entity} />\n </b>\n ),\n },\n {\n title: 'Overall',\n tooltip: 'Progress toward achieving full maturity',\n field: 'summary.progress.percentage',\n width: '13%',\n ...style,\n hidden: true,\n render: row => (\n <OverallCell\n areaSummary={{\n area: '',\n ...row.summary,\n }}\n />\n ),\n },\n {\n title: 'Rank',\n tooltip: 'Current overall rank',\n field: 'summary.rank',\n width: '10%',\n ...style,\n render: row => (\n <MaturityRankAvatar value={row.summary} size={25} variant=\"chip\" />\n ),\n },\n {\n title: 'Next Rank',\n tooltip: 'Progress toward achieving next rank',\n field: 'summary.rankProgress.percentage',\n width: '15%',\n ...style,\n render: row => (\n <NextRankCell\n areaSummary={{\n area: '',\n ...row.summary,\n }}\n />\n ),\n },\n ];\n\n // Dynamically add each category column\n const categories = value\n ?.flatMap(x => x.summary.areaSummaries)\n .map(x => x.area)\n .filter((x, i, a) => a.indexOf(x) === i);\n categories?.forEach(category => {\n const column = {\n title: category,\n field: `summary.areaSummaries.${category}`,\n width: '10%',\n ...style,\n render: (row: EntityMaturitySummary) => (\n <ProgressCell\n areaSummary={row.summary.areaSummaries.find(x => x.area === category)}\n />\n ),\n };\n\n columns.push(column);\n });\n\n if (!value) return <></>;\n\n return (\n <Table\n title=\"Component Maturity\"\n subtitle=\"View this entity's children in order of lowest to highest Maturity.\"\n columns={columns}\n data={value ?? []}\n options={{\n pageSize: 10,\n columnsButton: true,\n rowStyle: {\n backgroundColor: theme.palette.background.paper,\n borderTop: `1px solid ${theme.palette.background.default}`,\n borderBottom: `1px solid ${theme.palette.background.default}`,\n },\n }}\n />\n );\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Rank } from '@backstage-community/plugin-tech-insights-maturity-common';
|
|
2
|
+
import Typography from '@mui/material/Typography';
|
|
3
|
+
import Box from '@mui/material/Box';
|
|
4
|
+
import LinearProgress from '@mui/material/LinearProgress';
|
|
5
|
+
import Stack from '@mui/material/Stack';
|
|
6
|
+
import Tooltip from '@mui/material/Tooltip';
|
|
7
|
+
import { Line } from 'rc-progress';
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import { pluralize, getNextRankColor } from './utils.esm.js';
|
|
10
|
+
import { MaturityRankAvatar } from '../components/MaturityRankAvatar/MaturityRankAvatar.esm.js';
|
|
11
|
+
|
|
12
|
+
const AreaProgress = ({ areaSummary, variant }) => {
|
|
13
|
+
const { area, progress, rankProgress, rank, maxRank, isMaxRank } = areaSummary;
|
|
14
|
+
let result = /* @__PURE__ */ React.createElement(LinearProgress, { color: "secondary", variant: "indeterminate" });
|
|
15
|
+
if (progress) {
|
|
16
|
+
const nextRankName = isMaxRank ? Rank[maxRank] : Rank[rank + 1];
|
|
17
|
+
const progressCaption = isMaxRank ? "Max rank!" : `${rankProgress.percentage}% to ${nextRankName}`;
|
|
18
|
+
const remainingRankTasks = rankProgress.totalChecks - rankProgress.passedChecks;
|
|
19
|
+
const rankCheckInfo = `${remainingRankTasks} task${pluralize(
|
|
20
|
+
remainingRankTasks
|
|
21
|
+
)} left to reach ${nextRankName} rank in this area`;
|
|
22
|
+
const rankProgressTooltip = isMaxRank ? "" : rankCheckInfo;
|
|
23
|
+
const remainingTasks = progress.totalChecks - progress.passedChecks;
|
|
24
|
+
const checkInfo = `${remainingTasks} task${pluralize(
|
|
25
|
+
remainingTasks
|
|
26
|
+
)} left until area is fully mature (currently ${progress.percentage}%)`;
|
|
27
|
+
const progressTooltip = /* @__PURE__ */ React.createElement(React.Fragment, null, rankProgressTooltip, rankProgressTooltip !== "" && /* @__PURE__ */ React.createElement("br", null), checkInfo);
|
|
28
|
+
const fontVariant = variant === "infoCard" ? "body1" : "body2";
|
|
29
|
+
const logoSize = variant === "infoCard" ? 20 : 17;
|
|
30
|
+
result = /* @__PURE__ */ React.createElement(Stack, { key: area }, /* @__PURE__ */ React.createElement(Stack, { direction: "row", spacing: 1 }, /* @__PURE__ */ React.createElement(MaturityRankAvatar, { value: areaSummary, size: logoSize }), /* @__PURE__ */ React.createElement(Typography, { variant: fontVariant, gutterBottom: true, color: "textPrimary" }, area), /* @__PURE__ */ React.createElement(Typography, { variant: fontVariant, color: "textSecondary" }, progressCaption)), /* @__PURE__ */ React.createElement(Tooltip, { title: progressTooltip }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(
|
|
31
|
+
Line,
|
|
32
|
+
{
|
|
33
|
+
key: area,
|
|
34
|
+
strokeColor: getNextRankColor(rank, maxRank),
|
|
35
|
+
trailColor: "rgba(0, 0, 0, 0.1)",
|
|
36
|
+
strokeWidth: 2,
|
|
37
|
+
trailWidth: 2,
|
|
38
|
+
percent: rankProgress.percentage,
|
|
39
|
+
"data-testid": "progressbar"
|
|
40
|
+
}
|
|
41
|
+
))));
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export { AreaProgress };
|
|
47
|
+
//# sourceMappingURL=AreaProgress.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AreaProgress.esm.js","sources":["../../src/helpers/AreaProgress.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\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 */\nimport {\n MaturitySummaryByArea,\n Rank,\n} from '@backstage-community/plugin-tech-insights-maturity-common';\nimport Typography from '@mui/material/Typography';\nimport Box from '@mui/material/Box';\nimport LinearProgress from '@mui/material/LinearProgress';\nimport Stack from '@mui/material/Stack';\nimport Tooltip from '@mui/material/Tooltip';\nimport { Line } from 'rc-progress';\nimport React from 'react';\nimport { getNextRankColor, pluralize } from './utils';\nimport { MaturityRankAvatar } from '../components/MaturityRankAvatar';\n\ntype Props = {\n areaSummary: MaturitySummaryByArea;\n variant?: 'gridItem' | 'infoCard';\n};\n\nexport const AreaProgress = ({ areaSummary, variant }: Props) => {\n const { area, progress, rankProgress, rank, maxRank, isMaxRank } =\n areaSummary;\n let result = <LinearProgress color=\"secondary\" variant=\"indeterminate\" />;\n\n if (progress) {\n const nextRankName = isMaxRank ? Rank[maxRank] : Rank[rank + 1];\n const progressCaption = isMaxRank\n ? 'Max rank!'\n : `${rankProgress.percentage}% to ${nextRankName}`;\n\n const remainingRankTasks =\n rankProgress.totalChecks - rankProgress.passedChecks;\n const rankCheckInfo = `${remainingRankTasks} task${pluralize(\n remainingRankTasks,\n )} left to reach ${nextRankName} rank in this area`;\n const rankProgressTooltip = isMaxRank ? '' : rankCheckInfo;\n\n const remainingTasks = progress.totalChecks - progress.passedChecks;\n const checkInfo = `${remainingTasks} task${pluralize(\n remainingTasks,\n )} left until area is fully mature (currently ${progress.percentage}%)`;\n const progressTooltip = (\n <>\n {rankProgressTooltip}\n {rankProgressTooltip !== '' && <br />}\n {checkInfo}\n </>\n );\n\n const fontVariant = variant === 'infoCard' ? 'body1' : 'body2';\n const logoSize = variant === 'infoCard' ? 20 : 17;\n\n result = (\n <Stack key={area}>\n <Stack direction=\"row\" spacing={1}>\n <MaturityRankAvatar value={areaSummary} size={logoSize} />\n <Typography variant={fontVariant} gutterBottom color=\"textPrimary\">\n {area}\n </Typography>\n <Typography variant={fontVariant} color=\"textSecondary\">\n {progressCaption}\n </Typography>\n </Stack>\n <Tooltip title={progressTooltip}>\n <Box>\n <Line\n key={area}\n strokeColor={getNextRankColor(rank, maxRank)}\n trailColor=\"rgba(0, 0, 0, 0.1)\"\n strokeWidth={2}\n trailWidth={2}\n percent={rankProgress.percentage}\n data-testid=\"progressbar\"\n />\n </Box>\n </Tooltip>\n </Stack>\n );\n }\n\n return result;\n};\n"],"names":[],"mappings":";;;;;;;;;;;AAkCO,MAAM,YAAe,GAAA,CAAC,EAAE,WAAA,EAAa,SAAqB,KAAA;AAC/D,EAAA,MAAM,EAAE,IAAM,EAAA,QAAA,EAAU,cAAc,IAAM,EAAA,OAAA,EAAS,WACnD,GAAA,WAAA;AACF,EAAA,IAAI,yBAAU,KAAA,CAAA,aAAA,CAAA,cAAA,EAAA,EAAe,KAAM,EAAA,WAAA,EAAY,SAAQ,eAAgB,EAAA,CAAA;AAEvE,EAAA,IAAI,QAAU,EAAA;AACZ,IAAA,MAAM,eAAe,SAAY,GAAA,IAAA,CAAK,OAAO,CAAI,GAAA,IAAA,CAAK,OAAO,CAAC,CAAA;AAC9D,IAAA,MAAM,kBAAkB,SACpB,GAAA,WAAA,GACA,GAAG,YAAa,CAAA,UAAU,QAAQ,YAAY,CAAA,CAAA;AAElD,IAAM,MAAA,kBAAA,GACJ,YAAa,CAAA,WAAA,GAAc,YAAa,CAAA,YAAA;AAC1C,IAAM,MAAA,aAAA,GAAgB,CAAG,EAAA,kBAAkB,CAAQ,KAAA,EAAA,SAAA;AAAA,MACjD;AAAA,KACD,kBAAkB,YAAY,CAAA,kBAAA,CAAA;AAC/B,IAAM,MAAA,mBAAA,GAAsB,YAAY,EAAK,GAAA,aAAA;AAE7C,IAAM,MAAA,cAAA,GAAiB,QAAS,CAAA,WAAA,GAAc,QAAS,CAAA,YAAA;AACvD,IAAM,MAAA,SAAA,GAAY,CAAG,EAAA,cAAc,CAAQ,KAAA,EAAA,SAAA;AAAA,MACzC;AAAA,KACD,CAA+C,4CAAA,EAAA,QAAA,CAAS,UAAU,CAAA,EAAA,CAAA;AACnE,IAAM,MAAA,eAAA,6DAED,mBACA,EAAA,mBAAA,KAAwB,sBAAO,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,IAAG,GAClC,SACH,CAAA;AAGF,IAAM,MAAA,WAAA,GAAc,OAAY,KAAA,UAAA,GAAa,OAAU,GAAA,OAAA;AACvD,IAAM,MAAA,QAAA,GAAW,OAAY,KAAA,UAAA,GAAa,EAAK,GAAA,EAAA;AAE/C,IAAA,MAAA,uCACG,KAAM,EAAA,EAAA,GAAA,EAAK,wBACT,KAAA,CAAA,aAAA,CAAA,KAAA,EAAA,EAAM,WAAU,KAAM,EAAA,OAAA,EAAS,CAC9B,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,sBAAmB,KAAO,EAAA,WAAA,EAAa,MAAM,QAAU,EAAA,CAAA,sCACvD,UAAW,EAAA,EAAA,OAAA,EAAS,WAAa,EAAA,YAAA,EAAY,MAAC,KAAM,EAAA,aAAA,EAAA,EAClD,IACH,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,cAAW,OAAS,EAAA,WAAA,EAAa,OAAM,eACrC,EAAA,EAAA,eACH,CACF,CACA,kBAAA,KAAA,CAAA,aAAA,CAAC,WAAQ,KAAO,EAAA,eAAA,EAAA,sCACb,GACC,EAAA,IAAA,kBAAA,KAAA,CAAA,aAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QACC,GAAK,EAAA,IAAA;AAAA,QACL,WAAA,EAAa,gBAAiB,CAAA,IAAA,EAAM,OAAO,CAAA;AAAA,QAC3C,UAAW,EAAA,oBAAA;AAAA,QACX,WAAa,EAAA,CAAA;AAAA,QACb,UAAY,EAAA,CAAA;AAAA,QACZ,SAAS,YAAa,CAAA,UAAA;AAAA,QACtB,aAAY,EAAA;AAAA;AAAA,KAEhB,CACF,CACF,CAAA;AAAA;AAIJ,EAAO,OAAA,MAAA;AACT;;;;"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Link } from '@backstage/core-components';
|
|
2
|
+
import Tooltip from '@mui/material/Tooltip';
|
|
3
|
+
import HelpOutline from '@mui/icons-material/HelpOutline';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
const MaturityHelp = () => /* @__PURE__ */ React.createElement(Tooltip, { title: "Click here to learn more about Maturity!" }, /* @__PURE__ */ React.createElement(Link, { to: "https://github.com/backstage/community-plugins/blob/main/workspaces/tech-insights/plugins/tech-insights-maturity/README.md" }, /* @__PURE__ */ React.createElement(HelpOutline, { color: "info", style: { paddingLeft: "0.2rem" } })));
|
|
7
|
+
|
|
8
|
+
export { MaturityHelp };
|
|
9
|
+
//# sourceMappingURL=MaturityHelp.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaturityHelp.esm.js","sources":["../../src/helpers/MaturityHelp.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\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 */\nimport { Link } from '@backstage/core-components';\nimport Tooltip from '@mui/material/Tooltip';\nimport HelpOutline from '@mui/icons-material/HelpOutline';\nimport React from 'react';\n\nexport const MaturityHelp = () => (\n <Tooltip title=\"Click here to learn more about Maturity!\">\n <Link to=\"https://github.com/backstage/community-plugins/blob/main/workspaces/tech-insights/plugins/tech-insights-maturity/README.md\">\n <HelpOutline color=\"info\" style={{ paddingLeft: '0.2rem' }} />\n </Link>\n </Tooltip>\n);\n"],"names":[],"mappings":";;;;;AAoBa,MAAA,YAAA,GAAe,sBACzB,KAAA,CAAA,aAAA,CAAA,OAAA,EAAA,EAAQ,OAAM,0CACb,EAAA,kBAAA,KAAA,CAAA,aAAA,CAAC,QAAK,EAAG,EAAA,4HAAA,EAAA,sCACN,WAAY,EAAA,EAAA,KAAA,EAAM,QAAO,KAAO,EAAA,EAAE,aAAa,QAAS,EAAA,EAAG,CAC9D,CACF;;;;"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { parseEntityRef, getCompoundEntityRef } from '@backstage/catalog-model';
|
|
2
|
+
import { Link } from '@backstage/core-components';
|
|
3
|
+
import { createRouteRef, useRouteRef } from '@backstage/core-plugin-api';
|
|
4
|
+
import { EntityDisplayName } from '@backstage/plugin-catalog-react';
|
|
5
|
+
import { getOrCreateGlobalSingleton } from '@backstage/version-bridge';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
|
|
8
|
+
const entityRouteRef = getOrCreateGlobalSingleton(
|
|
9
|
+
"catalog:entity-route-ref",
|
|
10
|
+
() => createRouteRef({
|
|
11
|
+
id: "catalog:entity",
|
|
12
|
+
params: ["namespace", "kind", "name"]
|
|
13
|
+
})
|
|
14
|
+
);
|
|
15
|
+
const MaturityLink = ({
|
|
16
|
+
entity,
|
|
17
|
+
children
|
|
18
|
+
}) => {
|
|
19
|
+
const entityRoute = useRouteRef(entityRouteRef);
|
|
20
|
+
const compoundEntityRef = typeof entity === "string" ? parseEntityRef(entity) : getCompoundEntityRef(entity);
|
|
21
|
+
return /* @__PURE__ */ React.createElement(Link, { to: `${entityRoute(compoundEntityRef)}/maturity` }, children ?? /* @__PURE__ */ React.createElement(EntityDisplayName, { entityRef: compoundEntityRef }));
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export { MaturityLink };
|
|
25
|
+
//# sourceMappingURL=MaturityLink.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaturityLink.esm.js","sources":["../../src/helpers/MaturityLink.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\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 */\nimport {\n Entity,\n getCompoundEntityRef,\n parseEntityRef,\n} from '@backstage/catalog-model';\nimport { Link } from '@backstage/core-components';\nimport { createRouteRef, useRouteRef } from '@backstage/core-plugin-api';\nimport { EntityDisplayName } from '@backstage/plugin-catalog-react';\nimport { getOrCreateGlobalSingleton } from '@backstage/version-bridge';\nimport React, { PropsWithChildren } from 'react';\n\nconst entityRouteRef = getOrCreateGlobalSingleton(\n 'catalog:entity-route-ref',\n () =>\n createRouteRef({\n id: 'catalog:entity',\n params: ['namespace', 'kind', 'name'],\n }),\n);\n\ntype Props = {\n entity: Entity | string;\n};\n\nexport const MaturityLink = ({\n entity,\n children,\n}: PropsWithChildren<Props>) => {\n const entityRoute = useRouteRef(entityRouteRef);\n const compoundEntityRef =\n typeof entity === 'string'\n ? parseEntityRef(entity)\n : getCompoundEntityRef(entity);\n\n return (\n <Link to={`${entityRoute(compoundEntityRef)}/maturity`}>\n {children ?? <EntityDisplayName entityRef={compoundEntityRef} />}\n </Link>\n );\n};\n"],"names":[],"mappings":";;;;;;;AA0BA,MAAM,cAAiB,GAAA,0BAAA;AAAA,EACrB,0BAAA;AAAA,EACA,MACE,cAAe,CAAA;AAAA,IACb,EAAI,EAAA,gBAAA;AAAA,IACJ,MAAQ,EAAA,CAAC,WAAa,EAAA,MAAA,EAAQ,MAAM;AAAA,GACrC;AACL,CAAA;AAMO,MAAM,eAAe,CAAC;AAAA,EAC3B,MAAA;AAAA,EACA;AACF,CAAgC,KAAA;AAC9B,EAAM,MAAA,WAAA,GAAc,YAAY,cAAc,CAAA;AAC9C,EAAM,MAAA,iBAAA,GACJ,OAAO,MAAW,KAAA,QAAA,GACd,eAAe,MAAM,CAAA,GACrB,qBAAqB,MAAM,CAAA;AAEjC,EAAA,uBACG,KAAA,CAAA,aAAA,CAAA,IAAA,EAAA,EAAK,EAAI,EAAA,CAAA,EAAG,WAAY,CAAA,iBAAiB,CAAC,CAAA,SAAA,CAAA,EAAA,EACxC,QAAY,oBAAA,KAAA,CAAA,aAAA,CAAC,iBAAkB,EAAA,EAAA,SAAA,EAAW,mBAAmB,CAChE,CAAA;AAEJ;;;;"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Rank } from '@backstage-community/plugin-tech-insights-maturity-common';
|
|
2
|
+
import Bronze from '../img/bronze.png';
|
|
3
|
+
import Gold from '../img/gold.png';
|
|
4
|
+
import Silver from '../img/silver.png';
|
|
5
|
+
import Stone from '../img/stone.png';
|
|
6
|
+
|
|
7
|
+
const RankImg = {
|
|
8
|
+
Stone,
|
|
9
|
+
Bronze,
|
|
10
|
+
Silver,
|
|
11
|
+
Gold
|
|
12
|
+
};
|
|
13
|
+
const getRankImg = (rank) => {
|
|
14
|
+
let img;
|
|
15
|
+
switch (rank) {
|
|
16
|
+
case Rank.Bronze:
|
|
17
|
+
img = RankImg.Bronze;
|
|
18
|
+
break;
|
|
19
|
+
case Rank.Silver:
|
|
20
|
+
img = RankImg.Silver;
|
|
21
|
+
break;
|
|
22
|
+
case Rank.Gold:
|
|
23
|
+
img = RankImg.Gold;
|
|
24
|
+
break;
|
|
25
|
+
default:
|
|
26
|
+
img = RankImg.Stone;
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
return img;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export { getRankImg as default };
|
|
33
|
+
//# sourceMappingURL=Rank.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Rank.esm.js","sources":["../../src/helpers/Rank.tsx"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\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 */\nimport { Rank } from '@backstage-community/plugin-tech-insights-maturity-common';\nimport Bronze from '../img/bronze.png';\nimport Gold from '../img/gold.png';\nimport Silver from '../img/silver.png';\nimport Stone from '../img/stone.png';\n\nconst RankImg = {\n Stone,\n Bronze,\n Silver,\n Gold,\n};\n\nconst getRankImg = (rank?: Rank) => {\n let img;\n switch (rank) {\n case Rank.Bronze:\n img = RankImg.Bronze;\n break;\n case Rank.Silver:\n img = RankImg.Silver;\n break;\n case Rank.Gold:\n img = RankImg.Gold;\n break;\n default:\n img = RankImg.Stone;\n break;\n }\n return img;\n};\n\nexport default getRankImg;\n"],"names":[],"mappings":";;;;;;AAqBA,MAAM,OAAU,GAAA;AAAA,EACd,KAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA;AAEM,MAAA,UAAA,GAAa,CAAC,IAAgB,KAAA;AAClC,EAAI,IAAA,GAAA;AACJ,EAAA,QAAQ,IAAM;AAAA,IACZ,KAAK,IAAK,CAAA,MAAA;AACR,MAAA,GAAA,GAAM,OAAQ,CAAA,MAAA;AACd,MAAA;AAAA,IACF,KAAK,IAAK,CAAA,MAAA;AACR,MAAA,GAAA,GAAM,OAAQ,CAAA,MAAA;AACd,MAAA;AAAA,IACF,KAAK,IAAK,CAAA,IAAA;AACR,MAAA,GAAA,GAAM,OAAQ,CAAA,IAAA;AACd,MAAA;AAAA,IACF;AACE,MAAA,GAAA,GAAM,OAAQ,CAAA,KAAA;AACd,MAAA;AAAA;AAEJ,EAAO,OAAA,GAAA;AACT;;;;"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { RELATION_PARENT_OF, RELATION_OWNER_OF, RELATION_HAS_PART } from '@backstage/catalog-model';
|
|
2
|
+
import { Rank } from '@backstage-community/plugin-tech-insights-maturity-common';
|
|
3
|
+
|
|
4
|
+
const getSubEntityFilter = (entity) => {
|
|
5
|
+
let type = RELATION_HAS_PART;
|
|
6
|
+
if (entity.kind === "Group") {
|
|
7
|
+
type = entity.relations?.find(
|
|
8
|
+
(x) => [RELATION_PARENT_OF, RELATION_OWNER_OF].includes(x.type)
|
|
9
|
+
)?.type ?? RELATION_OWNER_OF;
|
|
10
|
+
}
|
|
11
|
+
return { type };
|
|
12
|
+
};
|
|
13
|
+
const getRankColor = (rank) => {
|
|
14
|
+
switch (rank) {
|
|
15
|
+
case Rank.Stone:
|
|
16
|
+
return "#70797D";
|
|
17
|
+
case Rank.Bronze:
|
|
18
|
+
return "#704A07";
|
|
19
|
+
case Rank.Silver:
|
|
20
|
+
return "#C4C4C4";
|
|
21
|
+
case Rank.Gold:
|
|
22
|
+
return "#DEB82D";
|
|
23
|
+
default:
|
|
24
|
+
return "#70797E";
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const getNextRankColor = (rank, maxRank) => {
|
|
28
|
+
if (maxRank === rank) {
|
|
29
|
+
return "limegreen";
|
|
30
|
+
}
|
|
31
|
+
return getRankColor(rank + 1);
|
|
32
|
+
};
|
|
33
|
+
const pluralize = (count) => {
|
|
34
|
+
if (count === 1) {
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
return "s";
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export { getNextRankColor, getRankColor, getSubEntityFilter, pluralize };
|
|
41
|
+
//# sourceMappingURL=utils.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.esm.js","sources":["../../src/helpers/utils.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\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 */\nimport {\n Entity,\n RELATION_HAS_PART,\n RELATION_OWNER_OF,\n RELATION_PARENT_OF,\n} from '@backstage/catalog-model';\nimport { Rank } from '@backstage-community/plugin-tech-insights-maturity-common';\n\nexport const getSubEntityFilter = (entity: Entity): { type: string } => {\n let type = RELATION_HAS_PART;\n if (entity.kind === 'Group') {\n type =\n entity.relations?.find(x =>\n [RELATION_PARENT_OF, RELATION_OWNER_OF].includes(x.type),\n )?.type ?? RELATION_OWNER_OF;\n }\n return { type };\n};\n\nexport const getRankColor = (rank: Rank) => {\n switch (rank) {\n case Rank.Stone:\n return '#70797D';\n case Rank.Bronze:\n return '#704A07';\n case Rank.Silver:\n return '#C4C4C4';\n case Rank.Gold:\n return '#DEB82D';\n default:\n return '#70797E';\n }\n};\n\nexport const getNextRankColor = (rank: Rank, maxRank: Rank) => {\n if (maxRank === rank) {\n return 'limegreen';\n }\n return getRankColor(rank + 1);\n};\n\nexport const pluralize = (count: number) => {\n if (count === 1) {\n return '';\n }\n return 's';\n};\n"],"names":[],"mappings":";;;AAuBa,MAAA,kBAAA,GAAqB,CAAC,MAAqC,KAAA;AACtE,EAAA,IAAI,IAAO,GAAA,iBAAA;AACX,EAAI,IAAA,MAAA,CAAO,SAAS,OAAS,EAAA;AAC3B,IAAA,IAAA,GACE,OAAO,SAAW,EAAA,IAAA;AAAA,MAAK,OACrB,CAAC,kBAAA,EAAoB,iBAAiB,CAAE,CAAA,QAAA,CAAS,EAAE,IAAI;AAAA,OACtD,IAAQ,IAAA,iBAAA;AAAA;AAEf,EAAA,OAAO,EAAE,IAAK,EAAA;AAChB;AAEa,MAAA,YAAA,GAAe,CAAC,IAAe,KAAA;AAC1C,EAAA,QAAQ,IAAM;AAAA,IACZ,KAAK,IAAK,CAAA,KAAA;AACR,MAAO,OAAA,SAAA;AAAA,IACT,KAAK,IAAK,CAAA,MAAA;AACR,MAAO,OAAA,SAAA;AAAA,IACT,KAAK,IAAK,CAAA,MAAA;AACR,MAAO,OAAA,SAAA;AAAA,IACT,KAAK,IAAK,CAAA,IAAA;AACR,MAAO,OAAA,SAAA;AAAA,IACT;AACE,MAAO,OAAA,SAAA;AAAA;AAEb;AAEa,MAAA,gBAAA,GAAmB,CAAC,IAAA,EAAY,OAAkB,KAAA;AAC7D,EAAA,IAAI,YAAY,IAAM,EAAA;AACpB,IAAO,OAAA,WAAA;AAAA;AAET,EAAO,OAAA,YAAA,CAAa,OAAO,CAAC,CAAA;AAC9B;AAEa,MAAA,SAAA,GAAY,CAAC,KAAkB,KAAA;AAC1C,EAAA,IAAI,UAAU,CAAG,EAAA;AACf,IAAO,OAAA,EAAA;AAAA;AAET,EAAO,OAAA,GAAA;AACT;;;;"}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import * as _backstage_catalog_model_index from '@backstage/catalog-model/index';
|
|
3
|
+
import * as react from 'react';
|
|
4
|
+
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
5
|
+
import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';
|
|
6
|
+
import { TechInsightsApi, TechInsightsClient } from '@backstage-community/plugin-tech-insights';
|
|
7
|
+
import { Entity } from '@backstage/catalog-model';
|
|
8
|
+
import { MaturityRank, MaturityScore, BulkMaturityCheckResponse, MaturitySummary, BulkMaturitySummary } from '@backstage-community/plugin-tech-insights-maturity-common';
|
|
9
|
+
import { CatalogApi } from '@backstage/catalog-client';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
declare const techInsightsMaturityPlugin: _backstage_core_plugin_api.BackstagePlugin<{
|
|
15
|
+
root: _backstage_core_plugin_api.RouteRef<undefined>;
|
|
16
|
+
}, {}, {}>;
|
|
17
|
+
/**
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
declare const EntityMaturityScorecardContent: () => react.JSX.Element;
|
|
21
|
+
/**
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
declare const EntityMaturitySummaryContent: () => react.JSX.Element;
|
|
25
|
+
/**
|
|
26
|
+
* @public
|
|
27
|
+
*/
|
|
28
|
+
declare const EntityMaturityRankWidget: ({ entity }: {
|
|
29
|
+
entity: _backstage_catalog_model_index.Entity;
|
|
30
|
+
}) => react.JSX.Element;
|
|
31
|
+
/**
|
|
32
|
+
* @public
|
|
33
|
+
*/
|
|
34
|
+
declare const MaturityPage: () => react.JSX.Element;
|
|
35
|
+
/**
|
|
36
|
+
* @public
|
|
37
|
+
*/
|
|
38
|
+
declare const EntityMaturitySummaryCard: () => react.JSX.Element;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* {@link @backstage/core-plugin-api#ApiRef} for the {@link MaturityApi}
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
declare const maturityApiRef: _backstage_core_plugin_api.ApiRef<MaturityApi>;
|
|
46
|
+
/**
|
|
47
|
+
* Maturity API client interface extention of TechInsightsApi
|
|
48
|
+
*
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
type MaturityApi = TechInsightsApi & {
|
|
52
|
+
getMaturityRank(entity: Entity): Promise<MaturityRank>;
|
|
53
|
+
getMaturityScore(entity: Entity): Promise<MaturityScore>;
|
|
54
|
+
getBulkMaturityCheckResults(entities: Entity[]): Promise<BulkMaturityCheckResponse>;
|
|
55
|
+
getChildMaturityCheckResults(entity: Entity): Promise<BulkMaturityCheckResponse>;
|
|
56
|
+
getMaturitySummary(entity: Entity): Promise<MaturitySummary>;
|
|
57
|
+
getBulkMaturitySummary(entities: Entity[]): Promise<BulkMaturitySummary>;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* MaturityClient extension of TechInsightsClient
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
declare class MaturityClient extends TechInsightsClient implements MaturityApi {
|
|
66
|
+
readonly catalogApi: CatalogApi;
|
|
67
|
+
constructor(options: {
|
|
68
|
+
discoveryApi: DiscoveryApi;
|
|
69
|
+
identityApi: IdentityApi;
|
|
70
|
+
catalogApi: CatalogApi;
|
|
71
|
+
});
|
|
72
|
+
getMaturityRank(entity: Entity): Promise<MaturityRank>;
|
|
73
|
+
getBulkMaturityCheckResults(entities: Entity[]): Promise<BulkMaturityCheckResponse>;
|
|
74
|
+
getMaturityScore(entity: Entity): Promise<MaturityScore>;
|
|
75
|
+
getChildMaturityCheckResults(entity: Entity): Promise<BulkMaturityCheckResponse>;
|
|
76
|
+
getMaturitySummary(entity: Entity): Promise<MaturitySummary>;
|
|
77
|
+
getBulkMaturitySummary(entities: Entity[]): Promise<BulkMaturitySummary>;
|
|
78
|
+
private getCheckResults;
|
|
79
|
+
private getBulkCheckResults;
|
|
80
|
+
private getGroupCheckResults;
|
|
81
|
+
private getRelatedComponents;
|
|
82
|
+
private getComponentsForGroup;
|
|
83
|
+
private getRelatedComponentsByRefs;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export { EntityMaturityRankWidget, EntityMaturityScorecardContent, EntityMaturitySummaryCard, EntityMaturitySummaryContent, type MaturityApi, MaturityClient, MaturityPage, maturityApiRef, techInsightsMaturityPlugin };
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { EntityMaturityRankWidget, EntityMaturityScorecardContent, EntityMaturitySummaryCard, EntityMaturitySummaryContent, MaturityPage, techInsightsMaturityPlugin } from './plugin.esm.js';
|
|
2
|
+
export { maturityApiRef } from './api/MaturityApi.esm.js';
|
|
3
|
+
export { MaturityClient } from './api/MaturityClient.esm.js';
|
|
4
|
+
//# sourceMappingURL=index.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
|