@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.
Files changed (88) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +91 -12
  3. package/config.d.ts +14 -0
  4. package/dist/App.esm.js +96 -4
  5. package/dist/App.esm.js.map +1 -1
  6. package/dist/api/index.esm.js +6 -0
  7. package/dist/api/index.esm.js.map +1 -1
  8. package/dist/assets/SettingIcon.esm.js +1 -0
  9. package/dist/assets/SettingIcon.esm.js.map +1 -1
  10. package/dist/components/ApiiroSidebar.esm.js.map +1 -1
  11. package/dist/components/CalendarDatePicker.esm.js.map +1 -1
  12. package/dist/components/DataGrid/DataGrid.esm.js +1 -0
  13. package/dist/components/DataGrid/DataGrid.esm.js.map +1 -1
  14. package/dist/components/MetricsGroup/TabMetricsGroup.esm.js +28 -4
  15. package/dist/components/MetricsGroup/TabMetricsGroup.esm.js.map +1 -1
  16. package/dist/components/MetricsGroup/WidgetMetricsGroup.esm.js +30 -7
  17. package/dist/components/MetricsGroup/WidgetMetricsGroup.esm.js.map +1 -1
  18. package/dist/components/RiskLevel.esm.js +1 -0
  19. package/dist/components/RiskLevel.esm.js.map +1 -1
  20. package/dist/components/charts/GaugeChart.esm.js +8 -6
  21. package/dist/components/charts/GaugeChart.esm.js.map +1 -1
  22. package/dist/components/common/StatusContainer.esm.js +123 -0
  23. package/dist/components/common/StatusContainer.esm.js.map +1 -0
  24. package/dist/components/filters/DiscoveredOnFilter.esm.js +1 -1
  25. package/dist/components/filters/DiscoveredOnFilter.esm.js.map +1 -1
  26. package/dist/components/tiles/MttrVsSLATile.esm.js +31 -14
  27. package/dist/components/tiles/MttrVsSLATile.esm.js.map +1 -1
  28. package/dist/components/tiles/RiskOverTimeTile.esm.js +15 -12
  29. package/dist/components/tiles/RiskOverTimeTile.esm.js.map +1 -1
  30. package/dist/components/tiles/SLAAdherenceTile.esm.js +15 -12
  31. package/dist/components/tiles/SLAAdherenceTile.esm.js.map +1 -1
  32. package/dist/components/tiles/StatusTile.esm.js +98 -66
  33. package/dist/components/tiles/StatusTile.esm.js.map +1 -1
  34. package/dist/components/tiles/TopLanguagesTile.esm.js +1 -0
  35. package/dist/components/tiles/TopLanguagesTile.esm.js.map +1 -1
  36. package/dist/components/tiles/TopRiskTile.esm.js +19 -16
  37. package/dist/components/tiles/TopRiskTile.esm.js.map +1 -1
  38. package/dist/index.d.ts +31 -6
  39. package/dist/index.esm.js +2 -1
  40. package/dist/index.esm.js.map +1 -1
  41. package/dist/pages/Applications/Applications.esm.js +104 -0
  42. package/dist/pages/Applications/Applications.esm.js.map +1 -0
  43. package/dist/pages/Applications/tableConfig.esm.js +147 -0
  44. package/dist/pages/Applications/tableConfig.esm.js.map +1 -0
  45. package/dist/pages/Repositories/Repositories.esm.js +26 -26
  46. package/dist/pages/Repositories/Repositories.esm.js.map +1 -1
  47. package/dist/pages/Repositories/tableConfig.esm.js +3 -2
  48. package/dist/pages/Repositories/tableConfig.esm.js.map +1 -1
  49. package/dist/pages/Risks/Risks.esm.js +9 -3
  50. package/dist/pages/Risks/Risks.esm.js.map +1 -1
  51. package/dist/pages/Risks/tableConfig.esm.js +25 -11
  52. package/dist/pages/Risks/tableConfig.esm.js.map +1 -1
  53. package/dist/pages/tab/ComponentTab.esm.js +72 -0
  54. package/dist/pages/tab/ComponentTab.esm.js.map +1 -0
  55. package/dist/pages/tab/SystemTab.esm.js +159 -0
  56. package/dist/pages/tab/SystemTab.esm.js.map +1 -0
  57. package/dist/pages/tab/TabProvider.esm.js +9 -3
  58. package/dist/pages/tab/TabProvider.esm.js.map +1 -1
  59. package/dist/pages/widget/ComponentWidget.esm.js +67 -0
  60. package/dist/pages/widget/ComponentWidget.esm.js.map +1 -0
  61. package/dist/pages/widget/SystemWidget.esm.js +81 -0
  62. package/dist/pages/widget/SystemWidget.esm.js.map +1 -0
  63. package/dist/pages/widget/WidgetProvider.esm.js +9 -3
  64. package/dist/pages/widget/WidgetProvider.esm.js.map +1 -1
  65. package/dist/plugin.esm.js.map +1 -1
  66. package/dist/queries/application.queries.esm.js +64 -0
  67. package/dist/queries/application.queries.esm.js.map +1 -0
  68. package/dist/queries/mttr-statistics.queries.esm.js +19 -12
  69. package/dist/queries/mttr-statistics.queries.esm.js.map +1 -1
  70. package/dist/queries/repository.queries.esm.js +19 -8
  71. package/dist/queries/repository.queries.esm.js.map +1 -1
  72. package/dist/queries/risk-score-over-time.queries.esm.js +19 -12
  73. package/dist/queries/risk-score-over-time.queries.esm.js.map +1 -1
  74. package/dist/queries/risks.queries.esm.js +19 -7
  75. package/dist/queries/risks.queries.esm.js.map +1 -1
  76. package/dist/queries/sla-breach.queries.esm.js +22 -11
  77. package/dist/queries/sla-breach.queries.esm.js.map +1 -1
  78. package/dist/queries/top-risks.queries.esm.js +19 -7
  79. package/dist/queries/top-risks.queries.esm.js.map +1 -1
  80. package/dist/theme/themeUtils.esm.js +5 -2
  81. package/dist/theme/themeUtils.esm.js.map +1 -1
  82. package/dist/utils/utils.esm.js +3 -2
  83. package/dist/utils/utils.esm.js.map +1 -1
  84. package/package.json +12 -12
  85. package/dist/pages/tab/Tab.esm.js +0 -147
  86. package/dist/pages/tab/Tab.esm.js.map +0 -1
  87. package/dist/pages/widget/Widget.esm.js +0 -161
  88. 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
