@backstage-community/plugin-apiiro 0.1.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 (223) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +232 -0
  3. package/config.d.ts +30 -0
  4. package/dist/App.esm.js +12 -0
  5. package/dist/App.esm.js.map +1 -0
  6. package/dist/api/index.esm.js +71 -0
  7. package/dist/api/index.esm.js.map +1 -0
  8. package/dist/assets/BulleyeIcon.esm.js +454 -0
  9. package/dist/assets/BulleyeIcon.esm.js.map +1 -0
  10. package/dist/assets/NoResultIcon.esm.js +146 -0
  11. package/dist/assets/NoResultIcon.esm.js.map +1 -0
  12. package/dist/assets/RiskIcon.esm.js +27 -0
  13. package/dist/assets/RiskIcon.esm.js.map +1 -0
  14. package/dist/assets/SettingIcon.esm.js +49 -0
  15. package/dist/assets/SettingIcon.esm.js.map +1 -0
  16. package/dist/assets/apiiroLogo/apiiroLogo.esm.js +21 -0
  17. package/dist/assets/apiiroLogo/apiiroLogo.esm.js.map +1 -0
  18. package/dist/assets/apiiroLogo/apiiroSidebar.esm.js +23 -0
  19. package/dist/assets/apiiroLogo/apiiroSidebar.esm.js.map +1 -0
  20. package/dist/assets/apiiroLogo/apiiroSmall.esm.js +19 -0
  21. package/dist/assets/apiiroLogo/apiiroSmall.esm.js.map +1 -0
  22. package/dist/assets/languageIcons/C.esm.js +7 -0
  23. package/dist/assets/languageIcons/C.esm.js.map +1 -0
  24. package/dist/assets/languageIcons/Cicd.esm.js +7 -0
  25. package/dist/assets/languageIcons/Cicd.esm.js.map +1 -0
  26. package/dist/assets/languageIcons/Clojure.esm.js +7 -0
  27. package/dist/assets/languageIcons/Clojure.esm.js.map +1 -0
  28. package/dist/assets/languageIcons/Cpp.esm.js +7 -0
  29. package/dist/assets/languageIcons/Cpp.esm.js.map +1 -0
  30. package/dist/assets/languageIcons/Csharp.esm.js +7 -0
  31. package/dist/assets/languageIcons/Csharp.esm.js.map +1 -0
  32. package/dist/assets/languageIcons/Dart.esm.js +7 -0
  33. package/dist/assets/languageIcons/Dart.esm.js.map +1 -0
  34. package/dist/assets/languageIcons/Go.esm.js +7 -0
  35. package/dist/assets/languageIcons/Go.esm.js.map +1 -0
  36. package/dist/assets/languageIcons/Groovy.esm.js +7 -0
  37. package/dist/assets/languageIcons/Groovy.esm.js.map +1 -0
  38. package/dist/assets/languageIcons/HTML.esm.js +7 -0
  39. package/dist/assets/languageIcons/HTML.esm.js.map +1 -0
  40. package/dist/assets/languageIcons/HclLanguage.esm.js +7 -0
  41. package/dist/assets/languageIcons/HclLanguage.esm.js.map +1 -0
  42. package/dist/assets/languageIcons/Java.esm.js +7 -0
  43. package/dist/assets/languageIcons/Java.esm.js.map +1 -0
  44. package/dist/assets/languageIcons/Javascript.esm.js +7 -0
  45. package/dist/assets/languageIcons/Javascript.esm.js.map +1 -0
  46. package/dist/assets/languageIcons/Kotlin.esm.js +7 -0
  47. package/dist/assets/languageIcons/Kotlin.esm.js.map +1 -0
  48. package/dist/assets/languageIcons/ObjectiveC.esm.js +7 -0
  49. package/dist/assets/languageIcons/ObjectiveC.esm.js.map +1 -0
  50. package/dist/assets/languageIcons/PHP.esm.js +7 -0
  51. package/dist/assets/languageIcons/PHP.esm.js.map +1 -0
  52. package/dist/assets/languageIcons/Perl.esm.js +13 -0
  53. package/dist/assets/languageIcons/Perl.esm.js.map +1 -0
  54. package/dist/assets/languageIcons/Python.esm.js +7 -0
  55. package/dist/assets/languageIcons/Python.esm.js.map +1 -0
  56. package/dist/assets/languageIcons/Ruby.esm.js +7 -0
  57. package/dist/assets/languageIcons/Ruby.esm.js.map +1 -0
  58. package/dist/assets/languageIcons/Rust.esm.js +7 -0
  59. package/dist/assets/languageIcons/Rust.esm.js.map +1 -0
  60. package/dist/assets/languageIcons/Scala.esm.js +7 -0
  61. package/dist/assets/languageIcons/Scala.esm.js.map +1 -0
  62. package/dist/assets/languageIcons/Swift.esm.js +7 -0
  63. package/dist/assets/languageIcons/Swift.esm.js.map +1 -0
  64. package/dist/assets/languageIcons/Terraform.esm.js +7 -0
  65. package/dist/assets/languageIcons/Terraform.esm.js.map +1 -0
  66. package/dist/assets/languageIcons/Typescript.esm.js +7 -0
  67. package/dist/assets/languageIcons/Typescript.esm.js.map +1 -0
  68. package/dist/assets/languageIcons/Unknown.esm.js +7 -0
  69. package/dist/assets/languageIcons/Unknown.esm.js.map +1 -0
  70. package/dist/assets/languageIcons/VB.esm.js +10 -0
  71. package/dist/assets/languageIcons/VB.esm.js.map +1 -0
  72. package/dist/assets/languageIcons/YAML.esm.js +7 -0
  73. package/dist/assets/languageIcons/YAML.esm.js.map +1 -0
  74. package/dist/assets/providerIcons/Azure.esm.js +7 -0
  75. package/dist/assets/providerIcons/Azure.esm.js.map +1 -0
  76. package/dist/assets/providerIcons/Bitbucket.esm.js +7 -0
  77. package/dist/assets/providerIcons/Bitbucket.esm.js.map +1 -0
  78. package/dist/assets/providerIcons/Gitlab.esm.js +7 -0
  79. package/dist/assets/providerIcons/Gitlab.esm.js.map +1 -0
  80. package/dist/components/ApiiroSidebar.esm.js +10 -0
  81. package/dist/components/ApiiroSidebar.esm.js.map +1 -0
  82. package/dist/components/ApplicationsList/ApplicationsList.esm.js +196 -0
  83. package/dist/components/ApplicationsList/ApplicationsList.esm.js.map +1 -0
  84. package/dist/components/CalendarDatePicker.esm.js +154 -0
  85. package/dist/components/CalendarDatePicker.esm.js.map +1 -0
  86. package/dist/components/CalendarDatePicker.styles.esm.js +198 -0
  87. package/dist/components/CalendarDatePicker.styles.esm.js.map +1 -0
  88. package/dist/components/Chip.esm.js +60 -0
  89. package/dist/components/Chip.esm.js.map +1 -0
  90. package/dist/components/ChipsList.esm.js +207 -0
  91. package/dist/components/ChipsList.esm.js.map +1 -0
  92. package/dist/components/ComponentDisplay.esm.js +42 -0
  93. package/dist/components/ComponentDisplay.esm.js.map +1 -0
  94. package/dist/components/DataGrid/CustomColumnMenu.esm.js +29 -0
  95. package/dist/components/DataGrid/CustomColumnMenu.esm.js.map +1 -0
  96. package/dist/components/DataGrid/CustomPagination.esm.js +113 -0
  97. package/dist/components/DataGrid/CustomPagination.esm.js.map +1 -0
  98. package/dist/components/DataGrid/CustomSearchToolbar.esm.js +117 -0
  99. package/dist/components/DataGrid/CustomSearchToolbar.esm.js.map +1 -0
  100. package/dist/components/DataGrid/DataGrid.esm.js +336 -0
  101. package/dist/components/DataGrid/DataGrid.esm.js.map +1 -0
  102. package/dist/components/DataGrid/PinColumnMenuItem.esm.js +24 -0
  103. package/dist/components/DataGrid/PinColumnMenuItem.esm.js.map +1 -0
  104. package/dist/components/DueDate.esm.js +34 -0
  105. package/dist/components/DueDate.esm.js.map +1 -0
  106. package/dist/components/Header.esm.js +27 -0
  107. package/dist/components/Header.esm.js.map +1 -0
  108. package/dist/components/MainContributors/MainContributors.esm.js +62 -0
  109. package/dist/components/MainContributors/MainContributors.esm.js.map +1 -0
  110. package/dist/components/MetricsGroup/TabMetricsGroup.esm.js +37 -0
  111. package/dist/components/MetricsGroup/TabMetricsGroup.esm.js.map +1 -0
  112. package/dist/components/MetricsGroup/WidgetMetricsGroup.esm.js +36 -0
  113. package/dist/components/MetricsGroup/WidgetMetricsGroup.esm.js.map +1 -0
  114. package/dist/components/RepositoryDisplay/RepositoryDisplay.esm.js +121 -0
  115. package/dist/components/RepositoryDisplay/RepositoryDisplay.esm.js.map +1 -0
  116. package/dist/components/RiskLevel.esm.js +88 -0
  117. package/dist/components/RiskLevel.esm.js.map +1 -0
  118. package/dist/components/RiskStatus.esm.js +58 -0
  119. package/dist/components/RiskStatus.esm.js.map +1 -0
  120. package/dist/components/SimpleTooltip.esm.js +24 -0
  121. package/dist/components/SimpleTooltip.esm.js.map +1 -0
  122. package/dist/components/SourcesDisplay.esm.js +47 -0
  123. package/dist/components/SourcesDisplay.esm.js.map +1 -0
  124. package/dist/components/TagsList/TagsList.esm.js +38 -0
  125. package/dist/components/TagsList/TagsList.esm.js.map +1 -0
  126. package/dist/components/TeamsDisplay.esm.js +47 -0
  127. package/dist/components/TeamsDisplay.esm.js.map +1 -0
  128. package/dist/components/charts/ColumnChart.esm.js +402 -0
  129. package/dist/components/charts/ColumnChart.esm.js.map +1 -0
  130. package/dist/components/charts/GaugeChart.esm.js +249 -0
  131. package/dist/components/charts/GaugeChart.esm.js.map +1 -0
  132. package/dist/components/charts/LineChart.esm.js +328 -0
  133. package/dist/components/charts/LineChart.esm.js.map +1 -0
  134. package/dist/components/charts/PieChart.esm.js +233 -0
  135. package/dist/components/charts/PieChart.esm.js.map +1 -0
  136. package/dist/components/common/ChartBox.esm.js +88 -0
  137. package/dist/components/common/ChartBox.esm.js.map +1 -0
  138. package/dist/components/common/CustomTooltip.esm.js +255 -0
  139. package/dist/components/common/CustomTooltip.esm.js.map +1 -0
  140. package/dist/components/common/ErrorSnackbar.esm.js +39 -0
  141. package/dist/components/common/ErrorSnackbar.esm.js.map +1 -0
  142. package/dist/components/common/NotFound.esm.js +30 -0
  143. package/dist/components/common/NotFound.esm.js.map +1 -0
  144. package/dist/components/common/SomethingWentWrong.esm.js +35 -0
  145. package/dist/components/common/SomethingWentWrong.esm.js.map +1 -0
  146. package/dist/components/common/languageIcons.esm.js +61 -0
  147. package/dist/components/common/languageIcons.esm.js.map +1 -0
  148. package/dist/components/common/logoSpinner.esm.js +28 -0
  149. package/dist/components/common/logoSpinner.esm.js.map +1 -0
  150. package/dist/components/common/scmProviders.esm.js +41 -0
  151. package/dist/components/common/scmProviders.esm.js.map +1 -0
  152. package/dist/components/filters/DiscoveredOnFilter.esm.js +284 -0
  153. package/dist/components/filters/DiscoveredOnFilter.esm.js.map +1 -0
  154. package/dist/components/filters/FilterDropdown.esm.js +325 -0
  155. package/dist/components/filters/FilterDropdown.esm.js.map +1 -0
  156. package/dist/components/filters/FilterDropdownClear.esm.js +45 -0
  157. package/dist/components/filters/FilterDropdownClear.esm.js.map +1 -0
  158. package/dist/components/filters/FilterDropdownList.esm.js +102 -0
  159. package/dist/components/filters/FilterDropdownList.esm.js.map +1 -0
  160. package/dist/components/filters/FilterDropdownSearch.esm.js +65 -0
  161. package/dist/components/filters/FilterDropdownSearch.esm.js.map +1 -0
  162. package/dist/components/filters/RiskInsightFilter.esm.js +579 -0
  163. package/dist/components/filters/RiskInsightFilter.esm.js.map +1 -0
  164. package/dist/components/tiles/MttrVsSLATile.esm.js +170 -0
  165. package/dist/components/tiles/MttrVsSLATile.esm.js.map +1 -0
  166. package/dist/components/tiles/RiskOverTimeTile.esm.js +311 -0
  167. package/dist/components/tiles/RiskOverTimeTile.esm.js.map +1 -0
  168. package/dist/components/tiles/SLAAdherenceTile.esm.js +115 -0
  169. package/dist/components/tiles/SLAAdherenceTile.esm.js.map +1 -0
  170. package/dist/components/tiles/StatusTile.esm.js +235 -0
  171. package/dist/components/tiles/StatusTile.esm.js.map +1 -0
  172. package/dist/components/tiles/TopLanguagesTile.esm.js +234 -0
  173. package/dist/components/tiles/TopLanguagesTile.esm.js.map +1 -0
  174. package/dist/components/tiles/TopRiskTile.esm.js +208 -0
  175. package/dist/components/tiles/TopRiskTile.esm.js.map +1 -0
  176. package/dist/hooks/useUrlFilters.esm.js +102 -0
  177. package/dist/hooks/useUrlFilters.esm.js.map +1 -0
  178. package/dist/index.d.ts +28 -0
  179. package/dist/index.esm.js +42 -0
  180. package/dist/index.esm.js.map +1 -0
  181. package/dist/pages/Repositories/Repositories.esm.js +102 -0
  182. package/dist/pages/Repositories/Repositories.esm.js.map +1 -0
  183. package/dist/pages/Repositories/tableConfig.esm.js +294 -0
  184. package/dist/pages/Repositories/tableConfig.esm.js.map +1 -0
  185. package/dist/pages/Risks/Risks.esm.js +258 -0
  186. package/dist/pages/Risks/Risks.esm.js.map +1 -0
  187. package/dist/pages/Risks/tableConfig.esm.js +305 -0
  188. package/dist/pages/Risks/tableConfig.esm.js.map +1 -0
  189. package/dist/pages/tab/Tab.esm.js +147 -0
  190. package/dist/pages/tab/Tab.esm.js.map +1 -0
  191. package/dist/pages/tab/TabProvider.esm.js +11 -0
  192. package/dist/pages/tab/TabProvider.esm.js.map +1 -0
  193. package/dist/pages/widget/Widget.esm.js +161 -0
  194. package/dist/pages/widget/Widget.esm.js.map +1 -0
  195. package/dist/pages/widget/WidgetProvider.esm.js +12 -0
  196. package/dist/pages/widget/WidgetProvider.esm.js.map +1 -0
  197. package/dist/plugin.esm.js +30 -0
  198. package/dist/plugin.esm.js.map +1 -0
  199. package/dist/queries/filterOptions.queries.esm.js +46 -0
  200. package/dist/queries/filterOptions.queries.esm.js.map +1 -0
  201. package/dist/queries/mttr-statistics.queries.esm.js +61 -0
  202. package/dist/queries/mttr-statistics.queries.esm.js.map +1 -0
  203. package/dist/queries/repository.queries.esm.js +60 -0
  204. package/dist/queries/repository.queries.esm.js.map +1 -0
  205. package/dist/queries/risk-score-over-time.queries.esm.js +61 -0
  206. package/dist/queries/risk-score-over-time.queries.esm.js.map +1 -0
  207. package/dist/queries/risks.queries.esm.js +65 -0
  208. package/dist/queries/risks.queries.esm.js.map +1 -0
  209. package/dist/queries/sla-breach.queries.esm.js +57 -0
  210. package/dist/queries/sla-breach.queries.esm.js.map +1 -0
  211. package/dist/queries/top-risks.queries.esm.js +47 -0
  212. package/dist/queries/top-risks.queries.esm.js.map +1 -0
  213. package/dist/routes.esm.js +8 -0
  214. package/dist/routes.esm.js.map +1 -0
  215. package/dist/theme/themeUtils.esm.js +290 -0
  216. package/dist/theme/themeUtils.esm.js.map +1 -0
  217. package/dist/utils/dateFormatter.esm.js +67 -0
  218. package/dist/utils/dateFormatter.esm.js.map +1 -0
  219. package/dist/utils/numberFormatter.esm.js +21 -0
  220. package/dist/utils/numberFormatter.esm.js.map +1 -0
  221. package/dist/utils/utils.esm.js +27 -0
  222. package/dist/utils/utils.esm.js.map +1 -0
  223. package/package.json +90 -0
