@backstage-community/plugin-apiiro 0.1.0 → 1.0.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 +23 -0
- package/README.md +91 -12
- package/config.d.ts +14 -0
- package/dist/App.esm.js +96 -4
- package/dist/App.esm.js.map +1 -1
- package/dist/api/index.esm.js +6 -0
- package/dist/api/index.esm.js.map +1 -1
- package/dist/assets/SettingIcon.esm.js +1 -0
- package/dist/assets/SettingIcon.esm.js.map +1 -1
- package/dist/components/ApiiroSidebar.esm.js.map +1 -1
- package/dist/components/CalendarDatePicker.esm.js.map +1 -1
- package/dist/components/DataGrid/DataGrid.esm.js +1 -0
- package/dist/components/DataGrid/DataGrid.esm.js.map +1 -1
- package/dist/components/MetricsGroup/TabMetricsGroup.esm.js +28 -4
- package/dist/components/MetricsGroup/TabMetricsGroup.esm.js.map +1 -1
- package/dist/components/MetricsGroup/WidgetMetricsGroup.esm.js +30 -7
- package/dist/components/MetricsGroup/WidgetMetricsGroup.esm.js.map +1 -1
- package/dist/components/RiskLevel.esm.js +1 -0
- package/dist/components/RiskLevel.esm.js.map +1 -1
- package/dist/components/charts/GaugeChart.esm.js +8 -6
- package/dist/components/charts/GaugeChart.esm.js.map +1 -1
- package/dist/components/common/StatusContainer.esm.js +123 -0
- package/dist/components/common/StatusContainer.esm.js.map +1 -0
- package/dist/components/filters/DiscoveredOnFilter.esm.js +1 -1
- package/dist/components/filters/DiscoveredOnFilter.esm.js.map +1 -1
- package/dist/components/tiles/MttrVsSLATile.esm.js +31 -14
- package/dist/components/tiles/MttrVsSLATile.esm.js.map +1 -1
- package/dist/components/tiles/RiskOverTimeTile.esm.js +15 -12
- package/dist/components/tiles/RiskOverTimeTile.esm.js.map +1 -1
- package/dist/components/tiles/SLAAdherenceTile.esm.js +15 -12
- package/dist/components/tiles/SLAAdherenceTile.esm.js.map +1 -1
- package/dist/components/tiles/StatusTile.esm.js +98 -66
- package/dist/components/tiles/StatusTile.esm.js.map +1 -1
- package/dist/components/tiles/TopLanguagesTile.esm.js +1 -0
- package/dist/components/tiles/TopLanguagesTile.esm.js.map +1 -1
- package/dist/components/tiles/TopRiskTile.esm.js +19 -16
- package/dist/components/tiles/TopRiskTile.esm.js.map +1 -1
- package/dist/index.d.ts +31 -6
- package/dist/index.esm.js +2 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/pages/Applications/Applications.esm.js +104 -0
- package/dist/pages/Applications/Applications.esm.js.map +1 -0
- package/dist/pages/Applications/tableConfig.esm.js +147 -0
- package/dist/pages/Applications/tableConfig.esm.js.map +1 -0
- package/dist/pages/Repositories/Repositories.esm.js +26 -26
- package/dist/pages/Repositories/Repositories.esm.js.map +1 -1
- package/dist/pages/Repositories/tableConfig.esm.js +3 -2
- package/dist/pages/Repositories/tableConfig.esm.js.map +1 -1
- package/dist/pages/Risks/Risks.esm.js +9 -3
- package/dist/pages/Risks/Risks.esm.js.map +1 -1
- package/dist/pages/Risks/tableConfig.esm.js +25 -11
- package/dist/pages/Risks/tableConfig.esm.js.map +1 -1
- package/dist/pages/tab/ComponentTab.esm.js +72 -0
- package/dist/pages/tab/ComponentTab.esm.js.map +1 -0
- package/dist/pages/tab/SystemTab.esm.js +159 -0
- package/dist/pages/tab/SystemTab.esm.js.map +1 -0
- package/dist/pages/tab/TabProvider.esm.js +9 -3
- package/dist/pages/tab/TabProvider.esm.js.map +1 -1
- package/dist/pages/widget/ComponentWidget.esm.js +67 -0
- package/dist/pages/widget/ComponentWidget.esm.js.map +1 -0
- package/dist/pages/widget/SystemWidget.esm.js +81 -0
- package/dist/pages/widget/SystemWidget.esm.js.map +1 -0
- package/dist/pages/widget/WidgetProvider.esm.js +9 -3
- package/dist/pages/widget/WidgetProvider.esm.js.map +1 -1
- package/dist/plugin.esm.js.map +1 -1
- package/dist/queries/application.queries.esm.js +64 -0
- package/dist/queries/application.queries.esm.js.map +1 -0
- package/dist/queries/mttr-statistics.queries.esm.js +19 -12
- package/dist/queries/mttr-statistics.queries.esm.js.map +1 -1
- package/dist/queries/repository.queries.esm.js +19 -8
- package/dist/queries/repository.queries.esm.js.map +1 -1
- package/dist/queries/risk-score-over-time.queries.esm.js +19 -12
- package/dist/queries/risk-score-over-time.queries.esm.js.map +1 -1
- package/dist/queries/risks.queries.esm.js +19 -7
- package/dist/queries/risks.queries.esm.js.map +1 -1
- package/dist/queries/sla-breach.queries.esm.js +22 -11
- package/dist/queries/sla-breach.queries.esm.js.map +1 -1
- package/dist/queries/top-risks.queries.esm.js +19 -7
- package/dist/queries/top-risks.queries.esm.js.map +1 -1
- package/dist/theme/themeUtils.esm.js +5 -2
- package/dist/theme/themeUtils.esm.js.map +1 -1
- package/dist/utils/utils.esm.js +3 -2
- package/dist/utils/utils.esm.js.map +1 -1
- package/package.json +12 -12
- package/dist/pages/tab/Tab.esm.js +0 -147
- package/dist/pages/tab/Tab.esm.js.map +0 -1
- package/dist/pages/widget/Widget.esm.js +0 -161
- package/dist/pages/widget/Widget.esm.js.map +0 -1
|
@@ -15,8 +15,11 @@ import { APIIRO_DEFAULT_BASE_URL } from '@backstage-community/plugin-apiiro-comm
|
|
|
15
15
|
import '../common/ChartBox.esm.js';
|
|
16
16
|
import { CustomTooltip } from '../common/CustomTooltip.esm.js';
|
|
17
17
|
import { NotFound } from '../common/NotFound.esm.js';
|
|
18
|
+
import '../common/StatusContainer.esm.js';
|
|
18
19
|
import { scmProviderIcons, generateRepoURL } from '../common/scmProviders.esm.js';
|
|
19
20
|
import { SettingIcon } from '../../assets/SettingIcon.esm.js';
|
|
21
|
+
import { useApi } from '@backstage/core-plugin-api';
|
|
22
|
+
import { apiiroApiRef } from '../../api/index.esm.js';
|
|
20
23
|
|
|
21
24
|
const ThemedIcon = styled("span")(({ theme }) => ({
|
|
22
25
|
display: "inline-flex",
|
|
@@ -148,85 +151,114 @@ const StatusTile = ({
|
|
|
148
151
|
width = "100%",
|
|
149
152
|
height = "auto",
|
|
150
153
|
repository,
|
|
154
|
+
application,
|
|
151
155
|
detailViewLink = null,
|
|
152
156
|
allowViewChart = true
|
|
153
157
|
}) => {
|
|
154
|
-
|
|
158
|
+
const isApplication = !!application;
|
|
159
|
+
const data = isApplication ? application : repository;
|
|
160
|
+
const connectApi = useApi(apiiroApiRef);
|
|
161
|
+
const redirectDevView = connectApi.getRedirectDevView();
|
|
162
|
+
if (!data || Object.keys(data).length === 0) {
|
|
155
163
|
return /* @__PURE__ */ jsxs(StatusBox, { width, height, alignContent: "flex-start", children: [
|
|
156
164
|
/* @__PURE__ */ jsx(CustomHeaderData, { title: "" }),
|
|
157
|
-
/* @__PURE__ */ jsx(
|
|
165
|
+
/* @__PURE__ */ jsx(
|
|
166
|
+
NotFound,
|
|
167
|
+
{
|
|
168
|
+
message: `Results for this ${isApplication ? "application" : "repository"} are either unavailable on Apiiro or can not be accessed.`
|
|
169
|
+
}
|
|
170
|
+
)
|
|
158
171
|
] });
|
|
159
172
|
}
|
|
160
|
-
const
|
|
161
|
-
const
|
|
162
|
-
const
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
173
|
+
const profileType = isApplication ? "applications" : "repositories";
|
|
174
|
+
const profileKey = isApplication ? application.key : repository.key;
|
|
175
|
+
const apiiroUrl = `${APIIRO_DEFAULT_BASE_URL}/profiles/${profileType}/${profileKey}`;
|
|
176
|
+
const queryParams = redirectDevView ? "?devView=true" : "";
|
|
177
|
+
const actionUrl = `${apiiroUrl}/risk/development${queryParams}`;
|
|
178
|
+
const renderActivityRow = () => {
|
|
179
|
+
if (isApplication) {
|
|
180
|
+
if (application.isActive === void 0) return null;
|
|
181
|
+
return /* @__PURE__ */ jsxs(StatusRow, { children: [
|
|
182
|
+
/* @__PURE__ */ jsx(StatusLabel, { children: "Activity:" }),
|
|
183
|
+
/* @__PURE__ */ jsx(StatusValue, { children: /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center" }, children: [
|
|
184
|
+
/* @__PURE__ */ jsx(StatusIndicator, { isActive: application.isActive }),
|
|
185
|
+
application.isActive ? "Active" : "Inactive"
|
|
186
|
+
] }) })
|
|
187
|
+
] });
|
|
188
|
+
}
|
|
189
|
+
if (!repository.lastActivity || !repository.activeSince) return null;
|
|
190
|
+
return /* @__PURE__ */ jsx(
|
|
191
|
+
CustomTooltip,
|
|
192
|
+
{
|
|
193
|
+
title: formatActivityTooltip(
|
|
194
|
+
repository.lastActivity,
|
|
195
|
+
repository.activeSince
|
|
196
|
+
),
|
|
197
|
+
placement: "bottom",
|
|
198
|
+
children: /* @__PURE__ */ jsxs(StatusRow, { children: [
|
|
199
|
+
/* @__PURE__ */ jsx(StatusLabel, { children: "Activity:" }),
|
|
200
|
+
/* @__PURE__ */ jsx(StatusValue, { children: /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center" }, children: [
|
|
201
|
+
/* @__PURE__ */ jsx(StatusIndicator, { isActive: repository.isActive }),
|
|
202
|
+
repository.isActive ? `In development for ${getDevelopmentDuration(
|
|
203
|
+
repository.activeSince
|
|
204
|
+
)}` : "Inactive"
|
|
205
|
+
] }) })
|
|
206
|
+
] })
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
};
|
|
210
|
+
const renderRiskScoreRow = () => {
|
|
211
|
+
const riskScore = isApplication ? application.riskScore ?? 0 : repository.riskScore;
|
|
212
|
+
return /* @__PURE__ */ jsx(
|
|
213
|
+
CustomTooltip,
|
|
214
|
+
{
|
|
215
|
+
title: "A weighted value based on the number of risks at each severity level.",
|
|
216
|
+
placement: "top",
|
|
217
|
+
children: /* @__PURE__ */ jsxs(StatusRow, { children: [
|
|
218
|
+
/* @__PURE__ */ jsx(StatusLabel, { children: "Risk score:" }),
|
|
219
|
+
/* @__PURE__ */ jsx(StatusValue, { children: formatNumberWithSuffix(riskScore) })
|
|
220
|
+
] })
|
|
221
|
+
}
|
|
222
|
+
);
|
|
223
|
+
};
|
|
224
|
+
const renderBranchRow = () => {
|
|
225
|
+
if (isApplication) return null;
|
|
226
|
+
const ProviderIconComponent = scmProviderIcons[repository.provider];
|
|
227
|
+
const settingsUrl = `${apiiroUrl}/profile/${repository.scmRepositoryKey}/multi-branch`;
|
|
228
|
+
return /* @__PURE__ */ jsxs(StatusRow, { children: [
|
|
229
|
+
ProviderIconComponent && /* @__PURE__ */ jsx(ThemedIcon, { children: /* @__PURE__ */ jsx(ProviderIconComponent, {}) }),
|
|
230
|
+
/* @__PURE__ */ jsx(
|
|
231
|
+
BranchLink,
|
|
168
232
|
{
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
placement: "bottom",
|
|
174
|
-
children: /* @__PURE__ */ jsxs(StatusRow, { children: [
|
|
175
|
-
/* @__PURE__ */ jsx(StatusLabel, { children: "Activity:" }),
|
|
176
|
-
/* @__PURE__ */ jsx(StatusValue, { children: /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center" }, children: [
|
|
177
|
-
/* @__PURE__ */ jsx(StatusIndicator, { isActive: repository.isActive }),
|
|
178
|
-
repository.isActive ? `In development for ${getDevelopmentDuration(
|
|
179
|
-
repository.activeSince
|
|
180
|
-
)}` : "Inactive"
|
|
181
|
-
] }) })
|
|
182
|
-
] })
|
|
233
|
+
to: generateRepoURL(repository) || "",
|
|
234
|
+
target: "_blank",
|
|
235
|
+
rel: "noopener noreferrer",
|
|
236
|
+
children: `Analyzing ${repository.branchName} branch`
|
|
183
237
|
}
|
|
184
238
|
),
|
|
185
239
|
/* @__PURE__ */ jsx(
|
|
186
|
-
|
|
240
|
+
Link,
|
|
187
241
|
{
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
] })
|
|
242
|
+
to: settingsUrl,
|
|
243
|
+
target: "_blank",
|
|
244
|
+
rel: "noopener noreferrer",
|
|
245
|
+
style: { display: "inline-flex", marginLeft: "4px" },
|
|
246
|
+
children: /* @__PURE__ */ jsx(SettingIcon, {})
|
|
194
247
|
}
|
|
195
|
-
)
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
{
|
|
210
|
-
to: settingsUrl,
|
|
211
|
-
target: "_blank",
|
|
212
|
-
rel: "noopener noreferrer",
|
|
213
|
-
style: { display: "inline-flex", marginLeft: "4px" },
|
|
214
|
-
children: /* @__PURE__ */ jsx(SettingIcon, {})
|
|
215
|
-
}
|
|
216
|
-
)
|
|
217
|
-
] }),
|
|
218
|
-
/* @__PURE__ */ jsxs(ActionLinks, { children: [
|
|
219
|
-
allowViewChart && /* @__PURE__ */ jsx(
|
|
220
|
-
ActionLink,
|
|
221
|
-
{
|
|
222
|
-
to: apiiroRepoUrl,
|
|
223
|
-
target: "_blank",
|
|
224
|
-
rel: "noopener noreferrer",
|
|
225
|
-
children: "Go to Apiiro \u2192"
|
|
226
|
-
}
|
|
227
|
-
),
|
|
228
|
-
detailViewLink && /* @__PURE__ */ jsx(ActionLink, { to: detailViewLink, children: "Detail View \u2192" })
|
|
229
|
-
] })
|
|
248
|
+
)
|
|
249
|
+
] });
|
|
250
|
+
};
|
|
251
|
+
const renderActionLinks = () => /* @__PURE__ */ jsxs(ActionLinks, { children: [
|
|
252
|
+
allowViewChart && /* @__PURE__ */ jsx(ActionLink, { to: actionUrl, target: "_blank", rel: "noopener noreferrer", children: "Go to Apiiro \u2192" }),
|
|
253
|
+
detailViewLink && /* @__PURE__ */ jsx(ActionLink, { to: detailViewLink, children: "Detail View \u2192" })
|
|
254
|
+
] });
|
|
255
|
+
return /* @__PURE__ */ jsxs(StatusBox, { width, height, alignContent: "flex-start", children: [
|
|
256
|
+
/* @__PURE__ */ jsx(CustomHeaderData, { title }),
|
|
257
|
+
/* @__PURE__ */ jsxs(StatusContent, { children: [
|
|
258
|
+
renderActivityRow(),
|
|
259
|
+
renderRiskScoreRow(),
|
|
260
|
+
renderBranchRow(),
|
|
261
|
+
renderActionLinks()
|
|
230
262
|
] })
|
|
231
263
|
] });
|
|
232
264
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusTile.esm.js","sources":["../../../src/components/tiles/StatusTile.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 Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport { styled } from '@mui/material/styles';\nimport {\n getActivityStatusColors,\n getLogoContainerColors,\n} from '../../theme/themeUtils';\nimport { Link } from 'react-router-dom';\nimport { ApiiroLogo } from '../../assets/apiiroLogo';\nimport { formatNumberWithSuffix } from '../../utils';\nimport {\n formatActivityTooltip,\n getDevelopmentDuration,\n} from '../../utils/dateFormatter';\nimport { RepositoryType } from '../../queries/queries.type';\nimport { CustomTooltip, NotFound } from '../common';\nimport { generateRepoURL, scmProviderIcons } from '../common/scmProviders';\nimport { APIIRO_DEFAULT_BASE_URL } from '@backstage-community/plugin-apiiro-common';\nimport SettingIcon from '../../assets/SettingIcon';\n\nconst ThemedIcon = styled('span')(({ theme }) => ({\n display: 'inline-flex',\n '& svg': {\n color: theme.palette.text.primary,\n flexShrink: 0,\n },\n '&:hover svg': {\n color: theme.palette.primary.main,\n },\n}));\n\nconst StatusIndicator = styled('span')<{ isActive: boolean }>(\n ({ theme, isActive }) => {\n const activityColors = getActivityStatusColors(theme);\n return {\n display: 'inline-block',\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: isActive\n ? activityColors.active\n : activityColors.inactive,\n marginRight: 8,\n };\n },\n);\n\nexport interface StatusTileProps {\n title?: string;\n width?: string | number;\n height?: string | number;\n repository: RepositoryType;\n detailViewLink?: string | null;\n allowViewChart?: boolean;\n}\n\nexport const StatusBox = styled(Box)<{\n width?: string | number;\n height?: string | number;\n}>(({ theme, width, height }) => ({\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: '12px',\n backgroundColor: theme.palette.background.paper,\n boxShadow: theme.shadows[1],\n width: width || 'fit-content',\n height: height || 'auto',\n margin: width === '100%' ? '0' : '0 auto',\n maxWidth: '100%',\n display: 'flex',\n flexDirection: 'column',\n boxSizing: 'border-box',\n}));\n\nconst StatusContent = styled(Box)(() => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: '12px',\n padding: '16px',\n}));\n\nconst StatusRow = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n}));\n\nconst StatusLabel = styled(Typography)(({ theme }) => ({\n fontSize: '16px',\n fontWeight: 400,\n color: theme.palette.text.secondary,\n}));\n\nconst StatusValue = styled(Typography)(({ theme }) => ({\n fontSize: '16px',\n fontWeight: 400,\n color: theme.palette.text.primary,\n}));\n\nconst BranchLink = styled(Link)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n fontSize: '16px',\n fontWeight: 400,\n color: theme.palette.info.main,\n textDecoration: 'underline',\n cursor: 'pointer',\n}));\n\nconst ActionLinks = styled(Box)(() => ({\n display: 'flex',\n gap: '16px',\n marginTop: '8px',\n}));\n\nconst ActionLink = styled(Link)(({ theme }) => ({\n fontSize: '16px',\n fontWeight: 400,\n color: theme.palette.info.main,\n textDecoration: 'none',\n cursor: 'pointer',\n}));\n\nconst CustomHeader = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: '12px',\n}));\n\nconst TitleContainer = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n paddingLeft: '16px',\n paddingTop: '16px',\n}));\n\nconst StyledTitle = styled(Typography)(({ theme }) => ({\n fontWeight: 400,\n fontSize: '16px',\n lineHeight: '24px',\n color: theme.palette.text.primary,\n}));\n\nconst LogoContainer = styled(Box)(({ theme }) => {\n const logoColors = getLogoContainerColors(theme);\n return {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'center',\n alignItems: 'center',\n padding: '12px 15px',\n gap: '10px',\n width: '109px',\n height: '40px',\n background: logoColors.background,\n borderRadius: '10px',\n '& svg': {\n width: '79px',\n height: '22px',\n '& path': {\n fill: logoColors.logoFill,\n },\n },\n };\n});\n\nconst CustomHeaderData = ({ title }: { title: string }) => (\n <CustomHeader>\n <TitleContainer>\n <StyledTitle>{title}</StyledTitle>\n </TitleContainer>\n <LogoContainer>\n <ApiiroLogo />\n </LogoContainer>\n </CustomHeader>\n);\n\nexport const StatusTile = ({\n title = 'Status',\n width = '100%',\n height = 'auto',\n repository,\n detailViewLink = null,\n allowViewChart = true,\n}: StatusTileProps) => {\n // Show message when no data is available\n if (Object.keys(repository).length === 0) {\n return (\n <StatusBox width={width} height={height} alignContent=\"flex-start\">\n <CustomHeaderData title=\"\" />\n <NotFound message=\"Results for this repository are either unavailable on Apiiro or cannot be accessed.\" />\n </StatusBox>\n );\n }\n\n const ProviderIconComponent = scmProviderIcons[repository.provider as string];\n const apiiroRepoUrl = `${APIIRO_DEFAULT_BASE_URL}/profiles/repositories/${repository.key}`;\n const settingsUrl = `${apiiroRepoUrl}/profile/${repository.scmRepositoryKey}/multi-branch`;\n\n return (\n <StatusBox width={width} height={height} alignContent=\"flex-start\">\n <CustomHeaderData title={title} />\n <StatusContent>\n {repository?.lastActivity && repository?.activeSince && (\n <CustomTooltip\n title={formatActivityTooltip(\n repository.lastActivity,\n repository.activeSince,\n )}\n placement=\"bottom\"\n >\n <StatusRow>\n <StatusLabel>Activity:</StatusLabel>\n <StatusValue>\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <StatusIndicator isActive={repository.isActive} />\n {repository.isActive\n ? `In development for ${getDevelopmentDuration(\n repository.activeSince,\n )}`\n : 'Inactive'}\n </Box>\n </StatusValue>\n </StatusRow>\n </CustomTooltip>\n )}\n <CustomTooltip\n title=\"A weighted value based on the number of risks at each severity level.\"\n placement=\"top\"\n >\n <StatusRow>\n <StatusLabel>Risk score:</StatusLabel>\n <StatusValue>\n {formatNumberWithSuffix(repository.riskScore)}\n </StatusValue>\n </StatusRow>\n </CustomTooltip>\n <StatusRow>\n {ProviderIconComponent && (\n <ThemedIcon>\n <ProviderIconComponent />\n </ThemedIcon>\n )}\n <BranchLink\n to={generateRepoURL(repository) || ''}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {`Analyzing ${repository.branchName} branch`}\n </BranchLink>\n <Link\n to={settingsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ display: 'inline-flex', marginLeft: '4px' }}\n >\n <SettingIcon />\n </Link>\n </StatusRow>\n <ActionLinks>\n {allowViewChart && (\n <ActionLink\n to={apiiroRepoUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n Go to Apiiro →\n </ActionLink>\n )}\n {detailViewLink && (\n <ActionLink to={detailViewLink}>Detail View →</ActionLink>\n )}\n </ActionLinks>\n </StatusContent>\n </StatusBox>\n );\n};\n\nexport default StatusTile;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"StatusTile.esm.js","sources":["../../../src/components/tiles/StatusTile.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 Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport { styled } from '@mui/material/styles';\nimport {\n getActivityStatusColors,\n getLogoContainerColors,\n} from '../../theme/themeUtils';\nimport { Link } from 'react-router-dom';\nimport { ApiiroLogo } from '../../assets/apiiroLogo';\nimport { formatNumberWithSuffix } from '../../utils';\nimport {\n formatActivityTooltip,\n getDevelopmentDuration,\n} from '../../utils/dateFormatter';\nimport { RepositoryType, ApplicationType } from '../../queries/queries.type';\nimport { CustomTooltip, NotFound } from '../common';\nimport { generateRepoURL, scmProviderIcons } from '../common/scmProviders';\nimport { APIIRO_DEFAULT_BASE_URL } from '@backstage-community/plugin-apiiro-common';\nimport SettingIcon from '../../assets/SettingIcon';\nimport { useApi } from '@backstage/core-plugin-api';\nimport { apiiroApiRef } from '../../api';\n\nconst ThemedIcon = styled('span')(({ theme }) => ({\n display: 'inline-flex',\n '& svg': {\n color: theme.palette.text.primary,\n flexShrink: 0,\n },\n '&:hover svg': {\n color: theme.palette.primary.main,\n },\n}));\n\nconst StatusIndicator = styled('span')<{ isActive: boolean }>(\n ({ theme, isActive }) => {\n const activityColors = getActivityStatusColors(theme);\n return {\n display: 'inline-block',\n width: 8,\n height: 8,\n borderRadius: '50%',\n backgroundColor: isActive\n ? activityColors.active\n : activityColors.inactive,\n marginRight: 8,\n };\n },\n);\n\nexport interface StatusTileProps {\n title?: string;\n width?: string | number;\n height?: string | number;\n repository?: RepositoryType;\n application?: ApplicationType;\n detailViewLink?: string | null;\n allowViewChart?: boolean;\n}\n\nexport const StatusBox = styled(Box)<{\n width?: string | number;\n height?: string | number;\n}>(({ theme, width, height }) => ({\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: '12px',\n backgroundColor: theme.palette.background.paper,\n boxShadow: theme.shadows[1],\n width: width || 'fit-content',\n height: height || 'auto',\n margin: width === '100%' ? '0' : '0 auto',\n maxWidth: '100%',\n display: 'flex',\n flexDirection: 'column',\n boxSizing: 'border-box',\n}));\n\nconst StatusContent = styled(Box)(() => ({\n display: 'flex',\n flexDirection: 'column',\n alignItems: 'flex-start',\n gap: '12px',\n padding: '16px',\n}));\n\nconst StatusRow = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n}));\n\nconst StatusLabel = styled(Typography)(({ theme }) => ({\n fontSize: '16px',\n fontWeight: 400,\n color: theme.palette.text.secondary,\n}));\n\nconst StatusValue = styled(Typography)(({ theme }) => ({\n fontSize: '16px',\n fontWeight: 400,\n color: theme.palette.text.primary,\n}));\n\nconst BranchLink = styled(Link)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n fontSize: '16px',\n fontWeight: 400,\n color: theme.palette.info.main,\n textDecoration: 'underline',\n cursor: 'pointer',\n}));\n\nconst ActionLinks = styled(Box)(() => ({\n display: 'flex',\n gap: '16px',\n marginTop: '8px',\n}));\n\nconst ActionLink = styled(Link)(({ theme }) => ({\n fontSize: '16px',\n fontWeight: 400,\n color: theme.palette.info.main,\n textDecoration: 'none',\n cursor: 'pointer',\n}));\n\nconst CustomHeader = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: '12px',\n}));\n\nconst TitleContainer = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n paddingLeft: '16px',\n paddingTop: '16px',\n}));\n\nconst StyledTitle = styled(Typography)(({ theme }) => ({\n fontWeight: 400,\n fontSize: '16px',\n lineHeight: '24px',\n color: theme.palette.text.primary,\n}));\n\nconst LogoContainer = styled(Box)(({ theme }) => {\n const logoColors = getLogoContainerColors(theme);\n return {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'center',\n alignItems: 'center',\n padding: '12px 15px',\n gap: '10px',\n width: '109px',\n height: '40px',\n background: logoColors.background,\n borderRadius: '10px',\n '& svg': {\n width: '79px',\n height: '22px',\n '& path': {\n fill: logoColors.logoFill,\n },\n },\n };\n});\n\nconst CustomHeaderData = ({ title }: { title: string }) => (\n <CustomHeader>\n <TitleContainer>\n <StyledTitle>{title}</StyledTitle>\n </TitleContainer>\n <LogoContainer>\n <ApiiroLogo />\n </LogoContainer>\n </CustomHeader>\n);\n\nexport const StatusTile = ({\n title = 'Status',\n width = '100%',\n height = 'auto',\n repository,\n application,\n detailViewLink = null,\n allowViewChart = true,\n}: StatusTileProps) => {\n const isApplication = !!application;\n const data = isApplication ? application : repository;\n const connectApi = useApi(apiiroApiRef);\n const redirectDevView = connectApi.getRedirectDevView();\n\n // Show message when no data is available\n if (!data || Object.keys(data).length === 0) {\n return (\n <StatusBox width={width} height={height} alignContent=\"flex-start\">\n <CustomHeaderData title=\"\" />\n <NotFound\n message={`Results for this ${\n isApplication ? 'application' : 'repository'\n } are either unavailable on Apiiro or can not be accessed.`}\n />\n </StatusBox>\n );\n }\n\n // Determine Apiiro URL based on type\n const profileType = isApplication ? 'applications' : 'repositories';\n const profileKey = isApplication ? application!.key : repository!.key;\n const apiiroUrl = `${APIIRO_DEFAULT_BASE_URL}/profiles/${profileType}/${profileKey}`;\n\n const queryParams = redirectDevView ? '?devView=true' : '';\n const actionUrl = `${apiiroUrl}/risk/development${queryParams}`;\n\n // Render Activity Row\n const renderActivityRow = () => {\n if (isApplication) {\n if (application!.isActive === undefined) return null;\n return (\n <StatusRow>\n <StatusLabel>Activity:</StatusLabel>\n <StatusValue>\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <StatusIndicator isActive={application!.isActive} />\n {application!.isActive ? 'Active' : 'Inactive'}\n </Box>\n </StatusValue>\n </StatusRow>\n );\n }\n\n // Repository activity with tooltip\n if (!repository!.lastActivity || !repository!.activeSince) return null;\n return (\n <CustomTooltip\n title={formatActivityTooltip(\n repository!.lastActivity,\n repository!.activeSince,\n )}\n placement=\"bottom\"\n >\n <StatusRow>\n <StatusLabel>Activity:</StatusLabel>\n <StatusValue>\n <Box sx={{ display: 'flex', alignItems: 'center' }}>\n <StatusIndicator isActive={repository!.isActive} />\n {repository!.isActive\n ? `In development for ${getDevelopmentDuration(\n repository!.activeSince,\n )}`\n : 'Inactive'}\n </Box>\n </StatusValue>\n </StatusRow>\n </CustomTooltip>\n );\n };\n\n // Render Risk Score Row (common for both)\n const renderRiskScoreRow = () => {\n const riskScore = isApplication\n ? application!.riskScore ?? 0\n : repository!.riskScore;\n return (\n <CustomTooltip\n title=\"A weighted value based on the number of risks at each severity level.\"\n placement=\"top\"\n >\n <StatusRow>\n <StatusLabel>Risk score:</StatusLabel>\n <StatusValue>{formatNumberWithSuffix(riskScore)}</StatusValue>\n </StatusRow>\n </CustomTooltip>\n );\n };\n\n // Render Repository-specific Branch Row\n const renderBranchRow = () => {\n if (isApplication) return null;\n\n const ProviderIconComponent =\n scmProviderIcons[repository!.provider as string];\n const settingsUrl = `${apiiroUrl}/profile/${\n repository!.scmRepositoryKey\n }/multi-branch`;\n\n return (\n <StatusRow>\n {ProviderIconComponent && (\n <ThemedIcon>\n <ProviderIconComponent />\n </ThemedIcon>\n )}\n <BranchLink\n to={generateRepoURL(repository!) || ''}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n >\n {`Analyzing ${repository!.branchName} branch`}\n </BranchLink>\n <Link\n to={settingsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{ display: 'inline-flex', marginLeft: '4px' }}\n >\n <SettingIcon />\n </Link>\n </StatusRow>\n );\n };\n\n // Render Action Links (common for both)\n const renderActionLinks = () => (\n <ActionLinks>\n {allowViewChart && (\n <ActionLink to={actionUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n Go to Apiiro →\n </ActionLink>\n )}\n {detailViewLink && (\n <ActionLink to={detailViewLink}>Detail View →</ActionLink>\n )}\n </ActionLinks>\n );\n\n return (\n <StatusBox width={width} height={height} alignContent=\"flex-start\">\n <CustomHeaderData title={title} />\n <StatusContent>\n {renderActivityRow()}\n {renderRiskScoreRow()}\n {renderBranchRow()}\n {renderActionLinks()}\n </StatusContent>\n </StatusBox>\n );\n};\n\nexport default StatusTile;\n"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ import { languageIconMap } from '../common/languageIcons.esm.js';
|
|
|
9
9
|
import { ChartBox } from '../common/ChartBox.esm.js';
|
|
10
10
|
import { CustomTooltip } from '../common/CustomTooltip.esm.js';
|
|
11
11
|
import { NotFound } from '../common/NotFound.esm.js';
|
|
12
|
+
import '../common/StatusContainer.esm.js';
|
|
12
13
|
import { useMemo, useState, useEffect, useCallback } from 'react';
|
|
13
14
|
import { PieChart } from '../charts/PieChart.esm.js';
|
|
14
15
|
import '@mui/material/SvgIcon';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TopLanguagesTile.esm.js","sources":["../../../src/components/tiles/TopLanguagesTile.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 { styled, useTheme } from '@mui/material/styles';\nimport { getBlueColorVariants, getOtherColor } from '../../theme/themeUtils';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport List from '@mui/material/List';\nimport ListItem from '@mui/material/ListItem';\nimport { languageIconMap, LanguageKey } from '../common/languageIcons';\nimport { CustomTooltip } from '../common';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { ChartBox } from '../common/ChartBox';\nimport PieChart, { PieChartData } from '../charts/PieChart';\nimport { ApiiroSmall } from '../../assets/apiiroLogo';\nimport { NotFound } from '../common';\nimport Divider from '@mui/material/Divider';\n\nexport interface TopLanguagesTileProps {\n title?: string;\n tooltip?: string;\n data?: Record<string, number> | undefined;\n width?: string | number;\n height?: string | number;\n}\n\nconst LegendContainer = styled(Box)(() => ({\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'center',\n gap: '6px',\n}));\n\nconst LegendItem = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n fontSize: '12px',\n color: theme.palette.text.secondary,\n}));\n\nconst LegendColor = styled('div')<{ color: string }>(({ color }) => ({\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: color,\n flexShrink: 0,\n}));\n\nconst CustomHeader = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: '12px',\n}));\n\nconst TitleContainer = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n}));\n\nconst StyledTitle = styled(Typography)(({ theme }) => ({\n fontWeight: 400,\n fontSize: '16px',\n lineHeight: '24px',\n color: theme.palette.text.primary,\n}));\n\nconst mapLanguagePercentagesToPieData = (\n languagePercentages: Record<string, number>,\n): PieChartData[] =>\n Object.entries(languagePercentages)\n .map(([language, value], index) => {\n // Ensure value is a valid number, default to 0 if not\n const numericValue =\n typeof value === 'number' && !isNaN(value) ? value : 0;\n return {\n id: `${language.toLowerCase().replace(/[^a-z0-9]+/g, '-')}-${index}`,\n label: language,\n value: numericValue,\n };\n })\n .filter(item => item.value > 0);\n\nexport const TopLanguagesTile = ({\n title = 'Top languages',\n data = {},\n width = '100%',\n}: TopLanguagesTileProps) => {\n const theme = useTheme();\n const blueColorVariants = getBlueColorVariants(theme);\n const otherColor = getOtherColor(theme);\n\n const chartData = useMemo(() => {\n if (data && Object.keys(data).length > 0) {\n const mappedData = mapLanguagePercentagesToPieData(data);\n if (mappedData.length > 0) {\n return mappedData;\n }\n }\n\n return [];\n }, [data]);\n\n const [processedData, setProcessedData] = useState<PieChartData[]>(chartData);\n\n useEffect(() => {\n setProcessedData(chartData);\n }, [chartData]);\n\n const customHeader = (\n <CustomHeader>\n <TitleContainer>\n <StyledTitle>{title}</StyledTitle>\n <ApiiroSmall sx={{ width: 20, height: 20, color: 'text.primary' }} />\n </TitleContainer>\n </CustomHeader>\n );\n // Generate colors for legend items based on data length\n const generateColor = useCallback(\n (index: number, itemId: string): string => {\n // If item id is \"other\", always use the other color\n if (itemId === 'other') {\n return otherColor;\n }\n\n // If index is within blue variants, use blue colors\n if (index < blueColorVariants.length) {\n return blueColorVariants[index];\n }\n\n // For additional items beyond blue variants, use the other color\n return otherColor;\n },\n [blueColorVariants, otherColor],\n );\n\n const legend = (\n <LegendContainer>\n {processedData.slice(0, 5).map((item, index) => (\n <LegendItem key={item.id}>\n <LegendColor color={item.color || generateColor(index, item.id)} />\n <Typography variant=\"caption\">{item.label}</Typography>\n </LegendItem>\n ))}\n {processedData.length > 5 && (\n <CustomTooltip\n title={\n <List dense disablePadding>\n {processedData.slice(5).map(item => {\n const LanguageIcon =\n languageIconMap[item.label as LanguageKey] ||\n languageIconMap['Unknown' as LanguageKey];\n\n return (\n <ListItem\n key={item.id}\n disableGutters\n disablePadding\n sx={{ py: 0.5, px: 1, minWidth: 200 }}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n justifyContent: 'space-between',\n }}\n >\n <Box\n sx={{ display: 'flex', alignItems: 'center', gap: 1 }}\n >\n <Box\n sx={{\n width: 24,\n height: 24,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <LanguageIcon />\n </Box>\n <Typography\n variant=\"body2\"\n sx={{ fontSize: '12px', color: 'text.primary' }}\n >\n {item.label}\n </Typography>\n </Box>\n <Typography\n variant=\"body2\"\n sx={{\n fontSize: '12px',\n color: 'text.primary',\n fontWeight: 400,\n }}\n >\n {Math.round(item.value)}%\n </Typography>\n </Box>\n </ListItem>\n );\n })}\n <Divider />\n <Typography\n variant=\"body2\"\n sx={{ py: 1, fontSize: '12px', color: 'text.primary' }}\n >\n Less then 0.1%\n </Typography>\n </List>\n }\n placement=\"top\"\n >\n <LegendItem>\n <LegendColor color={generateColor(-1, 'other')} />\n <Typography variant=\"caption\">Other</Typography>\n </LegendItem>\n </CustomTooltip>\n )}\n </LegendContainer>\n );\n\n // Show message when no data is available\n if (Object.keys(data).length === 0 || processedData.length === 0) {\n return (\n <ChartBox title={title} width={width} customHeader={customHeader}>\n <NotFound />\n </ChartBox>\n );\n }\n\n return (\n <ChartBox\n title={title}\n width={width}\n footer={legend}\n customHeader={customHeader}\n >\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '100%',\n flex: 1,\n minHeight: 0,\n }}\n >\n <PieChart\n data={chartData}\n width={310}\n height={310}\n generateColor={generateColor}\n onDataProcessed={setProcessedData}\n />\n </div>\n </ChartBox>\n );\n};\n\nexport default TopLanguagesTile;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAsCA,MAAM,eAAA,GAAkB,MAAA,CAAO,GAAG,CAAA,CAAE,OAAO;AAAA,EACzC,OAAA,EAAS,MAAA;AAAA,EACT,QAAA,EAAU,MAAA;AAAA,EACV,cAAA,EAAgB,QAAA;AAAA,EAChB,GAAA,EAAK;AACP,CAAA,CAAE,CAAA;AAEF,MAAM,aAAa,MAAA,CAAO,GAAG,EAAE,CAAC,EAAE,OAAM,MAAO;AAAA,EAC7C,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,GAAA,EAAK,KAAA;AAAA,EACL,QAAA,EAAU,MAAA;AAAA,EACV,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK;AAC5B,CAAA,CAAE,CAAA;AAEF,MAAM,cAAc,MAAA,CAAO,KAAK,EAAqB,CAAC,EAAE,OAAM,MAAO;AAAA,EACnE,KAAA,EAAO,KAAA;AAAA,EACP,MAAA,EAAQ,KAAA;AAAA,EACR,YAAA,EAAc,KAAA;AAAA,EACd,eAAA,EAAiB,KAAA;AAAA,EACjB,UAAA,EAAY;AACd,CAAA,CAAE,CAAA;AAEF,MAAM,YAAA,GAAe,MAAA,CAAO,GAAG,CAAA,CAAE,OAAO;AAAA,EACtC,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,cAAA,EAAgB,eAAA;AAAA,EAChB,YAAA,EAAc;AAChB,CAAA,CAAE,CAAA;AAEF,MAAM,cAAA,GAAiB,MAAA,CAAO,GAAG,CAAA,CAAE,OAAO;AAAA,EACxC,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,GAAA,EAAK;AACP,CAAA,CAAE,CAAA;AAEF,MAAM,cAAc,MAAA,CAAO,UAAU,EAAE,CAAC,EAAE,OAAM,MAAO;AAAA,EACrD,UAAA,EAAY,GAAA;AAAA,EACZ,QAAA,EAAU,MAAA;AAAA,EACV,UAAA,EAAY,MAAA;AAAA,EACZ,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK;AAC5B,CAAA,CAAE,CAAA;AAEF,MAAM,+BAAA,GAAkC,CACtC,mBAAA,KAEA,MAAA,CAAO,OAAA,CAAQ,mBAAmB,CAAA,CAC/B,GAAA,CAAI,CAAC,CAAC,QAAA,EAAU,KAAK,GAAG,KAAA,KAAU;AAEjC,EAAA,MAAM,YAAA,GACJ,OAAO,KAAA,KAAU,QAAA,IAAY,CAAC,KAAA,CAAM,KAAK,IAAI,KAAA,GAAQ,CAAA;AACvD,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,CAAA,EAAG,QAAA,CAAS,WAAA,EAAY,CAAE,QAAQ,aAAA,EAAe,GAAG,CAAC,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA;AAAA,IAClE,KAAA,EAAO,QAAA;AAAA,IACP,KAAA,EAAO;AAAA,GACT;AACF,CAAC,CAAA,CACA,MAAA,CAAO,CAAA,IAAA,KAAQ,IAAA,CAAK,QAAQ,CAAC,CAAA;AAE3B,MAAM,mBAAmB,CAAC;AAAA,EAC/B,KAAA,GAAQ,eAAA;AAAA,EACR,OAAO,EAAC;AAAA,EACR,KAAA,GAAQ;AACV,CAAA,KAA6B;AAC3B,EAAA,MAAM,QAAQ,QAAA,EAAS;AACvB,EAAA,MAAM,iBAAA,GAAoB,qBAAqB,KAAK,CAAA;AACpD,EAAA,MAAM,UAAA,GAAa,cAAc,KAAK,CAAA;AAEtC,EAAA,MAAM,SAAA,GAAY,QAAQ,MAAM;AAC9B,IAAA,IAAI,QAAQ,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,CAAE,SAAS,CAAA,EAAG;AACxC,MAAA,MAAM,UAAA,GAAa,gCAAgC,IAAI,CAAA;AACvD,MAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,QAAA,OAAO,UAAA;AAAA,MACT;AAAA,IACF;AAEA,IAAA,OAAO,EAAC;AAAA,EACV,CAAA,EAAG,CAAC,IAAI,CAAC,CAAA;AAET,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAyB,SAAS,CAAA;AAE5E,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,gBAAA,CAAiB,SAAS,CAAA;AAAA,EAC5B,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AAEd,EAAA,MAAM,YAAA,mBACJ,GAAA,CAAC,YAAA,EAAA,EACC,QAAA,kBAAA,IAAA,CAAC,cAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,eAAa,QAAA,EAAA,KAAA,EAAM,CAAA;AAAA,oBACpB,GAAA,CAAC,WAAA,EAAA,EAAY,EAAA,EAAI,EAAE,KAAA,EAAO,IAAI,MAAA,EAAQ,EAAA,EAAI,KAAA,EAAO,cAAA,EAAe,EAAG;AAAA,GAAA,EACrE,CAAA,EACF,CAAA;AAGF,EAAA,MAAM,aAAA,GAAgB,WAAA;AAAA,IACpB,CAAC,OAAe,MAAA,KAA2B;AAEzC,MAAA,IAAI,WAAW,OAAA,EAAS;AACtB,QAAA,OAAO,UAAA;AAAA,MACT;AAGA,MAAA,IAAI,KAAA,GAAQ,kBAAkB,MAAA,EAAQ;AACpC,QAAA,OAAO,kBAAkB,KAAK,CAAA;AAAA,MAChC;AAGA,MAAA,OAAO,UAAA;AAAA,IACT,CAAA;AAAA,IACA,CAAC,mBAAmB,UAAU;AAAA,GAChC;AAEA,EAAA,MAAM,MAAA,wBACH,eAAA,EAAA,EACE,QAAA,EAAA;AAAA,IAAA,aAAA,CAAc,KAAA,CAAM,GAAG,CAAC,CAAA,CAAE,IAAI,CAAC,IAAA,EAAM,KAAA,qBACpC,IAAA,CAAC,UAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,WAAA,EAAA,EAAY,OAAO,IAAA,CAAK,KAAA,IAAS,cAAc,KAAA,EAAO,IAAA,CAAK,EAAE,CAAA,EAAG,CAAA;AAAA,sBACjE,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,SAAA,EAAW,eAAK,KAAA,EAAM;AAAA,KAAA,EAAA,EAF3B,IAAA,CAAK,EAGtB,CACD,CAAA;AAAA,IACA,aAAA,CAAc,SAAS,CAAA,oBACtB,GAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,uBACE,IAAA,CAAC,IAAA,EAAA,EAAK,KAAA,EAAK,IAAA,EAAC,gBAAc,IAAA,EACvB,QAAA,EAAA;AAAA,UAAA,aAAA,CAAc,KAAA,CAAM,CAAC,CAAA,CAAE,GAAA,CAAI,CAAA,IAAA,KAAQ;AAClC,YAAA,MAAM,eACJ,eAAA,CAAgB,IAAA,CAAK,KAAoB,CAAA,IACzC,gBAAgB,SAAwB,CAAA;AAE1C,YAAA,uBACE,GAAA;AAAA,cAAC,QAAA;AAAA,cAAA;AAAA,gBAEC,cAAA,EAAc,IAAA;AAAA,gBACd,cAAA,EAAc,IAAA;AAAA,gBACd,IAAI,EAAE,EAAA,EAAI,KAAK,EAAA,EAAI,CAAA,EAAG,UAAU,GAAA,EAAI;AAAA,gBAEpC,QAAA,kBAAA,IAAA;AAAA,kBAAC,GAAA;AAAA,kBAAA;AAAA,oBACC,EAAA,EAAI;AAAA,sBACF,OAAA,EAAS,MAAA;AAAA,sBACT,UAAA,EAAY,QAAA;AAAA,sBACZ,KAAA,EAAO,MAAA;AAAA,sBACP,cAAA,EAAgB;AAAA,qBAClB;AAAA,oBAEA,QAAA,EAAA;AAAA,sCAAA,IAAA;AAAA,wBAAC,GAAA;AAAA,wBAAA;AAAA,0BACC,IAAI,EAAE,OAAA,EAAS,QAAQ,UAAA,EAAY,QAAA,EAAU,KAAK,CAAA,EAAE;AAAA,0BAEpD,QAAA,EAAA;AAAA,4CAAA,GAAA;AAAA,8BAAC,GAAA;AAAA,8BAAA;AAAA,gCACC,EAAA,EAAI;AAAA,kCACF,KAAA,EAAO,EAAA;AAAA,kCACP,MAAA,EAAQ,EAAA;AAAA,kCACR,OAAA,EAAS,MAAA;AAAA,kCACT,UAAA,EAAY,QAAA;AAAA,kCACZ,cAAA,EAAgB;AAAA,iCAClB;AAAA,gCAEA,8BAAC,YAAA,EAAA,EAAa;AAAA;AAAA,6BAChB;AAAA,4CACA,GAAA;AAAA,8BAAC,UAAA;AAAA,8BAAA;AAAA,gCACC,OAAA,EAAQ,OAAA;AAAA,gCACR,EAAA,EAAI,EAAE,QAAA,EAAU,MAAA,EAAQ,OAAO,cAAA,EAAe;AAAA,gCAE7C,QAAA,EAAA,IAAA,CAAK;AAAA;AAAA;AACR;AAAA;AAAA,uBACF;AAAA,sCACA,IAAA;AAAA,wBAAC,UAAA;AAAA,wBAAA;AAAA,0BACC,OAAA,EAAQ,OAAA;AAAA,0BACR,EAAA,EAAI;AAAA,4BACF,QAAA,EAAU,MAAA;AAAA,4BACV,KAAA,EAAO,cAAA;AAAA,4BACP,UAAA,EAAY;AAAA,2BACd;AAAA,0BAEC,QAAA,EAAA;AAAA,4BAAA,IAAA,CAAK,KAAA,CAAM,KAAK,KAAK,CAAA;AAAA,4BAAE;AAAA;AAAA;AAAA;AAC1B;AAAA;AAAA;AACF,eAAA;AAAA,cA5CK,IAAA,CAAK;AAAA,aA6CZ;AAAA,UAEJ,CAAC,CAAA;AAAA,8BACA,OAAA,EAAA,EAAQ,CAAA;AAAA,0BACT,GAAA;AAAA,YAAC,UAAA;AAAA,YAAA;AAAA,cACC,OAAA,EAAQ,OAAA;AAAA,cACR,IAAI,EAAE,EAAA,EAAI,GAAG,QAAA,EAAU,MAAA,EAAQ,OAAO,cAAA,EAAe;AAAA,cACtD,QAAA,EAAA;AAAA;AAAA;AAED,SAAA,EACF,CAAA;AAAA,QAEF,SAAA,EAAU,KAAA;AAAA,QAEV,+BAAC,UAAA,EAAA,EACC,QAAA,EAAA;AAAA,0BAAA,GAAA,CAAC,WAAA,EAAA,EAAY,KAAA,EAAO,aAAA,CAAc,EAAA,EAAI,OAAO,CAAA,EAAG,CAAA;AAAA,0BAChD,GAAA,CAAC,UAAA,EAAA,EAAW,OAAA,EAAQ,SAAA,EAAU,QAAA,EAAA,OAAA,EAAK;AAAA,SAAA,EACrC;AAAA;AAAA;AACF,GAAA,EAEJ,CAAA;AAIF,EAAA,IAAI,MAAA,CAAO,KAAK,IAAI,CAAA,CAAE,WAAW,CAAA,IAAK,aAAA,CAAc,WAAW,CAAA,EAAG;AAChE,IAAA,2BACG,QAAA,EAAA,EAAS,KAAA,EAAc,OAAc,YAAA,EACpC,QAAA,kBAAA,GAAA,CAAC,YAAS,CAAA,EACZ,CAAA;AAAA,EAEJ;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,KAAA;AAAA,MACA,KAAA;AAAA,MACA,MAAA,EAAQ,MAAA;AAAA,MACR,YAAA;AAAA,MAEA,QAAA,kBAAA,GAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,KAAA,EAAO;AAAA,YACL,OAAA,EAAS,MAAA;AAAA,YACT,cAAA,EAAgB,QAAA;AAAA,YAChB,UAAA,EAAY,QAAA;AAAA,YACZ,KAAA,EAAO,MAAA;AAAA,YACP,IAAA,EAAM,CAAA;AAAA,YACN,SAAA,EAAW;AAAA,WACb;AAAA,UAEA,QAAA,kBAAA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,IAAA,EAAM,SAAA;AAAA,cACN,KAAA,EAAO,GAAA;AAAA,cACP,MAAA,EAAQ,GAAA;AAAA,cACR,aAAA;AAAA,cACA,eAAA,EAAiB;AAAA;AAAA;AACnB;AAAA;AACF;AAAA,GACF;AAEJ;;;;"}
|
|
1
|
+
{"version":3,"file":"TopLanguagesTile.esm.js","sources":["../../../src/components/tiles/TopLanguagesTile.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 { styled, useTheme } from '@mui/material/styles';\nimport { getBlueColorVariants, getOtherColor } from '../../theme/themeUtils';\nimport Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport List from '@mui/material/List';\nimport ListItem from '@mui/material/ListItem';\nimport { languageIconMap, LanguageKey } from '../common/languageIcons';\nimport { CustomTooltip } from '../common';\nimport { useCallback, useEffect, useMemo, useState } from 'react';\nimport { ChartBox } from '../common/ChartBox';\nimport PieChart, { PieChartData } from '../charts/PieChart';\nimport { ApiiroSmall } from '../../assets/apiiroLogo';\nimport { NotFound } from '../common';\nimport Divider from '@mui/material/Divider';\n\nexport interface TopLanguagesTileProps {\n title?: string;\n tooltip?: string;\n data?: Record<string, number> | undefined;\n width?: string | number;\n height?: string | number;\n}\n\nconst LegendContainer = styled(Box)(() => ({\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'center',\n gap: '6px',\n}));\n\nconst LegendItem = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: '6px',\n fontSize: '12px',\n color: theme.palette.text.secondary,\n}));\n\nconst LegendColor = styled('div')<{ color: string }>(({ color }) => ({\n width: '8px',\n height: '8px',\n borderRadius: '50%',\n backgroundColor: color,\n flexShrink: 0,\n}));\n\nconst CustomHeader = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: '12px',\n}));\n\nconst TitleContainer = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n}));\n\nconst StyledTitle = styled(Typography)(({ theme }) => ({\n fontWeight: 400,\n fontSize: '16px',\n lineHeight: '24px',\n color: theme.palette.text.primary,\n}));\n\nconst mapLanguagePercentagesToPieData = (\n languagePercentages: Record<string, number>,\n): PieChartData[] =>\n Object.entries(languagePercentages)\n .map(([language, value], index) => {\n // Ensure value is a valid number, default to 0 if not\n const numericValue =\n typeof value === 'number' && !isNaN(value) ? value : 0;\n return {\n id: `${language.toLowerCase().replace(/[^a-z0-9]+/g, '-')}-${index}`,\n label: language,\n value: numericValue,\n };\n })\n .filter(item => item.value > 0);\n\nexport const TopLanguagesTile = ({\n title = 'Top languages',\n data = {},\n width = '100%',\n}: TopLanguagesTileProps) => {\n const theme = useTheme();\n const blueColorVariants = getBlueColorVariants(theme);\n const otherColor = getOtherColor(theme);\n\n const chartData = useMemo(() => {\n if (data && Object.keys(data).length > 0) {\n const mappedData = mapLanguagePercentagesToPieData(data);\n if (mappedData.length > 0) {\n return mappedData;\n }\n }\n\n return [];\n }, [data]);\n\n const [processedData, setProcessedData] = useState<PieChartData[]>(chartData);\n\n useEffect(() => {\n setProcessedData(chartData);\n }, [chartData]);\n\n const customHeader = (\n <CustomHeader>\n <TitleContainer>\n <StyledTitle>{title}</StyledTitle>\n <ApiiroSmall sx={{ width: 20, height: 20, color: 'text.primary' }} />\n </TitleContainer>\n </CustomHeader>\n );\n // Generate colors for legend items based on data length\n const generateColor = useCallback(\n (index: number, itemId: string): string => {\n // If item id is \"other\", always use the other color\n if (itemId === 'other') {\n return otherColor;\n }\n\n // If index is within blue variants, use blue colors\n if (index < blueColorVariants.length) {\n return blueColorVariants[index];\n }\n\n // For additional items beyond blue variants, use the other color\n return otherColor;\n },\n [blueColorVariants, otherColor],\n );\n\n const legend = (\n <LegendContainer>\n {processedData.slice(0, 5).map((item, index) => (\n <LegendItem key={item.id}>\n <LegendColor color={item.color || generateColor(index, item.id)} />\n <Typography variant=\"caption\">{item.label}</Typography>\n </LegendItem>\n ))}\n {processedData.length > 5 && (\n <CustomTooltip\n title={\n <List dense disablePadding>\n {processedData.slice(5).map(item => {\n const LanguageIcon =\n languageIconMap[item.label as LanguageKey] ||\n languageIconMap['Unknown' as LanguageKey];\n\n return (\n <ListItem\n key={item.id}\n disableGutters\n disablePadding\n sx={{ py: 0.5, px: 1, minWidth: 200 }}\n >\n <Box\n sx={{\n display: 'flex',\n alignItems: 'center',\n width: '100%',\n justifyContent: 'space-between',\n }}\n >\n <Box\n sx={{ display: 'flex', alignItems: 'center', gap: 1 }}\n >\n <Box\n sx={{\n width: 24,\n height: 24,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n }}\n >\n <LanguageIcon />\n </Box>\n <Typography\n variant=\"body2\"\n sx={{ fontSize: '12px', color: 'text.primary' }}\n >\n {item.label}\n </Typography>\n </Box>\n <Typography\n variant=\"body2\"\n sx={{\n fontSize: '12px',\n color: 'text.primary',\n fontWeight: 400,\n }}\n >\n {Math.round(item.value)}%\n </Typography>\n </Box>\n </ListItem>\n );\n })}\n <Divider />\n <Typography\n variant=\"body2\"\n sx={{ py: 1, fontSize: '12px', color: 'text.primary' }}\n >\n Less then 0.1%\n </Typography>\n </List>\n }\n placement=\"top\"\n >\n <LegendItem>\n <LegendColor color={generateColor(-1, 'other')} />\n <Typography variant=\"caption\">Other</Typography>\n </LegendItem>\n </CustomTooltip>\n )}\n </LegendContainer>\n );\n\n // Show message when no data is available\n if (Object.keys(data).length === 0 || processedData.length === 0) {\n return (\n <ChartBox title={title} width={width} customHeader={customHeader}>\n <NotFound />\n </ChartBox>\n );\n }\n\n return (\n <ChartBox\n title={title}\n width={width}\n footer={legend}\n customHeader={customHeader}\n >\n <div\n style={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n width: '100%',\n flex: 1,\n minHeight: 0,\n }}\n >\n <PieChart\n data={chartData}\n width={310}\n height={310}\n generateColor={generateColor}\n onDataProcessed={setProcessedData}\n />\n </div>\n </ChartBox>\n );\n};\n\nexport default TopLanguagesTile;\n"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ import { apiiroApiRef } from '../../api/index.esm.js';
|
|
|
9
9
|
import { CustomTooltip } from '../common/CustomTooltip.esm.js';
|
|
10
10
|
import { NotFound } from '../common/NotFound.esm.js';
|
|
11
11
|
import { SomethingWentWrong } from '../common/SomethingWentWrong.esm.js';
|
|
12
|
+
import '../common/StatusContainer.esm.js';
|
|
12
13
|
import { LogoSpinner } from '../common/logoSpinner.esm.js';
|
|
13
14
|
import { RiskLevel } from '../RiskLevel.esm.js';
|
|
14
15
|
import '@mui/material/SvgIcon';
|
|
@@ -91,7 +92,8 @@ const TopRiskTile = ({
|
|
|
91
92
|
width = "100%",
|
|
92
93
|
height = "366px",
|
|
93
94
|
repoId,
|
|
94
|
-
entityRef
|
|
95
|
+
entityRef,
|
|
96
|
+
applicationId
|
|
95
97
|
}) => {
|
|
96
98
|
const customHeader = /* @__PURE__ */ jsx(CustomHeader, { children: /* @__PURE__ */ jsxs(TitleContainer, { children: [
|
|
97
99
|
/* @__PURE__ */ jsx(StyledTitle, { children: title }),
|
|
@@ -103,15 +105,10 @@ const TopRiskTile = ({
|
|
|
103
105
|
connectApi: connectBackendApi,
|
|
104
106
|
fetchApi: fetch,
|
|
105
107
|
repoId,
|
|
106
|
-
entityRef
|
|
108
|
+
entityRef,
|
|
109
|
+
applicationId
|
|
107
110
|
});
|
|
108
|
-
|
|
109
|
-
ruleName: point.ruleName,
|
|
110
|
-
count: point.count,
|
|
111
|
-
severity: point.severity,
|
|
112
|
-
devPhase: point.devPhase
|
|
113
|
-
})) : data;
|
|
114
|
-
if (topRisksDataLoading) {
|
|
111
|
+
if (!repoId && !applicationId) {
|
|
115
112
|
return /* @__PURE__ */ jsx(
|
|
116
113
|
ChartBox,
|
|
117
114
|
{
|
|
@@ -125,14 +122,20 @@ const TopRiskTile = ({
|
|
|
125
122
|
display: "flex",
|
|
126
123
|
justifyContent: "center",
|
|
127
124
|
alignItems: "center",
|
|
128
|
-
minHeight: "
|
|
129
|
-
children: /* @__PURE__ */ jsx(
|
|
125
|
+
minHeight: "300px",
|
|
126
|
+
children: /* @__PURE__ */ jsx(NotFound, { message: "Please configure the apiiro annotation to access the data." })
|
|
130
127
|
}
|
|
131
128
|
)
|
|
132
129
|
}
|
|
133
130
|
);
|
|
134
131
|
}
|
|
135
|
-
|
|
132
|
+
const finalData = topRisksData ? topRisksData.map((point) => ({
|
|
133
|
+
ruleName: point.ruleName,
|
|
134
|
+
count: point.count,
|
|
135
|
+
severity: point.severity,
|
|
136
|
+
devPhase: point.devPhase
|
|
137
|
+
})) : data;
|
|
138
|
+
if (topRisksDataLoading) {
|
|
136
139
|
return /* @__PURE__ */ jsx(
|
|
137
140
|
ChartBox,
|
|
138
141
|
{
|
|
@@ -146,14 +149,14 @@ const TopRiskTile = ({
|
|
|
146
149
|
display: "flex",
|
|
147
150
|
justifyContent: "center",
|
|
148
151
|
alignItems: "center",
|
|
149
|
-
minHeight: "
|
|
150
|
-
children: /* @__PURE__ */ jsx(
|
|
152
|
+
minHeight: "250px",
|
|
153
|
+
children: /* @__PURE__ */ jsx(LogoSpinner, {})
|
|
151
154
|
}
|
|
152
155
|
)
|
|
153
156
|
}
|
|
154
157
|
);
|
|
155
158
|
}
|
|
156
|
-
if (
|
|
159
|
+
if (topRisksDataError) {
|
|
157
160
|
return /* @__PURE__ */ jsx(
|
|
158
161
|
ChartBox,
|
|
159
162
|
{
|
|
@@ -168,7 +171,7 @@ const TopRiskTile = ({
|
|
|
168
171
|
justifyContent: "center",
|
|
169
172
|
alignItems: "center",
|
|
170
173
|
minHeight: "300px",
|
|
171
|
-
children: /* @__PURE__ */ jsx(
|
|
174
|
+
children: /* @__PURE__ */ jsx(SomethingWentWrong, {})
|
|
172
175
|
}
|
|
173
176
|
)
|
|
174
177
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TopRiskTile.esm.js","sources":["../../../src/components/tiles/TopRiskTile.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 Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport { styled } from '@mui/material/styles';\nimport { fetchApiRef, useApi } from '@backstage/core-plugin-api';\nimport { ChartBox } from '../common/ChartBox';\nimport { useTopRisksData } from '../../queries/top-risks.queries';\nimport { apiiroApiRef } from '../../api';\nimport { TopRiskDataPoint } from '../../queries/queries.type';\nimport { CustomTooltip, NotFound, SomethingWentWrong } from '../common';\nimport { LogoSpinner } from '../common/logoSpinner';\nimport { RiskLevel } from '../RiskLevel';\nimport { ApiiroSmall } from '../../assets/apiiroLogo';\n\nexport interface TopRiskData {\n ruleName: string;\n count: number;\n severity: string;\n devPhase: string;\n}\n\nexport interface TopRiskTileProps {\n title?: string;\n tooltip?: string;\n data?: TopRiskData[];\n width?: string | number;\n height?: string | number;\n repoId?: string;\n entityRef?: string;\n}\n\nconst RiskListContainer = styled(Box)(() => ({\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n width: '100%',\n padding: '0 8px',\n}));\n\nconst RiskItem = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '12px 16px',\n borderRadius: '14px',\n border: `1px solid ${theme.palette.divider}`,\n minHeight: '48px',\n gap: '12px',\n cursor: 'pointer',\n transition: 'box-shadow 200ms ease-in-out',\n\n '&:hover': {\n boxShadow: '0 4px 8px rgba(0, 0, 0, 0.15)',\n },\n}));\n\nconst RiskContent = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n flex: 1,\n minWidth: 0, // Allow text truncation\n overflow: 'hidden', // Ensure container doesn't overflow\n}));\n\nconst TooltipWrapper = styled(Box)(() => ({\n flex: 1,\n minWidth: 0,\n overflow: 'hidden',\n display: 'flex',\n}));\n\nconst RiskName = styled(Typography)(({ theme }) => ({\n fontSize: '14px',\n fontWeight: 400,\n color: theme.palette.text.primary,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1,\n minWidth: 0,\n}));\n\nconst RiskCount = styled(Typography)(({ theme }) => ({\n fontSize: '16px',\n fontWeight: 500,\n color: theme.palette.text.primary,\n minWidth: 'fit-content',\n}));\n\nconst CustomHeader = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: '12px',\n}));\n\nconst TitleContainer = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n}));\n\nconst StyledTitle = styled(Typography)(({ theme }) => ({\n fontWeight: 400,\n fontSize: '16px',\n lineHeight: '24px',\n color: theme.palette.text.primary,\n}));\n\nexport const TopRiskTile = ({\n title = 'Top risks',\n data = [],\n width = '100%',\n height = '366px',\n repoId,\n entityRef,\n}: TopRiskTileProps) => {\n const customHeader = (\n <CustomHeader>\n <TitleContainer>\n <StyledTitle>{title}</StyledTitle>\n <ApiiroSmall sx={{ width: 20, height: 20, color: 'text.primary' }} />\n </TitleContainer>\n </CustomHeader>\n );\n // Use API hooks internally\n const connectBackendApi = useApi(apiiroApiRef);\n const { fetch } = useApi(fetchApiRef);\n\n // Always call the hook, but conditionally use the result\n const { topRisksData, topRisksDataError, topRisksDataLoading } =\n useTopRisksData({\n connectApi: connectBackendApi,\n fetchApi: fetch,\n repoId,\n entityRef,\n });\n\n // Transform API data to component data format\n const finalData: TopRiskData[] = topRisksData\n ? topRisksData.map((point: TopRiskDataPoint) => ({\n ruleName: point.ruleName,\n count: point.count,\n severity: point.severity,\n devPhase: point.devPhase,\n }))\n : data;\n\n // Show loading state while data is loading\n if (topRisksDataLoading) {\n return (\n <ChartBox\n title={title}\n width={width}\n height={height}\n customHeader={customHeader}\n >\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n minHeight=\"250px\"\n >\n <LogoSpinner />\n </Box>\n </ChartBox>\n );\n }\n\n // Show error state if there's an error\n if (topRisksDataError) {\n return (\n <ChartBox\n title={title}\n width={width}\n height={height}\n customHeader={customHeader}\n >\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n minHeight=\"300px\"\n >\n <SomethingWentWrong />\n </Box>\n </ChartBox>\n );\n }\n\n // Show message when no repository key is provided\n if (!repoId) {\n return (\n <ChartBox\n title={title}\n width={width}\n height={height}\n customHeader={customHeader}\n >\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n minHeight=\"300px\"\n >\n <NotFound message=\"Please provide the repository details to access the data.\" />\n </Box>\n </ChartBox>\n );\n }\n\n // Show message when no data is available\n if (finalData.length === 0) {\n return (\n <ChartBox\n title={title}\n width={width}\n height={height}\n customHeader={customHeader}\n >\n <NotFound />\n </ChartBox>\n );\n }\n\n return (\n <ChartBox\n title={title}\n width={width}\n height={height}\n customHeader={customHeader}\n >\n <RiskListContainer>\n {finalData.map((risk, index) => (\n <RiskItem key={`${risk.ruleName}-${index}`}>\n <RiskContent>\n <RiskLevel level={risk.severity} iconSize=\"large\" />\n <TooltipWrapper>\n <CustomTooltip title={risk.ruleName}>\n <RiskName>{risk.ruleName}</RiskName>\n </CustomTooltip>\n </TooltipWrapper>\n </RiskContent>\n <RiskCount>{risk.count}</RiskCount>\n </RiskItem>\n ))}\n </RiskListContainer>\n </ChartBox>\n );\n};\n\nexport default TopRiskTile;\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"TopRiskTile.esm.js","sources":["../../../src/components/tiles/TopRiskTile.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 Box from '@mui/material/Box';\nimport Typography from '@mui/material/Typography';\nimport { styled } from '@mui/material/styles';\nimport { fetchApiRef, useApi } from '@backstage/core-plugin-api';\nimport { ChartBox } from '../common/ChartBox';\nimport { useTopRisksData } from '../../queries/top-risks.queries';\nimport { apiiroApiRef } from '../../api';\nimport { TopRiskDataPoint } from '../../queries/queries.type';\nimport { CustomTooltip, NotFound, SomethingWentWrong } from '../common';\nimport { LogoSpinner } from '../common/logoSpinner';\nimport { RiskLevel } from '../RiskLevel';\nimport { ApiiroSmall } from '../../assets/apiiroLogo';\n\nexport interface TopRiskData {\n ruleName: string;\n count: number;\n severity: string;\n devPhase: string;\n}\n\nexport interface TopRiskTileProps {\n title?: string;\n tooltip?: string;\n data?: TopRiskData[];\n width?: string | number;\n height?: string | number;\n repoId?: string;\n entityRef?: string;\n applicationId?: string;\n}\n\nconst RiskListContainer = styled(Box)(() => ({\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n width: '100%',\n padding: '0 8px',\n}));\n\nconst RiskItem = styled(Box)(({ theme }) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '12px 16px',\n borderRadius: '14px',\n border: `1px solid ${theme.palette.divider}`,\n minHeight: '48px',\n gap: '12px',\n cursor: 'pointer',\n transition: 'box-shadow 200ms ease-in-out',\n\n '&:hover': {\n boxShadow: '0 4px 8px rgba(0, 0, 0, 0.15)',\n },\n}));\n\nconst RiskContent = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n flex: 1,\n minWidth: 0, // Allow text truncation\n overflow: 'hidden', // Ensure container doesn't overflow\n}));\n\nconst TooltipWrapper = styled(Box)(() => ({\n flex: 1,\n minWidth: 0,\n overflow: 'hidden',\n display: 'flex',\n}));\n\nconst RiskName = styled(Typography)(({ theme }) => ({\n fontSize: '14px',\n fontWeight: 400,\n color: theme.palette.text.primary,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1,\n minWidth: 0,\n}));\n\nconst RiskCount = styled(Typography)(({ theme }) => ({\n fontSize: '16px',\n fontWeight: 500,\n color: theme.palette.text.primary,\n minWidth: 'fit-content',\n}));\n\nconst CustomHeader = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: '12px',\n}));\n\nconst TitleContainer = styled(Box)(() => ({\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n}));\n\nconst StyledTitle = styled(Typography)(({ theme }) => ({\n fontWeight: 400,\n fontSize: '16px',\n lineHeight: '24px',\n color: theme.palette.text.primary,\n}));\n\nexport const TopRiskTile = ({\n title = 'Top risks',\n data = [],\n width = '100%',\n height = '366px',\n repoId,\n entityRef,\n applicationId,\n}: TopRiskTileProps) => {\n const customHeader = (\n <CustomHeader>\n <TitleContainer>\n <StyledTitle>{title}</StyledTitle>\n <ApiiroSmall sx={{ width: 20, height: 20, color: 'text.primary' }} />\n </TitleContainer>\n </CustomHeader>\n );\n // Use API hooks internally\n const connectBackendApi = useApi(apiiroApiRef);\n const { fetch } = useApi(fetchApiRef);\n\n const { topRisksData, topRisksDataError, topRisksDataLoading } =\n useTopRisksData({\n connectApi: connectBackendApi,\n fetchApi: fetch,\n repoId,\n entityRef,\n applicationId,\n });\n\n // Show message when repository key or application key is not provided\n if (!repoId && !applicationId) {\n return (\n <ChartBox\n title={title}\n width={width}\n height={height}\n customHeader={customHeader}\n >\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n minHeight=\"300px\"\n >\n <NotFound message=\"Please configure the apiiro annotation to access the data.\" />\n </Box>\n </ChartBox>\n );\n }\n\n // Transform API data to component data format\n const finalData: TopRiskData[] = topRisksData\n ? topRisksData.map((point: TopRiskDataPoint) => ({\n ruleName: point.ruleName,\n count: point.count,\n severity: point.severity,\n devPhase: point.devPhase,\n }))\n : data;\n\n // Show loading state while data is loading\n if (topRisksDataLoading) {\n return (\n <ChartBox\n title={title}\n width={width}\n height={height}\n customHeader={customHeader}\n >\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n minHeight=\"250px\"\n >\n <LogoSpinner />\n </Box>\n </ChartBox>\n );\n }\n\n // Show error state if there's an error\n if (topRisksDataError) {\n return (\n <ChartBox\n title={title}\n width={width}\n height={height}\n customHeader={customHeader}\n >\n <Box\n display=\"flex\"\n justifyContent=\"center\"\n alignItems=\"center\"\n minHeight=\"300px\"\n >\n <SomethingWentWrong />\n </Box>\n </ChartBox>\n );\n }\n\n // Show message when no data is available\n if (finalData.length === 0) {\n return (\n <ChartBox\n title={title}\n width={width}\n height={height}\n customHeader={customHeader}\n >\n <NotFound />\n </ChartBox>\n );\n }\n\n return (\n <ChartBox\n title={title}\n width={width}\n height={height}\n customHeader={customHeader}\n >\n <RiskListContainer>\n {finalData.map((risk, index) => (\n <RiskItem key={`${risk.ruleName}-${index}`}>\n <RiskContent>\n <RiskLevel level={risk.severity} iconSize=\"large\" />\n <TooltipWrapper>\n <CustomTooltip title={risk.ruleName}>\n <RiskName>{risk.ruleName}</RiskName>\n </CustomTooltip>\n </TooltipWrapper>\n </RiskContent>\n <RiskCount>{risk.count}</RiskCount>\n </RiskItem>\n ))}\n </RiskListContainer>\n </ChartBox>\n );\n};\n\nexport default TopRiskTile;\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,20 +3,40 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
|
3
3
|
import * as _backstage_core_plugin_api from '@backstage/core-plugin-api';
|
|
4
4
|
import { Entity } from '@backstage/catalog-model';
|
|
5
5
|
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* Backstage plugin for Apiiro security insights integration.
|
|
8
|
+
* Provides routes, API clients, and components for displaying security data.
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
7
11
|
declare const apiiroPlugin: _backstage_core_plugin_api.BackstagePlugin<{
|
|
8
12
|
root: _backstage_core_plugin_api.RouteRef<undefined>;
|
|
9
13
|
}, {}, {}>;
|
|
10
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Main page component for the Apiiro plugin.
|
|
16
|
+
* Displays repositories, applications, and risks in a dedicated page.
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
11
19
|
declare const ApiiroPage: () => react_jsx_runtime.JSX.Element;
|
|
12
20
|
|
|
13
|
-
/**
|
|
21
|
+
/**
|
|
22
|
+
* Sidebar navigation item for the Apiiro plugin.
|
|
23
|
+
* Displays the Apiiro icon and links to the Apiiro page.
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
14
26
|
declare const ApiiroSidebar: () => JSX.Element;
|
|
15
27
|
|
|
16
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Entity tab component that displays Apiiro security insights for system and component entities.
|
|
30
|
+
* Shows metrics, risks, and other security-related information for a specific entity.
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
17
33
|
declare const ApiiroTab: () => react_jsx_runtime.JSX.Element;
|
|
18
34
|
|
|
19
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* Widget component that displays Apiiro metrics summary for system and component entities.
|
|
37
|
+
* Can be added to entity overview pages to show key security metrics at a glance.
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
20
40
|
declare const ApiiroWidget: () => react_jsx_runtime.JSX.Element;
|
|
21
41
|
|
|
22
42
|
/**
|
|
@@ -24,5 +44,10 @@ declare const ApiiroWidget: () => react_jsx_runtime.JSX.Element;
|
|
|
24
44
|
* Checks if the entity has the APIIRO project annotation.
|
|
25
45
|
*/
|
|
26
46
|
declare const isApiiroRepoAvailable: (entity: Entity) => boolean;
|
|
47
|
+
/**
|
|
48
|
+
* @public
|
|
49
|
+
* Checks if the entity has the APIIRO application annotation.
|
|
50
|
+
*/
|
|
51
|
+
declare const isApiiroApplicationAvailable: (entity: Entity) => boolean;
|
|
27
52
|
|
|
28
|
-
export { ApiiroPage, ApiiroSidebar, ApiiroTab, ApiiroWidget, apiiroPlugin, isApiiroRepoAvailable };
|
|
53
|
+
export { ApiiroPage, ApiiroSidebar, ApiiroTab, ApiiroWidget, apiiroPlugin, isApiiroApplicationAvailable, isApiiroRepoAvailable };
|
package/dist/index.esm.js
CHANGED
|
@@ -19,6 +19,7 @@ import '@mui/icons-material/Clear';
|
|
|
19
19
|
import '@mui/material/IconButton';
|
|
20
20
|
import './components/common/ChartBox.esm.js';
|
|
21
21
|
import 'react-dom';
|
|
22
|
+
import './components/common/StatusContainer.esm.js';
|
|
22
23
|
import './components/common/logoSpinner.esm.js';
|
|
23
24
|
import '@backstage/core-components';
|
|
24
25
|
import '@mui/material/SvgIcon';
|
|
@@ -26,7 +27,7 @@ import '@mui/material/Chip';
|
|
|
26
27
|
import '@mui/material/Link';
|
|
27
28
|
import '@mui/icons-material/VisibilityOff';
|
|
28
29
|
import '@mui/material/Avatar';
|
|
29
|
-
export { isApiiroRepoAvailable } from './utils/utils.esm.js';
|
|
30
|
+
export { isApiiroApplicationAvailable, isApiiroRepoAvailable } from './utils/utils.esm.js';
|
|
30
31
|
import './components/filters/FilterDropdown.esm.js';
|
|
31
32
|
import './components/filters/RiskInsightFilter.esm.js';
|
|
32
33
|
import './components/CalendarDatePicker.esm.js';
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|