- if (Object.keys(repository).length === 0) {
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(NotFound, { message: "Results for this repository are either unavailable on Apiiro or cannot be accessed." })
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 ProviderIconComponent = scmProviderIcons[repository.provider];
161
- const apiiroRepoUrl = `${APIIRO_DEFAULT_BASE_URL}/profiles/repositories/${repository.key}`;
162
- const settingsUrl = `${apiiroRepoUrl}/profile/${repository.scmRepositoryKey}/multi-branch`;
163
- return /* @__PURE__ */ jsxs(StatusBox, { width, height, alignContent: "flex-start", children: [
164
- /* @__PURE__ */ jsx(CustomHeaderData, { title }),
165
- /* @__PURE__ */ jsxs(StatusContent, { children: [
166
- repository?.lastActivity && repository?.activeSince && /* @__PURE__ */ jsx(
167
- CustomTooltip,
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
- title: formatActivityTooltip(
170
- repository.lastActivity,
171
- repository.activeSince
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
- CustomTooltip,
240
+ Link,
187
241
  {
188
- title: "A weighted value based on the number of risks at each severity level.",
189
- placement: "top",
190
- children: /* @__PURE__ */ jsxs(StatusRow, { children: [
191
- /* @__PURE__ */ jsx(StatusLabel, { children: "Risk score:" }),
192
- /* @__PURE__ */ jsx(StatusValue, { children: formatNumberWithSuffix(repository.riskScore) })
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
- /* @__PURE__ */ jsxs(StatusRow, { children: [
197
- ProviderIconComponent && /* @__PURE__ */ jsx(ThemedIcon, { children: /* @__PURE__ */ jsx(ProviderIconComponent, {}) }),
198
- /* @__PURE__ */ jsx(
199
- BranchLink,
200
- {
201
- to: generateRepoURL(repository) || "",
202
- target: "_blank",
203
- rel: "noopener noreferrer",
204
- children: `Analyzing ${repository.branchName} branch`
205
- }
206
- ),
207
- /* @__PURE__ */ jsx(
208
- Link,
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":"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"}
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
- const finalData = topRisksData ? topRisksData.map((point) => ({
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: "250px",
129
- children: /* @__PURE__ */ jsx(LogoSpinner, {})
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
- if (topRisksDataError) {
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: "300px",
150
- children: /* @__PURE__ */ jsx(SomethingWentWrong, {})
152
+ minHeight: "250px",
153
+ children: /* @__PURE__ */ jsx(LogoSpinner, {})
151
154
  }
152
155
  )
153
156
  }
154
157
  );
155
158
  }
156
- if (!repoId) {
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(NotFound, { message: "Please provide the repository details to access the data." })
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
- /** @public */
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
- /** @public */
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
- /** @public */
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
- /** @public */
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
- /** @public */
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';
@@ -1 +1 @@
1
- {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.esm.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}