@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,47 @@
1
+ import { useQuery } from '@tanstack/react-query';
2
+ import { post } from '../api/index.esm.js';
3
+
4
+ const getTopRisksData = async ({
5
+ fetchApi,
6
+ signal,
7
+ connectApi,
8
+ repoId,
9
+ entityRef
10
+ }) => {
11
+ const url = await connectApi.discoveryApi.getBaseUrl("apiiro");
12
+ const body = { repositoryKey: repoId, ...entityRef && { entityRef } };
13
+ return await post(fetchApi, `${url}/top-risks`, {
14
+ signal,
15
+ body
16
+ });
17
+ };
18
+ function useTopRisksData({
19
+ fetchApi,
20
+ connectApi,
21
+ repoId,
22
+ entityRef
23
+ }) {
24
+ const {
25
+ data: topRisksData,
26
+ error: topRisksDataError,
27
+ isLoading: topRisksDataLoading
28
+ } = useQuery({
29
+ queryKey: ["GET_TOP_RISKS" /* GET_TOP_RISKS */, repoId, entityRef],
30
+ queryFn: ({ signal }) => repoId ? getTopRisksData({
31
+ fetchApi,
32
+ signal,
33
+ connectApi,
34
+ repoId,
35
+ entityRef
36
+ }) : Promise.resolve([]),
37
+ enabled: !!repoId
38
+ });
39
+ return {
40
+ topRisksData,
41
+ topRisksDataError,
42
+ topRisksDataLoading
43
+ };
44
+ }
45
+
46
+ export { useTopRisksData };
47
+ //# sourceMappingURL=top-risks.queries.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top-risks.queries.esm.js","sources":["../../src/queries/top-risks.queries.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { useQuery } from '@tanstack/react-query';\nimport { post } from '../api';\nimport { Query, TopRiskSuccessResponseData } from './queries.type';\n\nexport enum TOP_RISKS_QUERY_KEY {\n GET_TOP_RISKS = 'GET_TOP_RISKS',\n}\n\nconst getTopRisksData = async ({\n fetchApi,\n signal,\n connectApi,\n repoId,\n entityRef,\n}: Query & { repoId: string; entityRef?: string }) => {\n const url = await connectApi.discoveryApi.getBaseUrl('apiiro');\n const body = { repositoryKey: repoId, ...(entityRef && { entityRef }) };\n return await post<TopRiskSuccessResponseData>(fetchApi, `${url}/top-risks`, {\n signal,\n body,\n });\n};\n\nexport function useTopRisksData({\n fetchApi,\n connectApi,\n repoId,\n entityRef,\n}: Omit<Query, 'signal'> & { repoId?: string; entityRef?: string }) {\n const {\n data: topRisksData,\n error: topRisksDataError,\n isLoading: topRisksDataLoading,\n } = useQuery({\n queryKey: [TOP_RISKS_QUERY_KEY.GET_TOP_RISKS, repoId, entityRef],\n queryFn: ({ signal }) =>\n repoId\n ? getTopRisksData({\n fetchApi,\n signal,\n connectApi,\n repoId,\n entityRef,\n })\n : Promise.resolve([]),\n enabled: !!repoId,\n });\n\n return {\n topRisksData,\n topRisksDataError,\n topRisksDataLoading,\n };\n}\n"],"names":[],"mappings":";;;AAuBA,MAAM,kBAAkB,OAAO;AAAA,EAC7B,QAAA;AAAA,EACA,MAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,KAAsD;AACpD,EAAA,MAAM,GAAA,GAAM,MAAM,UAAA,CAAW,YAAA,CAAa,WAAW,QAAQ,CAAA;AAC7D,EAAA,MAAM,IAAA,GAAO,EAAE,aAAA,EAAe,MAAA,EAAQ,GAAI,SAAA,IAAa,EAAE,WAAU,EAAG;AACtE,EAAA,OAAO,MAAM,IAAA,CAAiC,QAAA,EAAU,CAAA,EAAG,GAAG,CAAA,UAAA,CAAA,EAAc;AAAA,IAC1E,MAAA;AAAA,IACA;AAAA,GACD,CAAA;AACH,CAAA;AAEO,SAAS,eAAA,CAAgB;AAAA,EAC9B,QAAA;AAAA,EACA,UAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAoE;AAClE,EAAA,MAAM;AAAA,IACJ,IAAA,EAAM,YAAA;AAAA,IACN,KAAA,EAAO,iBAAA;AAAA,IACP,SAAA,EAAW;AAAA,MACT,QAAA,CAAS;AAAA,IACX,QAAA,EAAU,CAAC,eAAA,sBAAmC,MAAA,EAAQ,SAAS,CAAA;AAAA,IAC/D,SAAS,CAAC,EAAE,MAAA,EAAO,KACjB,SACI,eAAA,CAAgB;AAAA,MACd,QAAA;AAAA,MACA,MAAA;AAAA,MACA,UAAA;AAAA,MACA,MAAA;AAAA,MACA;AAAA,KACD,CAAA,GACD,OAAA,CAAQ,OAAA,CAAQ,EAAE,CAAA;AAAA,IACxB,OAAA,EAAS,CAAC,CAAC;AAAA,GACZ,CAAA;AAED,EAAA,OAAO;AAAA,IACL,YAAA;AAAA,IACA,iBAAA;AAAA,IACA;AAAA,GACF;AACF;;;;"}
@@ -0,0 +1,8 @@
1
+ import { createRouteRef } from '@backstage/core-plugin-api';
2
+
3
+ const rootRouteRef = createRouteRef({
4
+ id: "apiiro-plugin"
5
+ });
6
+
7
+ export { rootRouteRef };
8
+ //# sourceMappingURL=routes.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.esm.js","sources":["../src/routes.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { createRouteRef } from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'apiiro-plugin',\n});\n"],"names":[],"mappings":";;AAiBO,MAAM,eAAe,cAAA,CAAe;AAAA,EACzC,EAAA,EAAI;AACN,CAAC;;;;"}
@@ -0,0 +1,290 @@
1
+ const lightPalette = {
2
+ risk: {
3
+ critical: "#bc0e4d",
4
+ high: "#f2405e",
5
+ medium: "#ffa70f",
6
+ low: "#ffe366"
7
+ },
8
+ riskStatus: {
9
+ open: "#f2405e",
10
+ accepted: "#00d0b3"
11
+ },
12
+ trend: {
13
+ positive: { line: "#f44336", background: "#fde7eb", text: "#9d0b23" },
14
+ negative: { line: "#2eefd9", background: "#d9fcf8", text: "#09776a" },
15
+ neutral: { line: "#769cd6", background: "#ebf1fa", text: "#012b70" }
16
+ },
17
+ activity: {
18
+ active: "#11e4cb"
19
+ },
20
+ businessImpact: {
21
+ high: "#d32f2f",
22
+ medium: "#f57c00",
23
+ low: "#388e3c"
24
+ },
25
+ gauge: {
26
+ success: "#2eefd9",
27
+ warning: "#f2405e"
28
+ },
29
+ sla: {
30
+ breach: "#f2405e",
31
+ adherence: "#a8c5ff"
32
+ },
33
+ blueVariants: [
34
+ "#012b70",
35
+ "#2e5a9e",
36
+ "#769cd6",
37
+ "#9db9e2",
38
+ "#b3c9e9",
39
+ "#c5d7ef",
40
+ "#d5e2f4",
41
+ "#e1eaf8",
42
+ "#ebf1fa",
43
+ "#f2f6fd",
44
+ "#f7fafe",
45
+ "#f9fbff"
46
+ ],
47
+ avatar: [
48
+ "#1976d2",
49
+ "#388e3c",
50
+ "#f57c00",
51
+ "#7b1fa2",
52
+ "#c62828",
53
+ "#00796b",
54
+ "#5d4037",
55
+ "#455a64"
56
+ ],
57
+ logo: {
58
+ background: "#E6E6E6",
59
+ fill: "#21263F"
60
+ },
61
+ countBadge: {
62
+ background: "#dfe4ff",
63
+ text: "#2b3ba8"
64
+ },
65
+ spinner: "#2eefd9",
66
+ other: "#e2e2e9",
67
+ header: "#21263F",
68
+ // Grey palette indices for light mode
69
+ grey: {
70
+ riskAutoIgnored: 600,
71
+ riskStatusIgnored: 500,
72
+ activityInactive: 400,
73
+ businessImpactDefault: 600,
74
+ gaugeBackground: 100,
75
+ slaNotSet: 300,
76
+ other: 700,
77
+ searchBackground: 50,
78
+ searchBorder: 300,
79
+ searchHoverBorder: 400,
80
+ codeBackground: 100,
81
+ codeBorder: 400
82
+ }
83
+ };
84
+ const darkPalette = {
85
+ risk: {
86
+ critical: "#d40f57ff",
87
+ high: "#f14763ff",
88
+ medium: "#ffb84d",
89
+ low: "#ffe680"
90
+ },
91
+ riskStatus: {
92
+ open: "#f2405e",
93
+ accepted: "#00d0b3"
94
+ },
95
+ trend: {
96
+ positive: {
97
+ line: "#ff7b8f",
98
+ background: "rgba(244, 67, 54, 0.2)",
99
+ text: "#ffb3bf"
100
+ },
101
+ negative: {
102
+ line: "#4dffd9",
103
+ background: "rgba(46, 239, 217, 0.2)",
104
+ text: "#80ffe6"
105
+ },
106
+ neutral: {
107
+ line: "#a3c4f3",
108
+ background: "rgba(118, 156, 214, 0.2)",
109
+ text: "#c4d9f7"
110
+ }
111
+ },
112
+ activity: {
113
+ active: "#4dffd9"
114
+ },
115
+ businessImpact: {
116
+ high: "#ff6b6b",
117
+ medium: "#ffb84d",
118
+ low: "#69db7c"
119
+ },
120
+ gauge: {
121
+ success: "#4dffd9",
122
+ warning: "#ff7b8f"
123
+ },
124
+ sla: {
125
+ breach: "#ff7b8f",
126
+ adherence: "#a3c4f3"
127
+ },
128
+ blueVariants: [
129
+ "#4a7fc7",
130
+ "#5d8fd4",
131
+ "#709fe0",
132
+ "#83afec",
133
+ "#96bff8",
134
+ "#a9cfff",
135
+ "#bcdfff",
136
+ "#cfefff",
137
+ "#e2f5ff",
138
+ "#f0faff",
139
+ "#f7fcff",
140
+ "#fafeff"
141
+ ],
142
+ avatar: [
143
+ "#5c9ce6",
144
+ "#5cb85c",
145
+ "#f5a623",
146
+ "#9b59b6",
147
+ "#e74c3c",
148
+ "#1abc9c",
149
+ "#8b6914",
150
+ "#7f8c8d"
151
+ ],
152
+ countBadge: {
153
+ background: "rgba(25, 118, 210, 0.2)",
154
+ // primary.main with 0.2 alpha
155
+ text: "#64b5f6"
156
+ // primary.light
157
+ },
158
+ logo: {
159
+ background: "rgba(255, 255, 255, 0.1)",
160
+ // white with 0.1 alpha
161
+ fill: "#ffffff"
162
+ },
163
+ spinner: "#2eefd9",
164
+ other: "#616161",
165
+ // grey[700]
166
+ header: "#21263F",
167
+ // background.paper in dark mode
168
+ // Grey palette indices for dark mode
169
+ grey: {
170
+ riskAutoIgnored: 400,
171
+ riskStatusIgnored: 400,
172
+ activityInactive: 500,
173
+ businessImpactDefault: 400,
174
+ gaugeBackground: 300,
175
+ slaNotSet: 600,
176
+ other: 700,
177
+ searchBackground: 900,
178
+ searchBorder: 700,
179
+ searchHoverBorder: 600,
180
+ codeBackground: 900,
181
+ codeBorder: 700
182
+ }
183
+ };
184
+ const getPalette = (theme) => theme.palette.mode === "dark" ? darkPalette : lightPalette;
185
+ const getRiskColors = (theme) => {
186
+ const palette = getPalette(theme);
187
+ return {
188
+ critical: palette.risk.critical,
189
+ high: palette.risk.high,
190
+ medium: palette.risk.medium,
191
+ low: palette.risk.low,
192
+ autoIgnored: theme.palette.grey[palette.grey.riskAutoIgnored]
193
+ };
194
+ };
195
+ const getRiskStatusColors = (theme) => {
196
+ const palette = getPalette(theme);
197
+ return {
198
+ open: palette.riskStatus.open,
199
+ accepted: palette.riskStatus.accepted,
200
+ ignored: theme.palette.grey[palette.grey.riskStatusIgnored]
201
+ };
202
+ };
203
+ const getTrendColors = (theme) => {
204
+ const palette = getPalette(theme);
205
+ return {
206
+ positive: palette.trend.positive,
207
+ negative: palette.trend.negative,
208
+ neutral: palette.trend.neutral
209
+ };
210
+ };
211
+ const getActivityStatusColors = (theme) => {
212
+ const palette = getPalette(theme);
213
+ return {
214
+ active: palette.activity.active,
215
+ inactive: theme.palette.grey[palette.grey.activityInactive]
216
+ };
217
+ };
218
+ const getBusinessImpactColors = (theme) => {
219
+ const palette = getPalette(theme);
220
+ return {
221
+ high: palette.businessImpact.high,
222
+ medium: palette.businessImpact.medium,
223
+ low: palette.businessImpact.low,
224
+ default: theme.palette.grey[palette.grey.businessImpactDefault]
225
+ };
226
+ };
227
+ const getGaugeColors = (theme) => {
228
+ const palette = getPalette(theme);
229
+ return {
230
+ success: palette.gauge.success,
231
+ warning: palette.gauge.warning,
232
+ background: theme.palette.grey[palette.grey.gaugeBackground],
233
+ pointer: theme.palette.text.primary
234
+ };
235
+ };
236
+ const getSlaColors = (theme) => {
237
+ const palette = getPalette(theme);
238
+ return {
239
+ breach: palette.sla.breach,
240
+ adherence: palette.sla.adherence,
241
+ notSet: theme.palette.grey[palette.grey.slaNotSet]
242
+ };
243
+ };
244
+ const getBlueColorVariants = (theme) => {
245
+ const palette = getPalette(theme);
246
+ return palette.blueVariants;
247
+ };
248
+ const getOtherColor = (theme) => {
249
+ const palette = getPalette(theme);
250
+ return palette.other || theme.palette.grey[palette.grey.other];
251
+ };
252
+ const getLogoContainerColors = (theme) => {
253
+ const palette = getPalette(theme);
254
+ return {
255
+ background: palette.logo.background,
256
+ logoFill: palette.logo.fill
257
+ };
258
+ };
259
+ const getAvatarColors = (theme) => {
260
+ const palette = getPalette(theme);
261
+ return palette.avatar;
262
+ };
263
+ const getCountBadgeColors = (theme) => {
264
+ const palette = getPalette(theme);
265
+ return {
266
+ background: palette.countBadge.background,
267
+ text: palette.countBadge.text
268
+ };
269
+ };
270
+ const getSearchToolbarColors = (theme) => {
271
+ const palette = getPalette(theme);
272
+ return {
273
+ iconColor: theme.palette.text.secondary,
274
+ backgroundColor: theme.palette.grey[palette.grey.searchBackground],
275
+ borderColor: theme.palette.grey[palette.grey.searchBorder],
276
+ hoverBorderColor: theme.palette.grey[palette.grey.searchHoverBorder],
277
+ focusBorderColor: theme.palette.primary.main
278
+ };
279
+ };
280
+ const getSpinnerColor = (theme) => {
281
+ const palette = getPalette(theme);
282
+ return palette.spinner;
283
+ };
284
+ const getHeaderBackground = (theme) => {
285
+ const palette = getPalette(theme);
286
+ return palette.header;
287
+ };
288
+
289
+ export { getActivityStatusColors, getAvatarColors, getBlueColorVariants, getBusinessImpactColors, getCountBadgeColors, getGaugeColors, getHeaderBackground, getLogoContainerColors, getOtherColor, getRiskColors, getRiskStatusColors, getSearchToolbarColors, getSlaColors, getSpinnerColor, getTrendColors };
290
+ //# sourceMappingURL=themeUtils.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"themeUtils.esm.js","sources":["../../src/theme/themeUtils.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { Theme } from '@mui/material/styles';\n\n/**\n * Valid MUI grey palette keys.\n */\ntype GreyKey =\n | 50\n | 100\n | 200\n | 300\n | 400\n | 500\n | 600\n | 700\n | 800\n | 900\n | 'A100'\n | 'A200'\n | 'A400'\n | 'A700';\n\n/**\n * Light mode color palette for the Apiiro plugin.\n */\nconst lightPalette = {\n risk: {\n critical: '#bc0e4d',\n high: '#f2405e',\n medium: '#ffa70f',\n low: '#ffe366',\n },\n riskStatus: {\n open: '#f2405e',\n accepted: '#00d0b3',\n },\n trend: {\n positive: { line: '#f44336', background: '#fde7eb', text: '#9d0b23' },\n negative: { line: '#2eefd9', background: '#d9fcf8', text: '#09776a' },\n neutral: { line: '#769cd6', background: '#ebf1fa', text: '#012b70' },\n },\n activity: {\n active: '#11e4cb',\n },\n businessImpact: {\n high: '#d32f2f',\n medium: '#f57c00',\n low: '#388e3c',\n },\n gauge: {\n success: '#2eefd9',\n warning: '#f2405e',\n },\n sla: {\n breach: '#f2405e',\n adherence: '#a8c5ff',\n },\n blueVariants: [\n '#012b70',\n '#2e5a9e',\n '#769cd6',\n '#9db9e2',\n '#b3c9e9',\n '#c5d7ef',\n '#d5e2f4',\n '#e1eaf8',\n '#ebf1fa',\n '#f2f6fd',\n '#f7fafe',\n '#f9fbff',\n ],\n avatar: [\n '#1976d2',\n '#388e3c',\n '#f57c00',\n '#7b1fa2',\n '#c62828',\n '#00796b',\n '#5d4037',\n '#455a64',\n ],\n logo: {\n background: '#E6E6E6',\n fill: '#21263F',\n },\n countBadge: {\n background: '#dfe4ff',\n text: '#2b3ba8',\n },\n spinner: '#2eefd9',\n other: '#e2e2e9',\n header: '#21263F',\n // Grey palette indices for light mode\n grey: {\n riskAutoIgnored: 600 as GreyKey,\n riskStatusIgnored: 500 as GreyKey,\n activityInactive: 400 as GreyKey,\n businessImpactDefault: 600 as GreyKey,\n gaugeBackground: 100 as GreyKey,\n slaNotSet: 300 as GreyKey,\n other: 700 as GreyKey,\n searchBackground: 50 as GreyKey,\n searchBorder: 300 as GreyKey,\n searchHoverBorder: 400 as GreyKey,\n codeBackground: 100 as GreyKey,\n codeBorder: 400 as GreyKey,\n },\n};\n\n/**\n * Dark mode color palette for the Apiiro plugin.\n */\nconst darkPalette = {\n risk: {\n critical: '#d40f57ff',\n high: '#f14763ff',\n medium: '#ffb84d',\n low: '#ffe680',\n },\n riskStatus: {\n open: '#f2405e',\n accepted: '#00d0b3',\n },\n trend: {\n positive: {\n line: '#ff7b8f',\n background: 'rgba(244, 67, 54, 0.2)',\n text: '#ffb3bf',\n },\n negative: {\n line: '#4dffd9',\n background: 'rgba(46, 239, 217, 0.2)',\n text: '#80ffe6',\n },\n neutral: {\n line: '#a3c4f3',\n background: 'rgba(118, 156, 214, 0.2)',\n text: '#c4d9f7',\n },\n },\n activity: {\n active: '#4dffd9',\n },\n businessImpact: {\n high: '#ff6b6b',\n medium: '#ffb84d',\n low: '#69db7c',\n },\n gauge: {\n success: '#4dffd9',\n warning: '#ff7b8f',\n },\n sla: {\n breach: '#ff7b8f',\n adherence: '#a3c4f3',\n },\n blueVariants: [\n '#4a7fc7',\n '#5d8fd4',\n '#709fe0',\n '#83afec',\n '#96bff8',\n '#a9cfff',\n '#bcdfff',\n '#cfefff',\n '#e2f5ff',\n '#f0faff',\n '#f7fcff',\n '#fafeff',\n ],\n avatar: [\n '#5c9ce6',\n '#5cb85c',\n '#f5a623',\n '#9b59b6',\n '#e74c3c',\n '#1abc9c',\n '#8b6914',\n '#7f8c8d',\n ],\n countBadge: {\n background: 'rgba(25, 118, 210, 0.2)', // primary.main with 0.2 alpha\n text: '#64b5f6', // primary.light\n },\n logo: {\n background: 'rgba(255, 255, 255, 0.1)', // white with 0.1 alpha\n fill: '#ffffff',\n },\n spinner: '#2eefd9',\n other: '#616161', // grey[700]\n header: '#21263F', // background.paper in dark mode\n // Grey palette indices for dark mode\n grey: {\n riskAutoIgnored: 400 as GreyKey,\n riskStatusIgnored: 400 as GreyKey,\n activityInactive: 500 as GreyKey,\n businessImpactDefault: 400 as GreyKey,\n gaugeBackground: 300 as GreyKey,\n slaNotSet: 600 as GreyKey,\n other: 700 as GreyKey,\n searchBackground: 900 as GreyKey,\n searchBorder: 700 as GreyKey,\n searchHoverBorder: 600 as GreyKey,\n codeBackground: 900 as GreyKey,\n codeBorder: 700 as GreyKey,\n },\n};\n\n/**\n * Gets the appropriate color palette based on theme mode.\n */\nconst getPalette = (theme: Theme) =>\n theme.palette.mode === 'dark' ? darkPalette : lightPalette;\n\n/**\n * Theme-aware semantic colors for risk levels.\n * These colors are designed to work in both light and dark modes.\n */\nexport const getRiskColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return {\n critical: palette.risk.critical,\n high: palette.risk.high,\n medium: palette.risk.medium,\n low: palette.risk.low,\n autoIgnored: theme.palette.grey[palette.grey.riskAutoIgnored],\n };\n};\n\n/**\n * Theme-aware semantic colors for risk status.\n */\nexport const getRiskStatusColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return {\n open: palette.riskStatus.open,\n accepted: palette.riskStatus.accepted,\n ignored: theme.palette.grey[palette.grey.riskStatusIgnored],\n };\n};\n\n/**\n * Theme-aware colors for trend indicators (positive/negative/neutral).\n */\nexport const getTrendColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return {\n positive: palette.trend.positive,\n negative: palette.trend.negative,\n neutral: palette.trend.neutral,\n };\n};\n\n/**\n * Theme-aware colors for activity status indicator.\n */\nexport const getActivityStatusColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return {\n active: palette.activity.active,\n inactive: theme.palette.grey[palette.grey.activityInactive],\n };\n};\n\n/**\n * Theme-aware colors for business impact levels.\n */\nexport const getBusinessImpactColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return {\n high: palette.businessImpact.high,\n medium: palette.businessImpact.medium,\n low: palette.businessImpact.low,\n default: theme.palette.grey[palette.grey.businessImpactDefault],\n };\n};\n\n/**\n * Theme-aware colors for gauge chart.\n */\nexport const getGaugeColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return {\n success: palette.gauge.success,\n warning: palette.gauge.warning,\n background: theme.palette.grey[palette.grey.gaugeBackground],\n pointer: theme.palette.text.primary,\n };\n};\n\n/**\n * Theme-aware colors for SLA adherence chart.\n */\nexport const getSlaColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return {\n breach: palette.sla.breach,\n adherence: palette.sla.adherence,\n notSet: theme.palette.grey[palette.grey.slaNotSet],\n };\n};\n\n/**\n * Theme-aware blue color variants for charts (e.g., TopLanguagesTile).\n */\nexport const getBlueColorVariants = (theme: Theme) => {\n const palette = getPalette(theme);\n return palette.blueVariants;\n};\n\n/**\n * Theme-aware \"other\" color for charts.\n */\nexport const getOtherColor = (theme: Theme) => {\n const palette = getPalette(theme);\n return palette.other || theme.palette.grey[palette.grey.other];\n};\n\n/**\n * Theme-aware colors for logo container.\n */\nexport const getLogoContainerColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return {\n background: palette.logo.background,\n logoFill: palette.logo.fill,\n };\n};\n\n/**\n * Theme-aware colors for avatar backgrounds.\n */\nexport const getAvatarColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return palette.avatar;\n};\n\n/**\n * Theme-aware colors for count badge.\n */\nexport const getCountBadgeColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return {\n background: palette.countBadge.background,\n text: palette.countBadge.text,\n };\n};\n\n/**\n * Theme-aware colors for search toolbar.\n */\nexport const getSearchToolbarColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return {\n iconColor: theme.palette.text.secondary,\n backgroundColor: theme.palette.grey[palette.grey.searchBackground],\n borderColor: theme.palette.grey[palette.grey.searchBorder],\n hoverBorderColor: theme.palette.grey[palette.grey.searchHoverBorder],\n focusBorderColor: theme.palette.primary.main,\n };\n};\n\n/**\n * Theme-aware colors for text (used in typography).\n */\nexport const getTypographyColors = (theme: Theme) => {\n return {\n primary: theme.palette.text.primary,\n secondary: theme.palette.text.secondary,\n disabled: theme.palette.text.disabled,\n };\n};\n\n/**\n * Theme-aware colors for code blocks.\n */\nexport const getCodeBlockColors = (theme: Theme) => {\n const palette = getPalette(theme);\n return {\n background: theme.palette.grey[palette.grey.codeBackground],\n border: theme.palette.grey[palette.grey.codeBorder],\n };\n};\n\n/**\n * Theme-aware spinner color.\n */\nexport const getSpinnerColor = (theme: Theme) => {\n const palette = getPalette(theme);\n return palette.spinner;\n};\n\n/**\n * Theme-aware header background color.\n */\nexport const getHeaderBackground = (theme: Theme) => {\n const palette = getPalette(theme);\n return palette.header || theme.palette.background.paper;\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ const formatDateWithTimeCheck = (dateString) => {
2
+ if (!dateString) return "N/A";
3
+ const date = new Date(dateString);
4
+ if (date.getHours() >= 20) {
5
+ date.setDate(date.getDate() + 1);
6
+ }
7
+ return date.toLocaleDateString("en-US", {
8
+ year: "numeric",
9
+ month: "long",
10
+ day: "numeric"
11
+ });
12
+ };
13
+ const MS_PER_DAY = 1e3 * 60 * 60 * 24;
14
+ const getDevelopmentDuration = (lastActivity) => {
15
+ if (!lastActivity) return "0 days";
16
+ const lastActivityDate = new Date(lastActivity);
17
+ const today = /* @__PURE__ */ new Date();
18
+ let years = today.getFullYear() - lastActivityDate.getFullYear();
19
+ let months = today.getMonth() - lastActivityDate.getMonth();
20
+ let days = today.getDate() - lastActivityDate.getDate();
21
+ if (days < 0) {
22
+ const lastMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1);
23
+ const daysInLastMonth = new Date(
24
+ lastMonth.getFullYear(),
25
+ lastMonth.getMonth() + 1,
26
+ 0
27
+ ).getDate();
28
+ days += daysInLastMonth;
29
+ months--;
30
+ }
31
+ if (months < 0) {
32
+ months += 12;
33
+ years--;
34
+ }
35
+ const totalMonths = years * 12 + months;
36
+ const totalDays = Math.round(
37
+ (today.getTime() - lastActivityDate.getTime()) / MS_PER_DAY
38
+ );
39
+ if (totalMonths >= 12) {
40
+ const yearCount = Math.round(totalMonths / 12);
41
+ return `${yearCount} ${yearCount === 1 ? "year" : "years"}`;
42
+ }
43
+ if (totalMonths > 0) {
44
+ return `${totalMonths} ${totalMonths === 1 ? "month" : "months"}`;
45
+ }
46
+ const dayCount = Math.max(1, totalDays);
47
+ if (dayCount === 1) return "1 day";
48
+ return `${dayCount} days`;
49
+ };
50
+ const formatActivityTooltip = (lastActivity, activeSince) => {
51
+ return `Last activity on ${formatDateWithTimeCheck(
52
+ lastActivity
53
+ )}. Active since ${formatDateWithTimeCheck(activeSince)}`;
54
+ };
55
+ const formatDate = (dateString) => {
56
+ if (!dateString) return "";
57
+ const date = new Date(dateString);
58
+ const userLocale = window.navigator.language || window.navigator.languages?.[0] || "en-US";
59
+ return date.toLocaleDateString(userLocale, {
60
+ year: "numeric",
61
+ month: "short",
62
+ day: "numeric"
63
+ });
64
+ };
65
+
66
+ export { formatActivityTooltip, formatDate, formatDateWithTimeCheck, getDevelopmentDuration };
67
+ //# sourceMappingURL=dateFormatter.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dateFormatter.esm.js","sources":["../../src/utils/dateFormatter.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport const formatDateWithTimeCheck = (dateString: string): string => {\n if (!dateString) return 'N/A';\n\n const date = new Date(dateString);\n\n // If the time is after 8 PM (20:00), add one day\n if (date.getHours() >= 20) {\n date.setDate(date.getDate() + 1);\n }\n\n return date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n });\n};\n\nconst MS_PER_DAY = 1000 * 60 * 60 * 24;\n\nexport const getDevelopmentDuration = (lastActivity: string): string => {\n if (!lastActivity) return '0 days';\n\n const lastActivityDate = new Date(lastActivity);\n const today = new Date();\n\n // Calculate the difference in years, months, and days\n let years = today.getFullYear() - lastActivityDate.getFullYear();\n let months = today.getMonth() - lastActivityDate.getMonth();\n let days = today.getDate() - lastActivityDate.getDate();\n\n // Adjust for negative days/months\n if (days < 0) {\n const lastMonth = new Date(today.getFullYear(), today.getMonth() - 1, 1);\n const daysInLastMonth = new Date(\n lastMonth.getFullYear(),\n lastMonth.getMonth() + 1,\n 0,\n ).getDate();\n days += daysInLastMonth;\n months--;\n }\n\n if (months < 0) {\n months += 12;\n years--;\n }\n\n // Calculate total months and days for more accurate year/month conversion\n const totalMonths = years * 12 + months;\n const totalDays = Math.round(\n (today.getTime() - lastActivityDate.getTime()) / MS_PER_DAY,\n );\n\n // Return the highest unit that has a value >= 1\n if (totalMonths >= 12) {\n const yearCount = Math.round(totalMonths / 12);\n return `${yearCount} ${yearCount === 1 ? 'year' : 'years'}`;\n }\n\n if (totalMonths > 0) {\n return `${totalMonths} ${totalMonths === 1 ? 'month' : 'months'}`;\n }\n\n // For days, ensure we have at least 1 day\n const dayCount = Math.max(1, totalDays);\n if (dayCount === 1) return '1 day';\n return `${dayCount} days`;\n};\n\nexport const formatActivityTooltip = (\n lastActivity: string,\n activeSince: string,\n): string => {\n return `Last activity on ${formatDateWithTimeCheck(\n lastActivity,\n )}. Active since ${formatDateWithTimeCheck(activeSince)}`;\n};\n\nexport const getStatusText = (\n isActive: boolean,\n lastActivity: string,\n): string => {\n if (!isActive) return 'Inactive';\n const duration = getDevelopmentDuration(lastActivity);\n return `In development for ${duration}`;\n};\n\n/**\n * Formats a date string to a locale-specific date format.\n * @param {string} dateString - The date string to format.\n * @returns {string} The formatted date string.\n */\nexport const formatDate = (dateString: string) => {\n if (!dateString) return '';\n const date = new Date(dateString);\n const userLocale =\n window.navigator.language || window.navigator.languages?.[0] || 'en-US';\n return date.toLocaleDateString(userLocale, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n};\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ const suffixMappings = [
2
+ { value: 1, symbol: "" },
3
+ { value: 1e3, symbol: "K" },
4
+ { value: 1e6, symbol: "M" },
5
+ { value: 1e9, symbol: "G" },
6
+ { value: 1e12, symbol: "T" },
7
+ { value: 1e15, symbol: "P" },
8
+ { value: 1e18, symbol: "E" }
9
+ ];
10
+ const defaultLocale = "en-US";
11
+ function formatNumberWithSuffix(num, decimalPlaces = 1) {
12
+ const { value, symbol } = suffixMappings.reduce(
13
+ (result, item) => num >= item.value ? item : result
14
+ );
15
+ return (num / value).toLocaleString(defaultLocale, {
16
+ maximumFractionDigits: decimalPlaces
17
+ }) + symbol;
18
+ }
19
+
20
+ export { formatNumberWithSuffix };
21
+ //# sourceMappingURL=numberFormatter.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"numberFormatter.esm.js","sources":["../../src/utils/numberFormatter.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\ninterface NumericSuffixConfig {\n value: number;\n symbol: string;\n}\n\nconst suffixMappings: NumericSuffixConfig[] = [\n { value: 1, symbol: '' },\n { value: 1e3, symbol: 'K' },\n { value: 1e6, symbol: 'M' },\n { value: 1e9, symbol: 'G' },\n { value: 1e12, symbol: 'T' },\n { value: 1e15, symbol: 'P' },\n { value: 1e18, symbol: 'E' },\n];\n\nconst defaultLocale = 'en-US';\n\nexport function formatNumberWithSuffix(\n num: number,\n decimalPlaces: number = 1,\n): string {\n const { value, symbol } = suffixMappings.reduce((result, item) =>\n num >= item.value ? item : result,\n );\n return (\n (num / value).toLocaleString(defaultLocale, {\n maximumFractionDigits: decimalPlaces,\n }) + symbol\n );\n}\n"],"names":[],"mappings":"AAoBA,MAAM,cAAA,GAAwC;AAAA,EAC5C,EAAE,KAAA,EAAO,CAAA,EAAG,MAAA,EAAQ,EAAA,EAAG;AAAA,EACvB,EAAE,KAAA,EAAO,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAI;AAAA,EAC1B,EAAE,KAAA,EAAO,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAI;AAAA,EAC1B,EAAE,KAAA,EAAO,GAAA,EAAK,MAAA,EAAQ,GAAA,EAAI;AAAA,EAC1B,EAAE,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,GAAA,EAAI;AAAA,EAC3B,EAAE,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,GAAA,EAAI;AAAA,EAC3B,EAAE,KAAA,EAAO,IAAA,EAAM,MAAA,EAAQ,GAAA;AACzB,CAAA;AAEA,MAAM,aAAA,GAAgB,OAAA;AAEf,SAAS,sBAAA,CACd,GAAA,EACA,aAAA,GAAwB,CAAA,EAChB;AACR,EAAA,MAAM,EAAE,KAAA,EAAO,MAAA,EAAO,GAAI,cAAA,CAAe,MAAA;AAAA,IAAO,CAAC,MAAA,EAAQ,IAAA,KACvD,GAAA,IAAO,IAAA,CAAK,QAAQ,IAAA,GAAO;AAAA,GAC7B;AACA,EAAA,OAAA,CACG,GAAA,GAAM,KAAA,EAAO,cAAA,CAAe,aAAA,EAAe;AAAA,IAC1C,qBAAA,EAAuB;AAAA,GACxB,CAAA,GAAI,MAAA;AAET;;;;"}
@@ -0,0 +1,27 @@
1
+ import { GitHub } from '@mui/icons-material';
2
+ import { Azure } from '../assets/providerIcons/Azure.esm.js';
3
+ import { Bitbucket } from '../assets/providerIcons/Bitbucket.esm.js';
4
+ import { Gitlab } from '../assets/providerIcons/Gitlab.esm.js';
5
+ import { APIIRO_PROJECT_ANNOTATION, APIIRO_METRICS_VIEW_ANNOTATION } from '@backstage-community/plugin-apiiro-common';
6
+
7
+ const scmProviderIcons = {
8
+ AzureDevops: Azure,
9
+ AzureDevopsServer: Azure,
10
+ BitbucketCloud: Bitbucket,
11
+ BitbucketServer: Bitbucket,
12
+ Github: GitHub,
13
+ GithubEnterprise: GitHub,
14
+ Gitlab,
15
+ GitlabServer: Gitlab
16
+ };
17
+ const isApiiroRepoAvailable = (entity) => Boolean(entity.metadata.annotations?.[APIIRO_PROJECT_ANNOTATION]);
18
+ const isApiiroMetricViewAvailable = (entity) => {
19
+ const metricViewAnnotation = entity.metadata.annotations?.[APIIRO_METRICS_VIEW_ANNOTATION];
20
+ if (metricViewAnnotation === void 0) {
21
+ return void 0;
22
+ }
23
+ return metricViewAnnotation.toLocaleLowerCase() === "true";
24
+ };
25
+
26
+ export { isApiiroMetricViewAvailable, isApiiroRepoAvailable, scmProviderIcons };
27
+ //# sourceMappingURL=utils.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.esm.js","sources":["../../src/utils/utils.ts"],"sourcesContent":["/*\n * Copyright 2025 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport { GitHub } from '@mui/icons-material';\nimport { Azure } from '../assets/providerIcons/Azure';\nimport { Bitbucket } from '../assets/providerIcons/Bitbucket';\nimport { Gitlab } from '../assets/providerIcons/Gitlab';\nimport type { Entity } from '@backstage/catalog-model';\nimport {\n APIIRO_PROJECT_ANNOTATION,\n APIIRO_METRICS_VIEW_ANNOTATION,\n} from '@backstage-community/plugin-apiiro-common';\n\nexport const scmProviderIcons: Record<string, any> = {\n AzureDevops: Azure,\n AzureDevopsServer: Azure,\n BitbucketCloud: Bitbucket,\n BitbucketServer: Bitbucket,\n Github: GitHub,\n GithubEnterprise: GitHub,\n Gitlab: Gitlab,\n GitlabServer: Gitlab,\n};\n\n/**\n * @public\n * Checks if the entity has the APIIRO project annotation.\n */\nexport const isApiiroRepoAvailable = (entity: Entity) =>\n Boolean(entity.metadata.annotations?.[APIIRO_PROJECT_ANNOTATION]);\n\n/**\n * Checks if the entity has the APIIRO project annotation.\n */\nexport const isApiiroMetricViewAvailable = (entity: Entity) => {\n const metricViewAnnotation =\n entity.metadata.annotations?.[APIIRO_METRICS_VIEW_ANNOTATION];\n\n if (metricViewAnnotation === undefined) {\n return undefined;\n }\n\n return metricViewAnnotation.toLocaleLowerCase() === 'true';\n};\n"],"names":[],"mappings":";;;;;;AAyBO,MAAM,gBAAA,GAAwC;AAAA,EACnD,WAAA,EAAa,KAAA;AAAA,EACb,iBAAA,EAAmB,KAAA;AAAA,EACnB,cAAA,EAAgB,SAAA;AAAA,EAChB,eAAA,EAAiB,SAAA;AAAA,EACjB,MAAA,EAAQ,MAAA;AAAA,EACR,gBAAA,EAAkB,MAAA;AAAA,EAClB,MAAA;AAAA,EACA,YAAA,EAAc;AAChB;AAMO,MAAM,qBAAA,GAAwB,CAAC,MAAA,KACpC,OAAA,CAAQ,OAAO,QAAA,CAAS,WAAA,GAAc,yBAAyB,CAAC;AAK3D,MAAM,2BAAA,GAA8B,CAAC,MAAA,KAAmB;AAC7D,EAAA,MAAM,oBAAA,GACJ,MAAA,CAAO,QAAA,CAAS,WAAA,GAAc,8BAA8B,CAAA;AAE9D,EAAA,IAAI,yBAAyB,MAAA,EAAW;AACtC,IAAA,OAAO,MAAA;AAAA,EACT;AAEA,EAAA,OAAO,oBAAA,CAAqB,mBAAkB,KAAM,MAAA;AACtD;;;;"}
package/package.json ADDED
@@ -0,0 +1,90 @@
1
+ {
2
+ "name": "@backstage-community/plugin-apiiro",
3
+ "version": "0.1.0",
4
+ "license": "Apache-2.0",
5
+ "main": "dist/index.esm.js",
6
+ "types": "dist/index.d.ts",
7
+ "publishConfig": {
8
+ "access": "public",
9
+ "main": "dist/index.esm.js",
10
+ "types": "dist/index.d.ts"
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/backstage/community-plugins",
15
+ "directory": "workspaces/apiiro/plugins/apiiro"
16
+ },
17
+ "backstage": {
18
+ "role": "frontend-plugin",
19
+ "pluginId": "apiiro",
20
+ "pluginPackages": [
21
+ "@backstage-community/plugin-apiiro",
22
+ "@backstage-community/plugin-apiiro-backend",
23
+ "@backstage-community/plugin-apiiro-common"
24
+ ]
25
+ },
26
+ "sideEffects": false,
27
+ "scripts": {
28
+ "start": "backstage-cli package start",
29
+ "build": "backstage-cli package build",
30
+ "lint": "backstage-cli package lint",
31
+ "test": "backstage-cli package test",
32
+ "clean": "backstage-cli package clean",
33
+ "prepack": "backstage-cli package prepack",
34
+ "postpack": "backstage-cli package postpack"
35
+ },
36
+ "dependencies": {
37
+ "@backstage-community/plugin-apiiro-common": "^0.1.0",
38
+ "@backstage/catalog-model": "^1.7.5",
39
+ "@backstage/core-components": "^0.18.2",
40
+ "@backstage/core-plugin-api": "^1.11.1",
41
+ "@backstage/plugin-catalog-react": "^1.21.2",
42
+ "@backstage/theme": "^0.7.0",
43
+ "@mui/icons-material": "^6.5.0",
44
+ "@mui/material": "^5.18.0",
45
+ "@mui/x-charts": "^7.29.1",
46
+ "@mui/x-data-grid": "^8.13.1",
47
+ "@react-spring/web": "^10.0.3",
48
+ "@tanstack/react-query": "^5.90.3",
49
+ "react-calendar": "^4.8.0",
50
+ "react-icons": "^5.5.0",
51
+ "react-use": "^17.2.4"
52
+ },
53
+ "peerDependencies": {
54
+ "react": "^17.0.0 || ^18.0.0",
55
+ "react-dom": "^17.0.0 || ^18.0.0",
56
+ "react-router-dom": "^6.30.1"
57
+ },
58
+ "devDependencies": {
59
+ "@backstage/cli": "^0.34.4",
60
+ "@backstage/core-app-api": "^1.19.1",
61
+ "@backstage/dev-utils": "^1.1.15",
62
+ "@backstage/plugin-catalog": "^1.31.4",
63
+ "@backstage/test-utils": "^1.7.12",
64
+ "@tanstack/eslint-plugin-query": "^5.91.0",
65
+ "@testing-library/jest-dom": "^6.0.0",
66
+ "@testing-library/react": "^14.0.0",
67
+ "@testing-library/user-event": "^14.0.0",
68
+ "@types/react": "^19.2.2",
69
+ "msw": "^1.0.0",
70
+ "react": "^17.0.0 || ^18.0.0",
71
+ "react-dom": "^17.0.0 || ^18.0.0",
72
+ "react-router-dom": "^6.30.1"
73
+ },
74
+ "resolutions": {
75
+ "react-is": "^17.0.0 || ^18.0.0"
76
+ },
77
+ "files": [
78
+ "dist",
79
+ "config.d.ts"
80
+ ],
81
+ "configSchema": "config.d.ts",
82
+ "typesVersions": {
83
+ "*": {
84
+ "package.json": [
85
+ "package.json"
86
+ ]
87
+ }
88
+ },
89
+ "module": "./dist/index.esm.js"
90
+ }