@@ -0,0 +1,115 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import Box from '@mui/material/Box';
3
+ import { useTheme } from '@mui/material/styles';
4
+ import { useApi, fetchApiRef } from '@backstage/core-plugin-api';
5
+ import { getSlaColors } from '../../theme/themeUtils.esm.js';
6
+ import { ChartBox } from '../common/ChartBox.esm.js';
7
+ import { ColumnChart } from '../charts/ColumnChart.esm.js';
8
+ import { useSlaBreachData } from '../../queries/sla-breach.queries.esm.js';
9
+ import { apiiroApiRef } from '../../api/index.esm.js';
10
+ import 'react';
11
+ import 'react-dom';
12
+ import { NotFound } from '../common/NotFound.esm.js';
13
+ import { SomethingWentWrong } from '../common/SomethingWentWrong.esm.js';
14
+ import { LogoSpinner } from '../common/logoSpinner.esm.js';
15
+
16
+ const SLAAdherenceTile = ({
17
+ title = "SLA adherence",
18
+ data = [],
19
+ width = "100%",
20
+ height = "366px",
21
+ repoId,
22
+ entityRef
23
+ }) => {
24
+ const theme = useTheme();
25
+ const slaColors = getSlaColors(theme);
26
+ const connectBackendApi = useApi(apiiroApiRef);
27
+ const { fetch } = useApi(fetchApiRef);
28
+ const { slaBreachData, slaBreachDataError, slaBreachDataLoading } = useSlaBreachData({
29
+ connectApi: connectBackendApi,
30
+ fetchApi: fetch,
31
+ repositoryKey: repoId,
32
+ entityRef
33
+ });
34
+ if (slaBreachDataLoading) {
35
+ return /* @__PURE__ */ jsx(ChartBox, { title, width, height, children: /* @__PURE__ */ jsx(
36
+ Box,
37
+ {
38
+ display: "flex",
39
+ justifyContent: "center",
40
+ alignItems: "center",
41
+ minHeight: "250px",
42
+ children: /* @__PURE__ */ jsx(LogoSpinner, {})
43
+ }
44
+ ) });
45
+ }
46
+ if (slaBreachDataError) {
47
+ return /* @__PURE__ */ jsx(ChartBox, { title, width, children: /* @__PURE__ */ jsx(SomethingWentWrong, {}) });
48
+ }
49
+ if (!repoId) {
50
+ return /* @__PURE__ */ jsx(ChartBox, { title, width, height, children: /* @__PURE__ */ jsx(
51
+ Box,
52
+ {
53
+ display: "flex",
54
+ justifyContent: "center",
55
+ alignItems: "center",
56
+ minHeight: "300px",
57
+ children: /* @__PURE__ */ jsx(NotFound, { message: "Please provide the repository details to access the data." })
58
+ }
59
+ ) });
60
+ }
61
+ const finalData = slaBreachData ? slaBreachData.map((point) => ({
62
+ category: point.riskLevel,
63
+ slaBreaches: point.slaBreach,
64
+ slaAdherence: point.slaAdherence,
65
+ dueDateNotSet: point.unsetDueDate
66
+ })) : data;
67
+ if (finalData.length === 0) {
68
+ return /* @__PURE__ */ jsx(ChartBox, { title, width, height, children: /* @__PURE__ */ jsx(NotFound, {}) });
69
+ }
70
+ const hasAllZeroValues = slaBreachData.every(
71
+ (point) => point.slaBreach === 0 && point.slaAdherence === 0 && point.unsetDueDate === 0
72
+ );
73
+ if (hasAllZeroValues) {
74
+ return /* @__PURE__ */ jsx(ChartBox, { title, width, height, children: /* @__PURE__ */ jsx(NotFound, {}) });
75
+ }
76
+ const getChartWidth = () => {
77
+ if (typeof width === "string" && width.includes("%")) {
78
+ return 400;
79
+ }
80
+ return typeof width === "number" ? width - 40 : 400;
81
+ };
82
+ const columnData = finalData.map((item) => ({
83
+ category: item.category,
84
+ values: [
85
+ {
86
+ label: "SLA breaches",
87
+ value: item.slaBreaches,
88
+ color: slaColors.breach
89
+ },
90
+ {
91
+ label: "SLA adherence",
92
+ value: item.slaAdherence,
93
+ color: slaColors.adherence
94
+ },
95
+ {
96
+ label: "Due date not set",
97
+ value: item.dueDateNotSet,
98
+ color: slaColors.notSet
99
+ }
100
+ ]
101
+ }));
102
+ return /* @__PURE__ */ jsx(ChartBox, { title, width, height, children: /* @__PURE__ */ jsx(
103
+ ColumnChart,
104
+ {
105
+ data: columnData,
106
+ width: getChartWidth(),
107
+ height: 300,
108
+ showLegend: true,
109
+ legendPosition: "bottom"
110
+ }
111
+ ) });
112
+ };
113
+
114
+ export { SLAAdherenceTile, SLAAdherenceTile as default };
115
+ //# sourceMappingURL=SLAAdherenceTile.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SLAAdherenceTile.esm.js","sources":["../../../src/components/tiles/SLAAdherenceTile.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 { useTheme } from '@mui/material/styles';\nimport { fetchApiRef, useApi } from '@backstage/core-plugin-api';\nimport { getSlaColors } from '../../theme/themeUtils';\nimport { ChartBox } from '../common/ChartBox';\nimport ColumnChart, { ColumnData } from '../charts/ColumnChart';\nimport { useSlaBreachData } from '../../queries/sla-breach.queries';\nimport { apiiroApiRef } from '../../api';\nimport { SlaBreachDataPoint } from '../../queries/queries.type';\nimport { NotFound, SomethingWentWrong } from '../common';\nimport { LogoSpinner } from '../common/logoSpinner';\n\nexport interface SLAAdherenceData {\n category: string;\n slaBreaches: number;\n slaAdherence: number;\n dueDateNotSet: number;\n}\n\nexport interface SLAAdherenceTileProps {\n title?: string;\n tooltip?: string;\n data?: SLAAdherenceData[];\n width?: string | number;\n height?: string | number;\n repoId?: string;\n entityRef?: string;\n}\n\nexport const SLAAdherenceTile = ({\n title = 'SLA adherence',\n data = [],\n width = '100%',\n height = '366px',\n repoId,\n entityRef,\n}: SLAAdherenceTileProps) => {\n // Use API hooks internally\n const theme = useTheme();\n const slaColors = getSlaColors(theme);\n const connectBackendApi = useApi(apiiroApiRef);\n const { fetch } = useApi(fetchApiRef);\n\n // Always call the hook, but conditionally use the result\n const { slaBreachData, slaBreachDataError, slaBreachDataLoading } =\n useSlaBreachData({\n connectApi: connectBackendApi,\n fetchApi: fetch,\n repositoryKey: repoId,\n entityRef: entityRef,\n });\n\n // Show loading state while data is loading (Query check - loading)\n if (slaBreachDataLoading) {\n return (\n <ChartBox title={title} width={width} height={height}>\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 (Query check - error)\n if (slaBreachDataError) {\n return (\n <ChartBox title={title} width={width}>\n <SomethingWentWrong />\n </ChartBox>\n );\n }\n\n // Show message when no repository key is provided\n if (!repoId) {\n return (\n <ChartBox title={title} width={width} height={height}>\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 // Transform API data to component data format\n const finalData: SLAAdherenceData[] = slaBreachData\n ? slaBreachData.map((point: SlaBreachDataPoint) => ({\n category: point.riskLevel,\n slaBreaches: point.slaBreach,\n slaAdherence: point.slaAdherence,\n dueDateNotSet: point.unsetDueDate,\n }))\n : data;\n\n // Total data length check\n if (finalData.length === 0) {\n return (\n <ChartBox title={title} width={width} height={height}>\n <NotFound />\n </ChartBox>\n );\n }\n\n // Check if all values are zero (slaBreach, slaAdherence, and unsetDueDate)\n const hasAllZeroValues = slaBreachData!.every(\n (point: SlaBreachDataPoint) =>\n point.slaBreach === 0 &&\n point.slaAdherence === 0 &&\n point.unsetDueDate === 0,\n );\n\n // If all zero, send NotFound\n if (hasAllZeroValues) {\n return (\n <ChartBox title={title} width={width} height={height}>\n <NotFound />\n </ChartBox>\n );\n }\n\n // Calculate chart width based on container\n const getChartWidth = () => {\n if (typeof width === 'string' && width.includes('%')) {\n // For percentage widths, assume a reasonable container width\n return 400; // This will be responsive within the container\n }\n return typeof width === 'number' ? width - 40 : 400; // Leave some padding\n };\n\n // Transform data for ColumnChart\n const columnData: ColumnData[] = finalData.map(item => ({\n category: item.category,\n values: [\n {\n label: 'SLA breaches',\n value: item.slaBreaches,\n color: slaColors.breach,\n },\n {\n label: 'SLA adherence',\n value: item.slaAdherence,\n color: slaColors.adherence,\n },\n {\n label: 'Due date not set',\n value: item.dueDateNotSet,\n color: slaColors.notSet,\n },\n ],\n }));\n\n return (\n <ChartBox title={title} width={width} height={height}>\n <ColumnChart\n data={columnData}\n width={getChartWidth()}\n height={300}\n showLegend\n legendPosition=\"bottom\"\n />\n </ChartBox>\n );\n};\n\nexport default SLAAdherenceTile;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,235 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import Box from '@mui/material/Box';
3
+ import Typography from '@mui/material/Typography';
4
+ import { styled } from '@mui/material/styles';
5
+ import { getActivityStatusColors, getLogoContainerColors } from '../../theme/themeUtils.esm.js';
6
+ import { Link } from 'react-router-dom';
7
+ import { ApiiroLogo } from '../../assets/apiiroLogo/apiiroLogo.esm.js';
8
+ import '@mui/material/SvgIcon';
9
+ import { formatNumberWithSuffix } from '../../utils/numberFormatter.esm.js';
10
+ import { formatActivityTooltip, getDevelopmentDuration } from '../../utils/dateFormatter.esm.js';
11
+ import '@mui/icons-material';
12
+ import 'react-icons/vsc';
13
+ import 'react-icons/si';
14
+ import { APIIRO_DEFAULT_BASE_URL } from '@backstage-community/plugin-apiiro-common';
15
+ import '../common/ChartBox.esm.js';
16
+ import { CustomTooltip } from '../common/CustomTooltip.esm.js';
17
+ import { NotFound } from '../common/NotFound.esm.js';
18
+ import { scmProviderIcons, generateRepoURL } from '../common/scmProviders.esm.js';
19
+ import { SettingIcon } from '../../assets/SettingIcon.esm.js';
20
+
21
+ const ThemedIcon = styled("span")(({ theme }) => ({
22
+ display: "inline-flex",
23
+ "& svg": {
24
+ color: theme.palette.text.primary,
25
+ flexShrink: 0
26
+ },
27
+ "&:hover svg": {
28
+ color: theme.palette.primary.main
29
+ }
30
+ }));
31
+ const StatusIndicator = styled("span")(
32
+ ({ theme, isActive }) => {
33
+ const activityColors = getActivityStatusColors(theme);
34
+ return {
35
+ display: "inline-block",
36
+ width: 8,
37
+ height: 8,
38
+ borderRadius: "50%",
39
+ backgroundColor: isActive ? activityColors.active : activityColors.inactive,
40
+ marginRight: 8
41
+ };
42
+ }
43
+ );
44
+ const StatusBox = styled(Box)(({ theme, width, height }) => ({
45
+ border: `1px solid ${theme.palette.divider}`,
46
+ borderRadius: "12px",
47
+ backgroundColor: theme.palette.background.paper,
48
+ boxShadow: theme.shadows[1],
49
+ width: width || "fit-content",
50
+ height: height || "auto",
51
+ margin: width === "100%" ? "0" : "0 auto",
52
+ maxWidth: "100%",
53
+ display: "flex",
54
+ flexDirection: "column",
55
+ boxSizing: "border-box"
56
+ }));
57
+ const StatusContent = styled(Box)(() => ({
58
+ display: "flex",
59
+ flexDirection: "column",
60
+ alignItems: "flex-start",
61
+ gap: "12px",
62
+ padding: "16px"
63
+ }));
64
+ const StatusRow = styled(Box)(() => ({
65
+ display: "flex",
66
+ alignItems: "center",
67
+ gap: "8px"
68
+ }));
69
+ const StatusLabel = styled(Typography)(({ theme }) => ({
70
+ fontSize: "16px",
71
+ fontWeight: 400,
72
+ color: theme.palette.text.secondary
73
+ }));
74
+ const StatusValue = styled(Typography)(({ theme }) => ({
75
+ fontSize: "16px",
76
+ fontWeight: 400,
77
+ color: theme.palette.text.primary
78
+ }));
79
+ const BranchLink = styled(Link)(({ theme }) => ({
80
+ display: "flex",
81
+ alignItems: "center",
82
+ gap: "8px",
83
+ fontSize: "16px",
84
+ fontWeight: 400,
85
+ color: theme.palette.info.main,
86
+ textDecoration: "underline",
87
+ cursor: "pointer"
88
+ }));
89
+ const ActionLinks = styled(Box)(() => ({
90
+ display: "flex",
91
+ gap: "16px",
92
+ marginTop: "8px"
93
+ }));
94
+ const ActionLink = styled(Link)(({ theme }) => ({
95
+ fontSize: "16px",
96
+ fontWeight: 400,
97
+ color: theme.palette.info.main,
98
+ textDecoration: "none",
99
+ cursor: "pointer"
100
+ }));
101
+ const CustomHeader = styled(Box)(() => ({
102
+ display: "flex",
103
+ alignItems: "center",
104
+ justifyContent: "space-between",
105
+ marginBottom: "12px"
106
+ }));
107
+ const TitleContainer = styled(Box)(() => ({
108
+ display: "flex",
109
+ alignItems: "center",
110
+ gap: "8px",
111
+ paddingLeft: "16px",
112
+ paddingTop: "16px"
113
+ }));
114
+ const StyledTitle = styled(Typography)(({ theme }) => ({
115
+ fontWeight: 400,
116
+ fontSize: "16px",
117
+ lineHeight: "24px",
118
+ color: theme.palette.text.primary
119
+ }));
120
+ const LogoContainer = styled(Box)(({ theme }) => {
121
+ const logoColors = getLogoContainerColors(theme);
122
+ return {
123
+ display: "flex",
124
+ flexDirection: "row",
125
+ justifyContent: "center",
126
+ alignItems: "center",
127
+ padding: "12px 15px",
128
+ gap: "10px",
129
+ width: "109px",
130
+ height: "40px",
131
+ background: logoColors.background,
132
+ borderRadius: "10px",
133
+ "& svg": {
134
+ width: "79px",
135
+ height: "22px",
136
+ "& path": {
137
+ fill: logoColors.logoFill
138
+ }
139
+ }
140
+ };
141
+ });
142
+ const CustomHeaderData = ({ title }) => /* @__PURE__ */ jsxs(CustomHeader, { children: [
143
+ /* @__PURE__ */ jsx(TitleContainer, { children: /* @__PURE__ */ jsx(StyledTitle, { children: title }) }),
144
+ /* @__PURE__ */ jsx(LogoContainer, { children: /* @__PURE__ */ jsx(ApiiroLogo, {}) })
145
+ ] });
146
+ const StatusTile = ({
147
+ title = "Status",
148
+ width = "100%",
149
+ height = "auto",
150
+ repository,
151
+ detailViewLink = null,
152
+ allowViewChart = true
153
+ }) => {
154
+ if (Object.keys(repository).length === 0) {
155
+ return /* @__PURE__ */ jsxs(StatusBox, { width, height, alignContent: "flex-start", children: [
156
+ /* @__PURE__ */ jsx(CustomHeaderData, { title: "" }),
157
+ /* @__PURE__ */ jsx(NotFound, { message: "Results for this repository are either unavailable on Apiiro or cannot be accessed." })
158
+ ] });
159
+ }
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,
168
+ {
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
+ ] })
183
+ }
184
+ ),
185
+ /* @__PURE__ */ jsx(
186
+ CustomTooltip,
187
+ {
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
+ ] })
194
+ }
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
+ ] })
230
+ ] })
231
+ ] });
232
+ };
233
+
234
+ export { StatusBox, StatusTile, StatusTile as default };
235
+ //# sourceMappingURL=StatusTile.esm.js.map
@@ -0,0 +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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"}
@@ -0,0 +1,234 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { styled, useTheme } from '@mui/material/styles';
3
+ import { getBlueColorVariants, getOtherColor } from '../../theme/themeUtils.esm.js';
4
+ import Box from '@mui/material/Box';
5
+ import Typography from '@mui/material/Typography';
6
+ import List from '@mui/material/List';
7
+ import ListItem from '@mui/material/ListItem';
8
+ import { languageIconMap } from '../common/languageIcons.esm.js';
9
+ import { ChartBox } from '../common/ChartBox.esm.js';
10
+ import { CustomTooltip } from '../common/CustomTooltip.esm.js';
11
+ import { NotFound } from '../common/NotFound.esm.js';
12
+ import { useMemo, useState, useEffect, useCallback } from 'react';
13
+ import { PieChart } from '../charts/PieChart.esm.js';
14
+ import '@mui/material/SvgIcon';
15
+ import { ApiiroSmall } from '../../assets/apiiroLogo/apiiroSmall.esm.js';
16
+ import Divider from '@mui/material/Divider';
17
+
18
+ const LegendContainer = styled(Box)(() => ({
19
+ display: "flex",
20
+ flexWrap: "wrap",
21
+ justifyContent: "center",
22
+ gap: "6px"
23
+ }));
24
+ const LegendItem = styled(Box)(({ theme }) => ({
25
+ display: "flex",
26
+ alignItems: "center",
27
+ gap: "6px",
28
+ fontSize: "12px",
29
+ color: theme.palette.text.secondary
30
+ }));
31
+ const LegendColor = styled("div")(({ color }) => ({
32
+ width: "8px",
33
+ height: "8px",
34
+ borderRadius: "50%",
35
+ backgroundColor: color,
36
+ flexShrink: 0
37
+ }));
38
+ const CustomHeader = styled(Box)(() => ({
39
+ display: "flex",
40
+ alignItems: "center",
41
+ justifyContent: "space-between",
42
+ marginBottom: "12px"
43
+ }));
44
+ const TitleContainer = styled(Box)(() => ({
45
+ display: "flex",
46
+ alignItems: "center",
47
+ gap: "8px"
48
+ }));
49
+ const StyledTitle = styled(Typography)(({ theme }) => ({
50
+ fontWeight: 400,
51
+ fontSize: "16px",
52
+ lineHeight: "24px",
53
+ color: theme.palette.text.primary
54
+ }));
55
+ const mapLanguagePercentagesToPieData = (languagePercentages) => Object.entries(languagePercentages).map(([language, value], index) => {
56
+ const numericValue = typeof value === "number" && !isNaN(value) ? value : 0;
57
+ return {
58
+ id: `${language.toLowerCase().replace(/[^a-z0-9]+/g, "-")}-${index}`,
59
+ label: language,
60
+ value: numericValue
61
+ };
62
+ }).filter((item) => item.value > 0);
63
+ const TopLanguagesTile = ({
64
+ title = "Top languages",
65
+ data = {},
66
+ width = "100%"
67
+ }) => {
68
+ const theme = useTheme();
69
+ const blueColorVariants = getBlueColorVariants(theme);
70
+ const otherColor = getOtherColor(theme);
71
+ const chartData = useMemo(() => {
72
+ if (data && Object.keys(data).length > 0) {
73
+ const mappedData = mapLanguagePercentagesToPieData(data);
74
+ if (mappedData.length > 0) {
75
+ return mappedData;
76
+ }
77
+ }
78
+ return [];
79
+ }, [data]);
80
+ const [processedData, setProcessedData] = useState(chartData);
81
+ useEffect(() => {
82
+ setProcessedData(chartData);
83
+ }, [chartData]);
84
+ const customHeader = /* @__PURE__ */ jsx(CustomHeader, { children: /* @__PURE__ */ jsxs(TitleContainer, { children: [
85
+ /* @__PURE__ */ jsx(StyledTitle, { children: title }),
86
+ /* @__PURE__ */ jsx(ApiiroSmall, { sx: { width: 20, height: 20, color: "text.primary" } })
87
+ ] }) });
88
+ const generateColor = useCallback(
89
+ (index, itemId) => {
90
+ if (itemId === "other") {
91
+ return otherColor;
92
+ }
93
+ if (index < blueColorVariants.length) {
94
+ return blueColorVariants[index];
95
+ }
96
+ return otherColor;
97
+ },
98
+ [blueColorVariants, otherColor]
99
+ );
100
+ const legend = /* @__PURE__ */ jsxs(LegendContainer, { children: [
101
+ processedData.slice(0, 5).map((item, index) => /* @__PURE__ */ jsxs(LegendItem, { children: [
102
+ /* @__PURE__ */ jsx(LegendColor, { color: item.color || generateColor(index, item.id) }),
103
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", children: item.label })
104
+ ] }, item.id)),
105
+ processedData.length > 5 && /* @__PURE__ */ jsx(
106
+ CustomTooltip,
107
+ {
108
+ title: /* @__PURE__ */ jsxs(List, { dense: true, disablePadding: true, children: [
109
+ processedData.slice(5).map((item) => {
110
+ const LanguageIcon = languageIconMap[item.label] || languageIconMap["Unknown"];
111
+ return /* @__PURE__ */ jsx(
112
+ ListItem,
113
+ {
114
+ disableGutters: true,
115
+ disablePadding: true,
116
+ sx: { py: 0.5, px: 1, minWidth: 200 },
117
+ children: /* @__PURE__ */ jsxs(
118
+ Box,
119
+ {
120
+ sx: {
121
+ display: "flex",
122
+ alignItems: "center",
123
+ width: "100%",
124
+ justifyContent: "space-between"
125
+ },
126
+ children: [
127
+ /* @__PURE__ */ jsxs(
128
+ Box,
129
+ {
130
+ sx: { display: "flex", alignItems: "center", gap: 1 },
131
+ children: [
132
+ /* @__PURE__ */ jsx(
133
+ Box,
134
+ {
135
+ sx: {
136
+ width: 24,
137
+ height: 24,
138
+ display: "flex",
139
+ alignItems: "center",
140
+ justifyContent: "center"
141
+ },
142
+ children: /* @__PURE__ */ jsx(LanguageIcon, {})
143
+ }
144
+ ),
145
+ /* @__PURE__ */ jsx(
146
+ Typography,
147
+ {
148
+ variant: "body2",
149
+ sx: { fontSize: "12px", color: "text.primary" },
150
+ children: item.label
151
+ }
152
+ )
153
+ ]
154
+ }
155
+ ),
156
+ /* @__PURE__ */ jsxs(
157
+ Typography,
158
+ {
159
+ variant: "body2",
160
+ sx: {
161
+ fontSize: "12px",
162
+ color: "text.primary",
163
+ fontWeight: 400
164
+ },
165
+ children: [
166
+ Math.round(item.value),
167
+ "%"
168
+ ]
169
+ }
170
+ )
171
+ ]
172
+ }
173
+ )
174
+ },
175
+ item.id
176
+ );
177
+ }),
178
+ /* @__PURE__ */ jsx(Divider, {}),
179
+ /* @__PURE__ */ jsx(
180
+ Typography,
181
+ {
182
+ variant: "body2",
183
+ sx: { py: 1, fontSize: "12px", color: "text.primary" },
184
+ children: "Less then 0.1%"
185
+ }
186
+ )
187
+ ] }),
188
+ placement: "top",
189
+ children: /* @__PURE__ */ jsxs(LegendItem, { children: [
190
+ /* @__PURE__ */ jsx(LegendColor, { color: generateColor(-1, "other") }),
191
+ /* @__PURE__ */ jsx(Typography, { variant: "caption", children: "Other" })
192
+ ] })
193
+ }
194
+ )
195
+ ] });
196
+ if (Object.keys(data).length === 0 || processedData.length === 0) {
197
+ return /* @__PURE__ */ jsx(ChartBox, { title, width, customHeader, children: /* @__PURE__ */ jsx(NotFound, {}) });
198
+ }
199
+ return /* @__PURE__ */ jsx(
200
+ ChartBox,
201
+ {
202
+ title,
203
+ width,
204
+ footer: legend,
205
+ customHeader,
206
+ children: /* @__PURE__ */ jsx(
207
+ "div",
208
+ {
209
+ style: {
210
+ display: "flex",
211
+ justifyContent: "center",
212
+ alignItems: "center",
213
+ width: "100%",
214
+ flex: 1,
215
+ minHeight: 0
216
+ },
217
+ children: /* @__PURE__ */ jsx(
218
+ PieChart,
219
+ {
220
+ data: chartData,
221
+ width: 310,
222
+ height: 310,
223
+ generateColor,
224
+ onDataProcessed: setProcessedData
225
+ }
226
+ )
227
+ }
228
+ )
229
+ }
230
+ );
231
+ };
232
+
233
+ export { TopLanguagesTile, TopLanguagesTile as default };
234
+ //# sourceMappingURL=TopLanguagesTile.esm.js.map