@backstage-community/plugin-cost-insights 0.12.25 → 0.12.27

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 (230) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/alerts/ProjectGrowthAlert.esm.js +24 -0
  3. package/dist/alerts/ProjectGrowthAlert.esm.js.map +1 -0
  4. package/dist/alerts/UnlabeledDataflowAlert.esm.js +25 -0
  5. package/dist/alerts/UnlabeledDataflowAlert.esm.js.map +1 -0
  6. package/dist/api/CostInsightsApi.esm.js +8 -0
  7. package/dist/api/CostInsightsApi.esm.js.map +1 -0
  8. package/dist/components/ActionItems/ActionItemCard.esm.js +46 -0
  9. package/dist/components/ActionItems/ActionItemCard.esm.js.map +1 -0
  10. package/dist/components/ActionItems/ActionItems.esm.js +90 -0
  11. package/dist/components/ActionItems/ActionItems.esm.js.map +1 -0
  12. package/dist/components/AlertInsights/AlertDialog.esm.js +123 -0
  13. package/dist/components/AlertInsights/AlertDialog.esm.js.map +1 -0
  14. package/dist/components/AlertInsights/AlertInsights.esm.js +157 -0
  15. package/dist/components/AlertInsights/AlertInsights.esm.js.map +1 -0
  16. package/dist/components/AlertInsights/AlertInsightsHeader.esm.js +17 -0
  17. package/dist/components/AlertInsights/AlertInsightsHeader.esm.js.map +1 -0
  18. package/dist/components/AlertInsights/AlertInsightsSection.esm.js +57 -0
  19. package/dist/components/AlertInsights/AlertInsightsSection.esm.js.map +1 -0
  20. package/dist/components/AlertInsights/AlertInsightsSectionHeader.esm.js +30 -0
  21. package/dist/components/AlertInsights/AlertInsightsSectionHeader.esm.js.map +1 -0
  22. package/dist/components/AlertInsights/AlertStatusSummary.esm.js +93 -0
  23. package/dist/components/AlertInsights/AlertStatusSummary.esm.js.map +1 -0
  24. package/dist/components/AlertInsights/AlertStatusSummaryButton.esm.js +35 -0
  25. package/dist/components/AlertInsights/AlertStatusSummaryButton.esm.js.map +1 -0
  26. package/dist/components/AlertInstructionsLayout/AlertInstructionsLayout.esm.js +47 -0
  27. package/dist/components/AlertInstructionsLayout/AlertInstructionsLayout.esm.js.map +1 -0
  28. package/dist/components/BarChart/BarChart.esm.js +167 -0
  29. package/dist/components/BarChart/BarChart.esm.js.map +1 -0
  30. package/dist/components/BarChart/BarChartLabel.esm.js +31 -0
  31. package/dist/components/BarChart/BarChartLabel.esm.js.map +1 -0
  32. package/dist/components/BarChart/BarChartLegend.esm.js +47 -0
  33. package/dist/components/BarChart/BarChartLegend.esm.js.map +1 -0
  34. package/dist/components/BarChart/BarChartStepper.esm.js +91 -0
  35. package/dist/components/BarChart/BarChartStepper.esm.js.map +1 -0
  36. package/dist/components/BarChart/BarChartStepperButton.esm.js +27 -0
  37. package/dist/components/BarChart/BarChartStepperButton.esm.js.map +1 -0
  38. package/dist/components/BarChart/BarChartSteps.esm.js +25 -0
  39. package/dist/components/BarChart/BarChartSteps.esm.js.map +1 -0
  40. package/dist/components/BarChart/BarChartTick.esm.js +29 -0
  41. package/dist/components/BarChart/BarChartTick.esm.js.map +1 -0
  42. package/dist/components/BarChart/BarChartTooltip.esm.js +30 -0
  43. package/dist/components/BarChart/BarChartTooltip.esm.js.map +1 -0
  44. package/dist/components/BarChart/BarChartTooltipItem.esm.js +24 -0
  45. package/dist/components/BarChart/BarChartTooltipItem.esm.js.map +1 -0
  46. package/dist/components/CopyUrlToClipboard/CopyUrlToClipboard.esm.js +44 -0
  47. package/dist/components/CopyUrlToClipboard/CopyUrlToClipboard.esm.js.map +1 -0
  48. package/dist/components/CostGrowth/CostGrowth.esm.js +55 -0
  49. package/dist/components/CostGrowth/CostGrowth.esm.js.map +1 -0
  50. package/dist/components/CostGrowth/CostGrowthIndicator.esm.js +31 -0
  51. package/dist/components/CostGrowth/CostGrowthIndicator.esm.js.map +1 -0
  52. package/dist/components/CostInsightsHeader/CostInsightsHeader.esm.js +57 -0
  53. package/dist/components/CostInsightsHeader/CostInsightsHeader.esm.js.map +1 -0
  54. package/dist/components/CostInsightsLayout/CostInsightsLayout.esm.js +35 -0
  55. package/dist/components/CostInsightsLayout/CostInsightsLayout.esm.js.map +1 -0
  56. package/dist/components/CostInsightsNavigation/CostInsightsNavigation.esm.js +87 -0
  57. package/dist/components/CostInsightsNavigation/CostInsightsNavigation.esm.js.map +1 -0
  58. package/dist/components/CostInsightsPage/CostInsightsPage.esm.js +229 -0
  59. package/dist/components/CostInsightsPage/CostInsightsPage.esm.js.map +1 -0
  60. package/dist/components/CostInsightsPage/CostInsightsPageRoot.esm.js +15 -0
  61. package/dist/components/CostInsightsPage/CostInsightsPageRoot.esm.js.map +1 -0
  62. package/dist/components/CostInsightsPage/CostInsightsThemeProvider.esm.js +24 -0
  63. package/dist/components/CostInsightsPage/CostInsightsThemeProvider.esm.js.map +1 -0
  64. package/dist/components/CostInsightsPage/index.esm.js +2 -0
  65. package/dist/components/CostInsightsPage/index.esm.js.map +1 -0
  66. package/dist/components/CostInsightsPage/selector.esm.js +15 -0
  67. package/dist/components/CostInsightsPage/selector.esm.js.map +1 -0
  68. package/dist/components/CostInsightsTabs/CostInsightsTabs.esm.js +89 -0
  69. package/dist/components/CostInsightsTabs/CostInsightsTabs.esm.js.map +1 -0
  70. package/dist/components/CostInsightsTabs/selector.esm.js +17 -0
  71. package/dist/components/CostInsightsTabs/selector.esm.js.map +1 -0
  72. package/dist/components/CostOverviewCard/CostOverviewBreakdownChart.esm.js +196 -0
  73. package/dist/components/CostOverviewCard/CostOverviewBreakdownChart.esm.js.map +1 -0
  74. package/dist/components/CostOverviewCard/CostOverviewCard.esm.js +99 -0
  75. package/dist/components/CostOverviewCard/CostOverviewCard.esm.js.map +1 -0
  76. package/dist/components/CostOverviewCard/CostOverviewChart.esm.js +157 -0
  77. package/dist/components/CostOverviewCard/CostOverviewChart.esm.js.map +1 -0
  78. package/dist/components/CostOverviewCard/CostOverviewHeader.esm.js +25 -0
  79. package/dist/components/CostOverviewCard/CostOverviewHeader.esm.js.map +1 -0
  80. package/dist/components/CostOverviewCard/CostOverviewLegend.esm.js +54 -0
  81. package/dist/components/CostOverviewCard/CostOverviewLegend.esm.js.map +1 -0
  82. package/dist/components/CostOverviewCard/selector.esm.js +22 -0
  83. package/dist/components/CostOverviewCard/selector.esm.js.map +1 -0
  84. package/dist/components/CurrencySelect/CurrencySelect.esm.js +52 -0
  85. package/dist/components/CurrencySelect/CurrencySelect.esm.js.map +1 -0
  86. package/dist/{esm/index-BPzWHt3A.esm.js → components/EntityCosts/EntityCosts.esm.js} +14 -80
  87. package/dist/{esm/index-BPzWHt3A.esm.js.map → components/EntityCosts/EntityCosts.esm.js.map} +1 -1
  88. package/dist/components/EntityCosts/index.esm.js +2 -0
  89. package/dist/components/EntityCosts/index.esm.js.map +1 -0
  90. package/dist/{esm/index-BA6m_qFS.esm.js → components/LabelDataflowInstructionsPage/LabelDataflowInstructionsPage.esm.js} +2 -79
  91. package/dist/components/LabelDataflowInstructionsPage/LabelDataflowInstructionsPage.esm.js.map +1 -0
  92. package/dist/components/LabelDataflowInstructionsPage/index.esm.js +2 -0
  93. package/dist/components/LabelDataflowInstructionsPage/index.esm.js.map +1 -0
  94. package/dist/components/LegendItem/LegendItem.esm.js +44 -0
  95. package/dist/components/LegendItem/LegendItem.esm.js.map +1 -0
  96. package/dist/components/MetricSelect/MetricSelect.esm.js +37 -0
  97. package/dist/components/MetricSelect/MetricSelect.esm.js.map +1 -0
  98. package/dist/components/PeriodSelect/PeriodSelect.esm.js +72 -0
  99. package/dist/components/PeriodSelect/PeriodSelect.esm.js.map +1 -0
  100. package/dist/components/ProductInsights/ProductInsights.esm.js +98 -0
  101. package/dist/components/ProductInsights/ProductInsights.esm.js.map +1 -0
  102. package/dist/components/ProductInsightsCard/ProductEntityDialog.esm.js +42 -0
  103. package/dist/components/ProductInsightsCard/ProductEntityDialog.esm.js.map +1 -0
  104. package/dist/components/ProductInsightsCard/ProductEntityTable.esm.js +139 -0
  105. package/dist/components/ProductInsightsCard/ProductEntityTable.esm.js.map +1 -0
  106. package/dist/components/ProductInsightsCard/ProductInsightsCard.esm.js +83 -0
  107. package/dist/components/ProductInsightsCard/ProductInsightsCard.esm.js.map +1 -0
  108. package/dist/components/ProductInsightsCard/ProductInsightsCardList.esm.js +34 -0
  109. package/dist/components/ProductInsightsCard/ProductInsightsCardList.esm.js.map +1 -0
  110. package/dist/components/ProductInsightsCard/ProductInsightsChart.esm.js +148 -0
  111. package/dist/components/ProductInsightsCard/ProductInsightsChart.esm.js.map +1 -0
  112. package/dist/components/ProjectGrowthAlertCard/ProjectGrowthAlertCard.esm.js +20 -0
  113. package/dist/components/ProjectGrowthAlertCard/ProjectGrowthAlertCard.esm.js.map +1 -0
  114. package/dist/components/ProjectGrowthAlertCard/ProjectGrowthAlertChart.esm.js +46 -0
  115. package/dist/components/ProjectGrowthAlertCard/ProjectGrowthAlertChart.esm.js.map +1 -0
  116. package/dist/components/ProjectGrowthInstructionsPage/ProjectGrowthInstructionsPage.esm.js +111 -0
  117. package/dist/components/ProjectGrowthInstructionsPage/ProjectGrowthInstructionsPage.esm.js.map +1 -0
  118. package/dist/components/ProjectGrowthInstructionsPage/index.esm.js +2 -0
  119. package/dist/components/ProjectGrowthInstructionsPage/index.esm.js.map +1 -0
  120. package/dist/components/ProjectSelect/ProjectSelect.esm.js +47 -0
  121. package/dist/components/ProjectSelect/ProjectSelect.esm.js.map +1 -0
  122. package/dist/components/UnlabeledDataflowAlertCard/UnlabeledDataflowAlertCard.esm.js +41 -0
  123. package/dist/components/UnlabeledDataflowAlertCard/UnlabeledDataflowAlertCard.esm.js.map +1 -0
  124. package/dist/components/WhyCostsMatter/WhyCostsMatter.esm.js +21 -0
  125. package/dist/components/WhyCostsMatter/WhyCostsMatter.esm.js.map +1 -0
  126. package/dist/example/alerts/KubernetesMigrationAlert.esm.js +86 -0
  127. package/dist/example/alerts/KubernetesMigrationAlert.esm.js.map +1 -0
  128. package/dist/example/client.esm.js +194 -0
  129. package/dist/example/client.esm.js.map +1 -0
  130. package/dist/example/components/KubernetesMigrationAlertCard/KubernetesMigrationAlertCard.esm.js +33 -0
  131. package/dist/example/components/KubernetesMigrationAlertCard/KubernetesMigrationAlertCard.esm.js.map +1 -0
  132. package/dist/{esm/index-BTIHr4n_.esm.js → example/components/KubernetesMigrationAlertCard/KubernetesMigrationBarChart.esm.js} +69 -48
  133. package/dist/example/components/KubernetesMigrationAlertCard/KubernetesMigrationBarChart.esm.js.map +1 -0
  134. package/dist/example/components/KubernetesMigrationAlertCard/KubernetesMigrationBarChartLegend.esm.js +107 -0
  135. package/dist/example/components/KubernetesMigrationAlertCard/KubernetesMigrationBarChartLegend.esm.js.map +1 -0
  136. package/dist/example/forms/KubernetesMigrationDismissForm.esm.js +57 -0
  137. package/dist/example/forms/KubernetesMigrationDismissForm.esm.js.map +1 -0
  138. package/dist/forms/AlertAcceptForm.esm.js +27 -0
  139. package/dist/forms/AlertAcceptForm.esm.js.map +1 -0
  140. package/dist/forms/AlertDismissForm.esm.js +100 -0
  141. package/dist/forms/AlertDismissForm.esm.js.map +1 -0
  142. package/dist/forms/AlertSnoozeForm.esm.js +52 -0
  143. package/dist/forms/AlertSnoozeForm.esm.js.map +1 -0
  144. package/dist/hooks/useConfig.esm.js +153 -0
  145. package/dist/hooks/useConfig.esm.js.map +1 -0
  146. package/dist/hooks/useCurrency.esm.js +26 -0
  147. package/dist/hooks/useCurrency.esm.js.map +1 -0
  148. package/dist/hooks/useFilters.esm.js +67 -0
  149. package/dist/hooks/useFilters.esm.js.map +1 -0
  150. package/dist/hooks/useGroups.esm.js +55 -0
  151. package/dist/hooks/useGroups.esm.js.map +1 -0
  152. package/dist/hooks/useLastCompleteBillingDate.esm.js +65 -0
  153. package/dist/hooks/useLastCompleteBillingDate.esm.js.map +1 -0
  154. package/dist/hooks/useLoading.esm.js +54 -0
  155. package/dist/hooks/useLoading.esm.js.map +1 -0
  156. package/dist/hooks/useScroll.esm.js +24 -0
  157. package/dist/hooks/useScroll.esm.js.map +1 -0
  158. package/dist/index.esm.js +37 -22
  159. package/dist/index.esm.js.map +1 -1
  160. package/dist/plugin.esm.js +55 -0
  161. package/dist/plugin.esm.js.map +1 -0
  162. package/dist/testUtils/filters.esm.js +8 -0
  163. package/dist/testUtils/filters.esm.js.map +1 -0
  164. package/dist/testUtils/loading.esm.js +14 -0
  165. package/dist/testUtils/loading.esm.js.map +1 -0
  166. package/dist/testUtils/mockData.esm.js +485 -0
  167. package/dist/testUtils/mockData.esm.js.map +1 -0
  168. package/dist/testUtils/products.esm.js +49 -0
  169. package/dist/testUtils/products.esm.js.map +1 -0
  170. package/dist/testUtils/providers.esm.js +41 -0
  171. package/dist/testUtils/providers.esm.js.map +1 -0
  172. package/dist/testUtils/testUtils.esm.js +142 -0
  173. package/dist/testUtils/testUtils.esm.js.map +1 -0
  174. package/dist/types/Alert.esm.js +66 -0
  175. package/dist/types/Alert.esm.js.map +1 -0
  176. package/dist/types/ChangeStatistic.esm.js +15 -0
  177. package/dist/types/ChangeStatistic.esm.js.map +1 -0
  178. package/dist/types/CurrencyType.esm.js +10 -0
  179. package/dist/types/CurrencyType.esm.js.map +1 -0
  180. package/dist/types/DateFormat.esm.js +4 -0
  181. package/dist/types/DateFormat.esm.js.map +1 -0
  182. package/dist/types/Duration.esm.js +10 -0
  183. package/dist/types/Duration.esm.js.map +1 -0
  184. package/dist/types/Icon.esm.js +12 -0
  185. package/dist/types/Icon.esm.js.map +1 -0
  186. package/dist/utils/alerts.esm.js +72 -0
  187. package/dist/utils/alerts.esm.js.map +1 -0
  188. package/dist/utils/assert.esm.js +29 -0
  189. package/dist/utils/assert.esm.js.map +1 -0
  190. package/dist/utils/change.esm.js +58 -0
  191. package/dist/utils/change.esm.js.map +1 -0
  192. package/dist/utils/charts.esm.js +9 -0
  193. package/dist/utils/charts.esm.js.map +1 -0
  194. package/dist/utils/config.esm.js +19 -0
  195. package/dist/utils/config.esm.js.map +1 -0
  196. package/dist/utils/currency.esm.js +56 -0
  197. package/dist/utils/currency.esm.js.map +1 -0
  198. package/dist/utils/duration.esm.js +55 -0
  199. package/dist/utils/duration.esm.js.map +1 -0
  200. package/dist/utils/filters.esm.js +14 -0
  201. package/dist/utils/filters.esm.js.map +1 -0
  202. package/dist/utils/formatters.esm.js +103 -0
  203. package/dist/utils/formatters.esm.js.map +1 -0
  204. package/dist/utils/grammar.esm.js +14 -0
  205. package/dist/utils/grammar.esm.js.map +1 -0
  206. package/dist/utils/graphs.esm.js +48 -0
  207. package/dist/utils/graphs.esm.js.map +1 -0
  208. package/dist/utils/history.esm.js +32 -0
  209. package/dist/utils/history.esm.js.map +1 -0
  210. package/dist/utils/loading.esm.js +51 -0
  211. package/dist/utils/loading.esm.js.map +1 -0
  212. package/dist/utils/navigation.esm.js +56 -0
  213. package/dist/utils/navigation.esm.js.map +1 -0
  214. package/dist/utils/scroll.esm.js +38 -0
  215. package/dist/utils/scroll.esm.js.map +1 -0
  216. package/dist/utils/sort.esm.js +10 -0
  217. package/dist/utils/sort.esm.js.map +1 -0
  218. package/dist/utils/styles.esm.js +562 -0
  219. package/dist/utils/styles.esm.js.map +1 -0
  220. package/dist/utils/sum.esm.js +4 -0
  221. package/dist/utils/sum.esm.js.map +1 -0
  222. package/package.json +17 -12
  223. package/dist/esm/index-BA6m_qFS.esm.js.map +0 -1
  224. package/dist/esm/index-BFM2mP6Z.esm.js +0 -4084
  225. package/dist/esm/index-BFM2mP6Z.esm.js.map +0 -1
  226. package/dist/esm/index-BTIHr4n_.esm.js.map +0 -1
  227. package/dist/esm/index-DaitkcPN.esm.js +0 -1136
  228. package/dist/esm/index-DaitkcPN.esm.js.map +0 -1
  229. package/dist/esm/selector-D7iXJwd9.esm.js +0 -594
  230. package/dist/esm/selector-D7iXJwd9.esm.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"index-BFM2mP6Z.esm.js","sources":["../../src/plugin.ts","../../src/types/Duration.ts","../../src/types/Alert.ts","../../src/types/ChangeStatistic.ts","../../src/types/CurrencyType.ts","../../src/types/DateFormat.ts","../../src/types/Icon.ts","../../src/utils/navigation.tsx","../../src/utils/config.ts","../../src/utils/assert.ts","../../src/utils/currency.ts","../../src/hooks/useConfig.tsx","../../src/hooks/useCurrency.tsx","../../src/utils/filters.ts","../../src/utils/history.ts","../../src/api/CostInsightsApi.ts","../../src/utils/duration.ts","../../src/utils/loading.ts","../../src/utils/styles.ts","../../src/hooks/useLoading.tsx","../../src/hooks/useGroups.tsx","../../src/hooks/useFilters.tsx","../../src/hooks/useScroll.tsx","../../src/hooks/useLastCompleteBillingDate.tsx","../../src/forms/AlertAcceptForm.tsx","../../src/forms/AlertSnoozeForm.tsx","../../src/forms/AlertDismissForm.tsx","../../src/utils/alerts.tsx","../../src/components/CostInsightsPage/CostInsightsThemeProvider.tsx","../../src/components/AlertInstructionsLayout/AlertInstructionsLayout.tsx","../../src/components/BarChart/BarChartLabel.tsx","../../src/components/BarChart/BarChartTick.tsx","../../src/components/BarChart/BarChartStepperButton.tsx","../../src/components/BarChart/BarChartSteps.tsx","../../src/components/BarChart/BarChartStepper.tsx","../../src/components/BarChart/BarChartTooltip.tsx","../../src/components/BarChart/BarChartTooltipItem.tsx","../../src/utils/formatters.ts","../../src/utils/sort.ts","../../src/utils/graphs.ts","../../src/components/BarChart/BarChart.tsx","../../src/components/LegendItem/LegendItem.tsx","../../src/components/BarChart/BarChartLegend.tsx","../../src/utils/change.ts","../../src/utils/grammar.ts","../../src/components/CostGrowth/CostGrowth.tsx","../../src/components/CostGrowth/CostGrowthIndicator.tsx","../../src/components/CostInsightsTabs/selector.ts","../../src/components/CostInsightsTabs/CostInsightsTabs.tsx","../../src/components/CostInsightsLayout/CostInsightsLayout.tsx","../../src/components/CostInsightsNavigation/CostInsightsNavigation.tsx","../../src/components/ProductInsightsCard/ProductEntityTable.tsx","../../src/components/ProductInsightsCard/ProductEntityDialog.tsx","../../src/components/ProductInsightsCard/ProductInsightsChart.tsx","../../src/components/ProjectGrowthAlertCard/ProjectGrowthAlertChart.tsx","../../src/components/ProjectGrowthAlertCard/ProjectGrowthAlertCard.tsx","../../src/alerts/ProjectGrowthAlert.tsx","../../src/components/UnlabeledDataflowAlertCard/UnlabeledDataflowAlertCard.tsx","../../src/alerts/UnlabeledDataflowAlert.tsx","../../src/components/ProjectGrowthInstructionsPage/ProjectGrowthInstructionsPage.tsx","../../src/example/components/KubernetesMigrationAlertCard/KubernetesMigrationBarChartLegend.tsx","../../src/example/components/KubernetesMigrationAlertCard/KubernetesMigrationBarChart.tsx","../../src/example/components/KubernetesMigrationAlertCard/KubernetesMigrationAlertCard.tsx","../../src/example/forms/KubernetesMigrationDismissForm.tsx","../../src/example/alerts/KubernetesMigrationAlert.tsx","../../src/testUtils/products.ts","../../src/testUtils/filters.ts","../../src/testUtils/loading.ts","../../src/testUtils/mockData.ts","../../src/testUtils/providers.tsx","../../src/testUtils/testUtils.ts","../../src/example/client.ts"],"sourcesContent":["/*\n * Copyright 2020 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 */\n\nimport {\n createPlugin,\n createRouteRef,\n createRoutableExtension,\n} from '@backstage/core-plugin-api';\n\nexport const rootRouteRef = createRouteRef({\n id: 'cost-insights',\n});\n\nexport const projectGrowthAlertRef = createRouteRef({\n id: 'cost-insights:investigating-growth',\n});\n\nexport const unlabeledDataflowAlertRef = createRouteRef({\n id: 'cost-insights:labeling-jobs',\n});\n\n/** @public */\nexport const costInsightsPlugin = createPlugin({\n id: 'cost-insights',\n featureFlags: [{ name: 'cost-insights-currencies' }],\n routes: {\n root: rootRouteRef,\n growthAlerts: projectGrowthAlertRef,\n unlabeledDataflowAlerts: unlabeledDataflowAlertRef,\n },\n});\n\n/** @public */\nexport const CostInsightsPage = costInsightsPlugin.provide(\n createRoutableExtension({\n name: 'CostInsightsPage',\n component: () =>\n import('./components/CostInsightsPage').then(m => m.CostInsightsPage),\n mountPoint: rootRouteRef,\n }),\n);\n\n/**\n * An extension for displaying costs on an entity page.\n *\n * @public\n */\nexport const EntityCostInsightsContent = costInsightsPlugin.provide(\n createRoutableExtension({\n name: 'EntityCostInsightsContent',\n component: () =>\n import('./components/EntityCosts').then(m => m.EntityCosts),\n mountPoint: rootRouteRef,\n }),\n);\n\n/** @public */\nexport const CostInsightsProjectGrowthInstructionsPage =\n costInsightsPlugin.provide(\n createRoutableExtension({\n name: 'CostInsightsProjectGrowthInstructionsPage',\n component: () =>\n import('./components/ProjectGrowthInstructionsPage').then(\n m => m.ProjectGrowthInstructionsPage,\n ),\n mountPoint: projectGrowthAlertRef,\n }),\n );\n\n/** @public */\nexport const CostInsightsLabelDataflowInstructionsPage =\n costInsightsPlugin.provide(\n createRoutableExtension({\n name: 'CostInsightsLabelDataflowInstructionsPage',\n component: () =>\n import('./components/LabelDataflowInstructionsPage').then(\n m => m.LabelDataflowInstructionsPage,\n ),\n mountPoint: unlabeledDataflowAlertRef,\n }),\n );\n","/*\n * Copyright 2020 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 */\n\n/**\n * Time periods for cost comparison; slight abuse of ISO 8601 periods. We take P3M to mean\n * 'last completed quarter', and P30D/P90D to be '[month|quarter] relative to today'. So if\n * it's September 15, P3M represents costs for Q2 and P30D represents August 16 -\n * September 15.\n *\n * @public\n */\nexport enum Duration {\n P7D = 'P7D',\n P30D = 'P30D',\n P90D = 'P90D',\n P3M = 'P3M',\n}\n","/*\n * Copyright 2020 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 */\n\nimport { ForwardRefExoticComponent, RefAttributes } from 'react';\nimport {\n ChangeStatistic,\n Maybe,\n} from '@backstage-community/plugin-cost-insights-common';\nimport { Duration } from './Duration';\n\n/**\n * Generic alert type with required fields for display. The `element` field will be rendered in\n * the Cost Insights \"Action Items\" section. This should use data fetched in the CostInsightsApi\n * implementation to render an InfoCard or other visualization.\n *\n * The alert type exposes hooks which can be used to enable and access various events,\n * such as when a user dismisses or snoozes an alert. Default forms and buttons\n * will be rendered if a hook is defined.\n *\n * Each default form can be overridden with a custom component. It must be implemented using\n * React.forwardRef. See https://reactjs.org/docs/forwarding-refs\n *\n * Errors thrown within hooks will generate a snackbar error notification.\n *\n * @public\n */\nexport type Alert = {\n title: string | JSX.Element;\n subtitle: string | JSX.Element;\n element?: JSX.Element;\n status?: AlertStatus;\n url?: string;\n buttonText?: string; // Default: View Instructions\n SnoozeForm?: Maybe<AlertForm>;\n AcceptForm?: Maybe<AlertForm>;\n DismissForm?: Maybe<AlertForm>;\n onSnoozed?(options: AlertOptions): Promise<Alert[]>;\n onAccepted?(options: AlertOptions): Promise<Alert[]>;\n onDismissed?(options: AlertOptions): Promise<Alert[]>;\n};\n\n/** @public */\nexport type AlertForm<\n A extends Alert = any,\n Data = any,\n> = ForwardRefExoticComponent<\n AlertFormProps<A, Data> & RefAttributes<HTMLFormElement>\n>;\n\n/** @public */\nexport interface AlertOptions<T = any> {\n data: T;\n group: string;\n}\n\n/**\n * Default snooze form intervals are expressed using an ISO 8601 repeating interval string.\n * For example, R1/P7D/2020-09-02 for 1 week or R1/P30D/2020-09-02 for 1 month.\n *\n * For example, if a user dismisses an alert on Monday January 01 for 1 week,\n * it can be re-served on Monday, January 08. 7 calendar days from January 02,\n * inclusive of the last day.\n *\n * https://en.wikipedia.org/wiki/ISO_8601#Repeating_intervals\n *\n * @public\n */\nexport interface AlertSnoozeFormData {\n intervals: string;\n}\n\n/** @public */\nexport interface AlertDismissFormData {\n other: Maybe<string>;\n reason: AlertDismissReason;\n feedback: Maybe<string>;\n}\n\n// TODO: Convert enum to literal\n/** @public */\nexport enum AlertStatus {\n Snoozed = 'snoozed',\n Accepted = 'accepted',\n Dismissed = 'dismissed',\n}\n\n/** @public */\nexport type AlertFormProps<A extends Alert, FormData = {}> = {\n alert: A;\n onSubmit: (data: FormData) => void;\n disableSubmit: (isDisabled: boolean) => void;\n};\n\n/** @public */\nexport interface AlertDismissOption {\n label: string;\n reason: string;\n}\n\n/** @public */\nexport enum AlertDismissReason {\n Other = 'other',\n Resolved = 'resolved',\n Expected = 'expected',\n Seasonal = 'seasonal',\n Migration = 'migration',\n NotApplicable = 'not-applicable',\n}\n\n/** @public */\nexport const AlertDismissOptions: AlertDismissOption[] = [\n {\n reason: AlertDismissReason.Resolved,\n label: 'This action item is now resolved.',\n },\n {\n reason: AlertDismissReason.Seasonal,\n label: 'This is an expected increase at this time of year.',\n },\n {\n reason: AlertDismissReason.Migration,\n label: 'This increase is from a migration in process.',\n },\n {\n reason: AlertDismissReason.Expected,\n label: 'This is an expected increase due to our team’s priorities.',\n },\n {\n reason: AlertDismissReason.NotApplicable,\n label: 'This action item doesn’t make sense for my team.',\n },\n {\n reason: AlertDismissReason.Other,\n label: 'Other (please specify)',\n },\n];\n\n/** @public */\nexport type AlertSnoozeOption = {\n label: string;\n duration: Duration;\n};\n\n/** @public */\nexport const AlertSnoozeOptions: AlertSnoozeOption[] = [\n {\n duration: Duration.P7D,\n label: '1 Week',\n },\n {\n duration: Duration.P30D,\n label: '1 Month',\n },\n {\n duration: Duration.P90D,\n label: '1 Quarter',\n },\n];\n\n/** @public */\nexport interface AlertCost {\n id: string;\n aggregation: [number, number];\n}\n\n/** @public */\nexport interface ResourceData {\n previous: number;\n current: number;\n name: Maybe<string>;\n}\n\n/** @public */\nexport interface BarChartOptions {\n previousFill: string;\n currentFill: string;\n previousName: string;\n currentName: string;\n}\n\n/**\n * @public\n * @deprecated use BarChartOptions instead\n */\nexport interface BarChartData extends BarChartOptions {}\n\n/** @public */\nexport enum DataKey {\n Previous = 'previous',\n Current = 'current',\n Name = 'name',\n}\n\n/** @public */\nexport interface ProjectGrowthData {\n project: string;\n periodStart: string;\n periodEnd: string;\n aggregation: [number, number];\n change: ChangeStatistic;\n products: Array<AlertCost>;\n}\n\n/** @public */\nexport interface UnlabeledDataflowData {\n periodStart: string;\n periodEnd: string;\n projects: Array<UnlabeledDataflowAlertProject>;\n unlabeledCost: number;\n labeledCost: number;\n}\n\n/** @public */\nexport interface UnlabeledDataflowAlertProject {\n id: string;\n unlabeledCost: number;\n labeledCost: number;\n}\n","/*\n * Copyright 2020 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 */\n\n/** @public */\nexport const EngineerThreshold = 0.5;\n\n/** @public */\nexport enum ChangeThreshold {\n upper = 0.05,\n lower = -0.05,\n}\n\n/** @public */\nexport enum GrowthType {\n Negligible,\n Savings,\n Excess,\n}\n","/*\n * Copyright 2020 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 */\n\n/** @public */\nexport enum CurrencyType {\n USD = 'USD',\n CarbonOffsetTons = 'CARBON_OFFSET_TONS',\n Beers = 'BEERS',\n IceCream = 'PINTS_OF_ICE_CREAM',\n}\n","/*\n * Copyright 2020 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 */\n\n/** @public */\nexport const DEFAULT_DATE_FORMAT = 'yyyy-LL-dd';\n","/*\n * Copyright 2020 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 */\n\n/** @public */\nexport type Icon = {\n kind: string;\n component: JSX.Element;\n};\n\n/** @public */\nexport enum IconType {\n Compute = 'compute',\n Data = 'data',\n Database = 'database',\n Storage = 'storage',\n Search = 'search',\n ML = 'ml',\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React from 'react';\nimport MoneyIcon from '@material-ui/icons/MonetizationOn';\nimport ActionIcon from '@material-ui/icons/Whatshot';\nimport Settings from '@material-ui/icons/Settings';\nimport AccountTree from '@material-ui/icons/AccountTree';\nimport Storage from '@material-ui/icons/Storage';\nimport Search from '@material-ui/icons/Search';\nimport CloudQueue from '@material-ui/icons/CloudQueue';\nimport School from '@material-ui/icons/School';\nimport ViewHeadline from '@material-ui/icons/ViewHeadline';\nimport { IconType } from '../types';\n\nexport enum DefaultNavigation {\n CostOverviewCard = 'cost-overview-card',\n AlertInsightsHeader = 'alert-insights-header',\n}\n\nexport type NavigationItem = {\n navigation: string;\n icon: JSX.Element;\n title: string;\n};\n\nexport const getDefaultNavigationItems = (alerts: number): NavigationItem[] => {\n const items = [\n {\n navigation: DefaultNavigation.CostOverviewCard,\n icon: <MoneyIcon />,\n title: 'Cost Overview',\n },\n ];\n if (alerts > 0) {\n items.push({\n navigation: DefaultNavigation.AlertInsightsHeader,\n icon: <ActionIcon />,\n title: 'Action Items',\n });\n }\n return items;\n};\n\nexport function getIcon(icon?: string): JSX.Element {\n switch (icon) {\n case IconType.Compute:\n return <Settings />;\n case IconType.Data:\n return <AccountTree />;\n case IconType.Database:\n return <ViewHeadline />;\n case IconType.Storage:\n return <Storage />;\n case IconType.Search:\n return <Search />;\n case IconType.ML:\n return <School />;\n default:\n return <CloudQueue />;\n }\n}\n","/*\n * Copyright 2020 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 */\n\nimport { Currency } from '../types';\nimport { Metric } from '@backstage-community/plugin-cost-insights-common';\n\nexport function validateMetrics(metrics: Metric[]) {\n const defaults = metrics.filter(metric => metric.default);\n if (defaults.length > 1) {\n throw new Error(\n `Only one default metric can be set at a time. Found ${defaults.length}`,\n );\n }\n}\n\nexport function validateCurrencies(currencies: Currency[]) {\n const withoutKinds = currencies.filter(currency => currency.kind === null);\n if (withoutKinds.length > 1) {\n throw new Error(\n `Only one currency can be without kind. Found ${withoutKinds.length}`,\n );\n }\n}\n","/*\n * Copyright 2020 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 */\n\nexport function notEmpty<TValue>(\n value: TValue | null | undefined,\n): value is TValue {\n return !isNull(value) && !isUndefined(value);\n}\n\nexport function isUndefined(value: any): value is undefined {\n return value === undefined;\n}\n\nexport function isNull(value: any): boolean {\n return value === null;\n}\n\n// Utility for exhaustiveness checking in switch statements\nexport function assertNever(x: never): never {\n throw new Error(`Exhaustiveness check failed: ${x}`);\n}\n\nexport function assertAlways<T>(argument: T | undefined): T {\n if (argument === undefined) {\n throw new TypeError(\n 'Expected to always find a value but received undefined',\n );\n }\n return argument;\n}\n\n// Utility for working with static lists; asserts a value will always be found or\n// throws an error\nexport function findAlways<T>(\n collection: T[],\n callback: (el: T) => boolean,\n): T {\n return assertAlways(collection.find(callback));\n}\n\nexport function findAnyKey<T>(\n record: Record<string, T> | undefined,\n): string | undefined {\n return Object.keys(record ?? {}).find(_ => true);\n}\n","/*\n * Copyright 2020 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 { Currency, CurrencyType, Duration } from '../types';\nimport { assertNever } from './assert';\n\nexport const rateOf = (cost: number, duration: Duration) => {\n switch (duration) {\n case Duration.P30D:\n return cost / 12;\n case Duration.P7D:\n case Duration.P90D:\n case Duration.P3M:\n return cost / 4;\n default:\n return assertNever(duration);\n }\n};\n\nexport const defaultCurrencies: Currency[] = [\n {\n kind: null,\n label: 'Engineers 🛠',\n unit: 'engineer',\n },\n {\n kind: CurrencyType.USD,\n label: 'US Dollars 💵',\n unit: 'dollar',\n prefix: '$',\n rate: 1,\n },\n {\n kind: CurrencyType.CarbonOffsetTons,\n label: 'Carbon Offset Tons ♻️⚖️s',\n unit: 'carbon offset ton',\n rate: 3.5,\n },\n {\n kind: CurrencyType.Beers,\n label: 'Beers 🍺',\n unit: 'beer',\n rate: 4.5,\n },\n {\n kind: CurrencyType.IceCream,\n label: 'Pints of Ice Cream 🍦',\n unit: 'ice cream pint',\n rate: 5.5,\n },\n];\n\nexport const createCurrencyFormat = (\n currency: string = 'USD',\n locale: string = 'en-US',\n) =>\n new Intl.NumberFormat(locale, {\n currency,\n style: 'currency',\n });\n","/*\n * Copyright 2020 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 */\n\nimport React, {\n createContext,\n PropsWithChildren,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport { Config as BackstageConfig } from '@backstage/config';\nimport { Currency, EngineerThreshold, Icon } from '../types';\nimport {\n Metric,\n Product,\n} from '@backstage-community/plugin-cost-insights-common';\nimport { getIcon } from '../utils/navigation';\nimport { validateCurrencies, validateMetrics } from '../utils/config';\nimport { createCurrencyFormat, defaultCurrencies } from '../utils/currency';\nimport { configApiRef, useApi } from '@backstage/core-plugin-api';\n\n/*\n * Config schema 2021-08-05\n *\n * costInsights:\n * engineerCost: 200000\n * products:\n * productA:\n * name: Product A\n * icon: storage\n * productB:\n * name: Product B\n * icon: data\n * metrics:\n * metricA:\n * name: Metric A\n * default: true\n * metricB:\n * name: Metric B\n * baseCurrency:\n * locale: nl-NL\n * options:\n * currency: EUR\n * minimumFractionDigits: 3\n * currencies:\n * currencyA:\n * label: Currency A\n * unit: Unit A\n * currencyB:\n * label: Currency B\n * kind: CURRENCY_B\n * unit: Unit B\n * prefix: B\n * rate: 3.5\n */\n\n/** @public */\nexport type ConfigContextProps = {\n baseCurrency: Intl.NumberFormat;\n metrics: Metric[];\n products: Product[];\n icons: Icon[];\n engineerCost: number;\n engineerThreshold: number;\n hideTrendLine: boolean;\n currencies: Currency[];\n};\n\nexport const ConfigContext = createContext<ConfigContextProps | undefined>(\n undefined,\n);\n\nconst defaultState: ConfigContextProps = {\n baseCurrency: createCurrencyFormat(),\n metrics: [],\n products: [],\n icons: [],\n engineerCost: 0,\n engineerThreshold: EngineerThreshold,\n hideTrendLine: false,\n currencies: defaultCurrencies,\n};\n\nexport const ConfigProvider = ({ children }: PropsWithChildren<{}>) => {\n const c: BackstageConfig = useApi(configApiRef);\n const [config, setConfig] = useState(defaultState);\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n function getProducts(): Product[] {\n const products = c.getOptionalConfig('costInsights.products');\n if (products) {\n return products.keys().map(key => ({\n kind: key,\n name: products.getString(`${key}.name`),\n aggregation: [0, 0],\n }));\n }\n return [];\n }\n\n function getMetrics(): Metric[] {\n const metrics = c.getOptionalConfig('costInsights.metrics');\n if (metrics) {\n return metrics.keys().map(key => ({\n kind: key,\n name: metrics.getString(`${key}.name`),\n default: metrics.getOptionalBoolean(`${key}.default`) ?? false,\n }));\n }\n\n return [];\n }\n\n function getBaseCurrency(): Intl.NumberFormat {\n const baseCurrency = c.getOptionalConfig('costInsights.baseCurrency');\n if (baseCurrency) {\n const options = baseCurrency.getOptionalConfig('options');\n return new Intl.NumberFormat(\n baseCurrency.getOptionalString('locale'),\n options\n ? {\n localeMatcher: options.getOptionalString('localeMatcher'),\n style: 'currency',\n currency: options.getOptionalString('currency'),\n currencySign: options.getOptionalString('currencySign'),\n useGrouping: options.getOptionalBoolean('useGrouping'),\n minimumIntegerDigits: options.getOptionalNumber(\n 'minimumIntegerDigits',\n ),\n minimumFractionDigits: options.getOptionalNumber(\n 'minimumFractionDigits',\n ),\n maximumFractionDigits: options.getOptionalNumber(\n 'maximumFractionDigits',\n ),\n minimumSignificantDigits: options.getOptionalNumber(\n 'minimumSignificantDigits',\n ),\n maximumSignificantDigits: options.getOptionalNumber(\n 'maximumSignificantDigits',\n ),\n }\n : undefined,\n );\n }\n\n return defaultState.baseCurrency;\n }\n\n function getCurrencies(): Currency[] {\n const currencies = c.getOptionalConfig('costInsights.currencies');\n if (currencies) {\n return currencies.keys().map(key => ({\n label: currencies.getString(`${key}.label`),\n unit: currencies.getString(`${key}.unit`),\n kind: currencies.getOptionalString(`${key}.kind`) || null,\n prefix: currencies.getOptionalString(`${key}.prefix`),\n rate: currencies.getOptionalNumber(`${key}.rate`),\n }));\n }\n\n return defaultCurrencies;\n }\n\n function getIcons(): Icon[] {\n const products = c.getOptionalConfig('costInsights.products');\n if (products) {\n return products.keys().map(k => ({\n kind: k,\n component: getIcon(products.getOptionalString(`${k}.icon`)),\n }));\n }\n return [];\n }\n\n function getEngineerCost(): number {\n return c.getNumber('costInsights.engineerCost');\n }\n\n function getEngineerThreshold(): number {\n return (\n c.getOptionalNumber('costInsights.engineerThreshold') ??\n defaultState.engineerThreshold\n );\n }\n\n function getHideTrendLine(): boolean {\n return (\n c.getOptionalBoolean('costInsights.hideTrendLine') ??\n defaultState.hideTrendLine\n );\n }\n\n function getConfig() {\n const baseCurrency = getBaseCurrency();\n const products = getProducts();\n const metrics = getMetrics();\n const engineerCost = getEngineerCost();\n const engineerThreshold = getEngineerThreshold();\n const hideTrendLine = getHideTrendLine();\n const icons = getIcons();\n const currencies = getCurrencies();\n\n validateMetrics(metrics);\n validateCurrencies(currencies);\n\n setConfig(prevState => ({\n ...prevState,\n baseCurrency,\n metrics,\n products,\n engineerCost,\n engineerThreshold,\n hideTrendLine,\n icons,\n currencies,\n }));\n\n setLoading(false);\n }\n\n getConfig();\n }, []); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (loading) {\n return null;\n }\n\n return (\n <ConfigContext.Provider value={config}>{children}</ConfigContext.Provider>\n );\n};\n\nexport function useConfig(): ConfigContextProps {\n const config = useContext(ConfigContext);\n return config ? config : assertNever();\n}\n\nfunction assertNever(): never {\n throw new Error('Cannot use useConfig outside of ConfigProvider');\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, {\n Dispatch,\n SetStateAction,\n useState,\n useContext,\n PropsWithChildren,\n} from 'react';\nimport { Currency } from '../types';\nimport { useConfig } from './useConfig';\n\n/** @public */\nexport type CurrencyContextProps = {\n currency: Currency;\n setCurrency: Dispatch<SetStateAction<Currency>>;\n};\n\nexport const CurrencyContext = React.createContext<\n CurrencyContextProps | undefined\n>(undefined);\n\nexport const CurrencyProvider = ({ children }: PropsWithChildren<{}>) => {\n const config = useConfig();\n const currencies = config.currencies;\n const engineers = currencies.find(currency => currency.kind === null);\n const [currency, setCurrency] = useState<Currency>(\n engineers || currencies[0],\n );\n return (\n <CurrencyContext.Provider value={{ currency, setCurrency }}>\n {children}\n </CurrencyContext.Provider>\n );\n};\n\nexport function useCurrency(): [Currency, Dispatch<SetStateAction<Currency>>] {\n const context = useContext(CurrencyContext);\n\n if (!context) {\n assertNever();\n }\n\n return [context.currency, context.setCurrency];\n}\n\nfunction assertNever(): never {\n throw Error('Cannot use useCurrency outside of CurrencyProvider');\n}\n","/*\n * Copyright 2020 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 */\n\nimport { Duration, PageFilters } from '../types';\nimport { Group } from '@backstage-community/plugin-cost-insights-common';\n\nexport function getDefaultPageFilters(groups: Group[]): PageFilters {\n return {\n group: groups.length ? groups[0].id : null,\n project: null,\n duration: Duration.P90D,\n metric: null,\n };\n}\n","/*\n * Copyright 2020 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 */\n\nimport qs from 'qs';\nimport * as yup from 'yup';\nimport { Duration, PageFilters } from '../types';\nimport { Group } from '@backstage-community/plugin-cost-insights-common';\nimport { getDefaultPageFilters } from '../utils/filters';\nimport { ConfigContextProps } from '../hooks/useConfig';\n\nconst schema = yup\n .object()\n .shape({\n group: yup.string().nullable(),\n project: yup.string().nullable(),\n })\n .required();\n\nexport const stringify = (queryParams: Partial<PageFilters>) =>\n qs.stringify(queryParams, { strictNullHandling: true });\n\nexport const parse = (queryString: string): Partial<PageFilters> =>\n qs.parse(queryString, { ignoreQueryPrefix: true, strictNullHandling: true });\n\nexport const validate = (queryString: string): Promise<PageFilters> => {\n return schema.validate(parse(queryString), {\n stripUnknown: true,\n strict: true,\n }) as Promise<PageFilters>;\n};\n\nexport const getInitialPageState = (\n groups: Group[],\n queryParams: Partial<PageFilters> = {},\n) => {\n return {\n ...getDefaultPageFilters(groups),\n ...(queryParams.project ? { project: queryParams.project } : {}),\n ...(queryParams.group ? { group: queryParams.group } : {}),\n };\n};\n\nexport const getInitialProductState = (config: ConfigContextProps) =>\n config.products.map(product => ({\n productType: product.kind,\n duration: Duration.P30D,\n }));\n","/*\n * Copyright 2020 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 */\n\nimport {\n Cost,\n Entity,\n Group,\n Project,\n Maybe,\n MetricData,\n} from '@backstage-community/plugin-cost-insights-common';\n\nimport { Alert } from '../types';\nimport { createApiRef } from '@backstage/core-plugin-api';\n\n/** @public */\nexport type ProductInsightsOptions = {\n /**\n * The product from the cost-insights configuration in app-config.yaml\n */\n product: string;\n\n /**\n * The group id from getUserGroups or query parameters\n */\n group: string;\n\n /**\n * An ISO 8601 repeating interval string, such as R2/P3M/2020-09-01\n */\n intervals: string;\n\n /**\n * (optional) The project id from getGroupProjects or query parameters\n */\n project: Maybe<string>;\n};\n\n/** @public */\nexport type CostInsightsApi = {\n /**\n * Get the most current date for which billing data is complete, in YYYY-MM-DD format. This helps\n * define the intervals used in other API methods to avoid showing incomplete cost. The costs for\n * today, for example, will not be complete. This ideally comes from the cloud provider.\n */\n getLastCompleteBillingDate(): Promise<string>;\n\n /**\n * Get a list of groups the given user belongs to. These may be LDAP groups or similar\n * organizational groups. Cost Insights is designed to show costs based on group membership;\n * if a user has multiple groups, they are able to switch between groups to see costs for each.\n *\n * This method should be removed once the Backstage identity plugin provides the same concept.\n *\n * @param userId - The login id for the current user\n */\n getUserGroups(userId: string): Promise<Group[]>;\n\n /**\n * Get a list of cloud billing entities that belong to this group (projects in GCP, AWS has a\n * similar concept in billing accounts). These act as filters for the displayed costs, users can\n * choose whether they see all costs for a group, or those from a particular owned project.\n *\n * @param group - The group id from getUserGroups or query parameters\n */\n getGroupProjects(group: string): Promise<Project[]>;\n\n /**\n * Get daily cost aggregations for a given catalog entity and interval time frame.\n *\n * The return type includes an array of daily cost aggregations as well as statistics about the\n * change in cost over the intervals. Calculating these statistics requires us to bucket costs\n * into two or more time periods, hence a repeating interval format rather than just a start and\n * end date.\n *\n * The rate of change in this comparison allows teams to reason about their cost growth (or\n * reduction) and compare it to metrics important to the business.\n *\n * Note: implementing this is only required when using the `EntityCostInsightsContent` extension.\n *\n * @param catalogEntityRef - A reference to the catalog entity, as described in\n * https://backstage.io/docs/features/software-catalog/references\n * @param intervals - An ISO 8601 repeating interval string, such as R2/P30D/2020-09-01\n * https://en.wikipedia.org/wiki/ISO_8601#Repeating_intervals\n */\n getCatalogEntityDailyCost?(\n catalogEntityRef: string,\n intervals: string,\n ): Promise<Cost>;\n\n /**\n * Get daily cost aggregations for a given group and interval time frame.\n *\n * The return type includes an array of daily cost aggregations as well as statistics about the\n * change in cost over the intervals. Calculating these statistics requires us to bucket costs\n * into two or more time periods, hence a repeating interval format rather than just a start and\n * end date.\n *\n * The rate of change in this comparison allows teams to reason about their cost growth (or\n * reduction) and compare it to metrics important to the business.\n *\n * @param group - The group id from getUserGroups or query parameters\n * @param intervals - An ISO 8601 repeating interval string, such as R2/P30D/2020-09-01\n * https://en.wikipedia.org/wiki/ISO_8601#Repeating_intervals\n */\n getGroupDailyCost(group: string, intervals: string): Promise<Cost>;\n\n /**\n * Get daily cost aggregations for a given billing entity (project in GCP, AWS has a similar\n * concept in billing accounts) and interval time frame.\n *\n * The return type includes an array of daily cost aggregations as well as statistics about the\n * change in cost over the intervals. Calculating these statistics requires us to bucket costs\n * into two or more time periods, hence a repeating interval format rather than just a start and\n * end date.\n *\n * The rate of change in this comparison allows teams to reason about the project's cost growth\n * (or reduction) and compare it to metrics important to the business.\n *\n * @param project - The project id from getGroupProjects or query parameters\n * @param intervals - An ISO 8601 repeating interval string, such as R2/P30D/2020-09-01\n * https://en.wikipedia.org/wiki/ISO_8601#Repeating_intervals\n */\n getProjectDailyCost(project: string, intervals: string): Promise<Cost>;\n\n /**\n * Get aggregations for a particular metric and interval time frame. Teams\n * can see metrics important to their business in comparison to the growth\n * (or reduction) of a project or group's daily costs.\n *\n * @param metric - A metric from the cost-insights configuration in app-config.yaml.\n * @param intervals - An ISO 8601 repeating interval string, such as R2/P30D/2020-09-01\n * https://en.wikipedia.org/wiki/ISO_8601#Repeating_intervals\n */\n getDailyMetricData(metric: string, intervals: string): Promise<MetricData>;\n\n /**\n * Get cost aggregations for a particular cloud product and interval time frame. This includes\n * total cost for the product, as well as a breakdown of particular entities that incurred cost\n * in this product. The type of entity depends on the product - it may be deployed services,\n * storage buckets, managed database instances, etc.\n *\n * If project is supplied, this should only return product costs for the given billing entity\n * (project in GCP).\n *\n * The time period is supplied as a Duration rather than intervals, since this is always expected\n * to return data for two bucketed time period (e.g. month vs month, or quarter vs quarter).\n *\n * @param options - Options to use when fetching insights for a particular cloud product and\n * interval time frame.\n */\n getProductInsights(options: ProductInsightsOptions): Promise<Entity>;\n\n /**\n * Get current cost alerts for a given group. These show up as Action Items for the group on the\n * Cost Insights page. Alerts may include cost-saving recommendations, such as infrastructure\n * migrations, or cost-related warnings, such as an unexpected billing anomaly.\n */\n getAlerts(group: string): Promise<Alert[]>;\n};\n\n/** @public */\nexport const costInsightsApiRef = createApiRef<CostInsightsApi>({\n id: 'plugin.costinsights.service',\n});\n","/*\n * Copyright 2020 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 */\n\nimport { DateTime, Duration as LuxonDuration } from 'luxon';\nimport { Duration, DEFAULT_DATE_FORMAT } from '../types';\nimport { assertNever } from './assert';\n\nexport const DEFAULT_DURATION = Duration.P30D;\n\n/**\n * Derive the start date of a given period, assuming two repeating intervals.\n *\n * @param duration - see comment on Duration enum\n * @param inclusiveEndDate - from CostInsightsApi.getLastCompleteBillingDate\n */\nexport function inclusiveStartDateOf(\n duration: Duration,\n inclusiveEndDate: string,\n): string {\n switch (duration) {\n case Duration.P7D:\n case Duration.P30D:\n case Duration.P90D:\n return DateTime.fromISO(inclusiveEndDate)\n .minus(\n LuxonDuration.fromISO(duration).plus(LuxonDuration.fromISO(duration)),\n )\n .toFormat(DEFAULT_DATE_FORMAT);\n case Duration.P3M:\n return DateTime.fromISO(inclusiveEndDate)\n .startOf('quarter')\n .minus(\n LuxonDuration.fromISO(duration).plus(LuxonDuration.fromISO(duration)),\n )\n .toFormat(DEFAULT_DATE_FORMAT);\n default:\n return assertNever(duration);\n }\n}\n\nexport function exclusiveEndDateOf(\n duration: Duration,\n inclusiveEndDate: string,\n): string {\n switch (duration) {\n case Duration.P7D:\n case Duration.P30D:\n case Duration.P90D:\n return DateTime.fromISO(inclusiveEndDate)\n .plus({ days: 1 })\n .toFormat(DEFAULT_DATE_FORMAT);\n case Duration.P3M:\n return DateTime.fromISO(quarterEndDate(inclusiveEndDate))\n .plus({ days: 1 })\n .toFormat(DEFAULT_DATE_FORMAT);\n default:\n return assertNever(duration);\n }\n}\n\nexport function inclusiveEndDateOf(\n duration: Duration,\n inclusiveEndDate: string,\n): string {\n return DateTime.fromISO(exclusiveEndDateOf(duration, inclusiveEndDate))\n .minus({ days: 1 })\n .toFormat(DEFAULT_DATE_FORMAT);\n}\n\n// https://en.wikipedia.org/wiki/ISO_8601#Repeating_intervals\nexport function intervalsOf(\n duration: Duration,\n inclusiveEndDate: string,\n repeating: number = 2,\n) {\n return `R${repeating}/${duration}/${exclusiveEndDateOf(\n duration,\n inclusiveEndDate,\n )}`;\n}\n\nexport function quarterEndDate(inclusiveEndDate: string): string {\n const endDate = DateTime.fromISO(inclusiveEndDate);\n const endOfQuarter = endDate.endOf('quarter').toFormat(DEFAULT_DATE_FORMAT);\n if (endOfQuarter === inclusiveEndDate) {\n return endDate.toFormat(DEFAULT_DATE_FORMAT);\n }\n return endDate\n .startOf('quarter')\n .minus({ days: 1 })\n .toFormat(DEFAULT_DATE_FORMAT);\n}\n","/*\n * Copyright 2020 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 */\n\nimport { Duration, Loading } from '../types';\nimport {\n Entity,\n Maybe,\n Product,\n} from '@backstage-community/plugin-cost-insights-common';\nimport { DEFAULT_DURATION } from './duration';\n\nexport type ProductState = {\n product: Product;\n entity: Maybe<Entity>;\n duration: Duration;\n};\n\nexport enum DefaultLoadingAction {\n UserGroups = 'user-groups',\n LastCompleteBillingDate = 'billing-date',\n CostInsightsInitial = 'cost-insights-initial',\n CostInsightsPage = 'cost-insights-page',\n CostInsightsProducts = 'cost-insights-products',\n CostInsightsAlerts = 'cost-insights-alerts',\n}\n\nexport const INITIAL_LOADING_ACTIONS = [\n DefaultLoadingAction.UserGroups,\n DefaultLoadingAction.CostInsightsInitial,\n DefaultLoadingAction.CostInsightsProducts,\n];\n\nexport const getDefaultState = (loadingActions: string[]): Loading => {\n return loadingActions.reduce(\n (defaultState, action) => ({ ...defaultState, [action]: true }),\n {},\n );\n};\n\nexport const getResetState = (loadingActions: string[]): Loading => {\n return loadingActions.reduce(\n (defaultState, action) => ({ ...defaultState, [action]: false }),\n {},\n );\n};\n\nexport const getResetStateWithoutInitial = (\n loadingActions: string[],\n): Loading => {\n return loadingActions.reduce((defaultState, action) => {\n const loadingActionState = (INITIAL_LOADING_ACTIONS as string[]).includes(\n action,\n )\n ? false\n : true;\n return { ...defaultState, [action]: loadingActionState };\n }, {});\n};\n\nexport const settledResponseOf = (\n responses: PromiseSettledResult<Entity | any>[],\n): Array<Maybe<Entity>> => {\n return responses.map(response =>\n response.status === 'fulfilled' ? response.value : null,\n );\n};\n\nexport const initialStatesOf = (\n products: Product[],\n responses: Array<Maybe<Entity>>,\n): ProductState[] => {\n return products.map((product, index) => ({\n entity: responses[index],\n product: product,\n duration: DEFAULT_DURATION,\n }));\n};\n","/*\n * Copyright 2020 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 */\n\nimport {\n emphasize,\n lighten,\n darken,\n getLuminance,\n} from '@material-ui/core/styles/colorManipulator';\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\nimport { CostInsightsTheme, CostInsightsThemeOptions } from '../types';\n\nexport const costInsightsLightTheme = {\n palette: {\n blue: '#509AF5',\n lightBlue: '#9BF0E1',\n darkBlue: '#4101F5',\n magenta: '#DC148C',\n yellow: '#FFC864',\n tooltip: {\n background: '#171717',\n color: '#DDD',\n },\n navigationText: '#b5b5b5',\n alertBackground: 'rgba(219, 219, 219, 0.13)',\n dataViz: [\n '#509BF5',\n '#4B917D',\n '#FF6437',\n '#F573A0',\n '#F59B23',\n '#B49BC8',\n '#C39687',\n '#A0C3D2',\n '#FFC864',\n '#BABABA',\n ],\n },\n} as CostInsightsThemeOptions;\n\n// Higher tonal values from light theme (Google recommends 600 -> 200)\n// https://material.io/design/color/the-color-system.html#tools-for-picking-colors\nexport const costInsightsDarkTheme = {\n palette: {\n blue: '#77b8f9',\n lightBlue: '#d8f9f4',\n darkBlue: '#b595fd',\n magenta: '#ee93cd',\n yellow: '#fff2da',\n tooltip: {\n background: '#EEE',\n color: '#424242',\n },\n navigationText: '#b5b5b5',\n alertBackground: 'rgba(32, 32, 32, 0.13)',\n dataViz: [\n '#8accff',\n '#7bc2ac',\n '#ff9664',\n '#ffa5d1',\n '#ffcc57',\n '#e6ccfb',\n '#f7c7b7',\n '#d2f6ff',\n '#fffb94',\n '#ececec',\n ],\n },\n} as CostInsightsThemeOptions;\n\n// The opposite of Material UI's emphasize function - darken darks, lighten lights\nexport function brighten(color: string, coefficient = 0.2) {\n return getLuminance(color) > 0.5\n ? lighten(color, coefficient)\n : darken(color, coefficient);\n}\n\nexport const useCostOverviewStyles = (theme: CostInsightsTheme) => ({\n axis: {\n fill: theme.palette.text.primary,\n },\n container: {\n height: 450,\n width: 1200,\n },\n cartesianGrid: {\n stroke: theme.palette.textVerySubtle,\n },\n chart: {\n margin: {\n right: 30,\n top: 16,\n },\n },\n yAxis: {\n width: 75,\n },\n});\n\nexport const useOverviewTabsStyles = makeStyles<CostInsightsTheme>(\n (theme: CostInsightsTheme) => ({\n default: {\n padding: theme.spacing(2),\n fontWeight: theme.typography.fontWeightBold,\n color: theme.palette.text.secondary,\n textTransform: 'uppercase',\n },\n selected: {\n color: theme.palette.text.primary,\n },\n }),\n);\n\nexport const useBarChartStyles = (theme: CostInsightsTheme) => ({\n axis: {\n fill: theme.palette.text.primary,\n },\n barChart: {\n margin: {\n left: 16,\n right: 16,\n },\n },\n cartesianGrid: {\n stroke: theme.palette.textVerySubtle,\n },\n cursor: {\n fill: theme.palette.textVerySubtle,\n fillOpacity: 0.3,\n },\n container: {\n height: 400,\n width: 1200,\n },\n infoIcon: {\n marginLeft: 2,\n fontSize: '1.25em',\n },\n xAxis: {\n height: 50,\n },\n});\n\nexport const useBarChartLayoutStyles = makeStyles(theme =>\n createStyles({\n wrapper: {\n display: 'flex',\n flexDirection: 'column',\n },\n legend: {\n paddingBottom: theme.spacing(2),\n },\n }),\n);\n\nexport const useBarChartStepperButtonStyles = makeStyles<CostInsightsTheme>(\n (theme: CostInsightsTheme) =>\n createStyles({\n root: {\n ...theme.typography.button,\n boxSizing: 'border-box',\n transition: theme.transitions.create(\n ['background-color', 'box-shadow', 'border'],\n {\n duration: theme.transitions.duration.short,\n },\n ),\n borderRadius: '50%',\n padding: 0,\n width: 40,\n height: 40,\n boxShadow: theme.shadows[6],\n '&:active': {\n boxShadow: theme.shadows[12],\n },\n color: theme.palette.text.primary,\n backgroundColor: lighten(theme.palette.background.default, 0.1),\n '&:hover': {\n backgroundColor: lighten(theme.palette.background.default, 0.2),\n textDecoration: 'none',\n },\n },\n }),\n);\n\nexport const useBarChartLabelStyles = makeStyles(theme =>\n createStyles({\n foreignObject: {\n textAlign: 'center',\n },\n label: {\n fontWeight: theme.typography.fontWeightBold,\n display: 'block',\n textDecoration: 'none',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n },\n infoIcon: {\n marginLeft: 2,\n fontSize: '1.25em',\n },\n button: {\n textTransform: 'none',\n fontWeight: theme.typography.fontWeightBold,\n fontSize: theme.typography.fontSize,\n },\n }),\n);\n\nexport const useCostInsightsStyles = makeStyles(theme => ({\n h6Subtle: {\n ...theme.typography.h6,\n fontWeight: 'normal',\n color: theme.palette.textSubtle,\n },\n}));\n\nexport const useCostInsightsTabsStyles = makeStyles<Theme>(theme => ({\n tabs: {\n borderBottom: `1px solid ${theme.palette.textVerySubtle}`,\n backgroundColor: brighten(theme.palette.background.default),\n padding: theme.spacing(0, 4),\n },\n tab: {\n minHeight: 68,\n minWidth: 180,\n padding: theme.spacing(1, 4),\n '&:hover': {\n color: 'inherit',\n backgroundColor: 'inherit',\n },\n },\n indicator: {\n backgroundColor: theme.palette.navigation.indicator,\n height: 4,\n },\n tabLabel: {\n display: 'flex',\n alignItems: 'center',\n },\n tabLabelText: {\n fontSize: theme.typography.fontSize,\n fontWeight: theme.typography.fontWeightBold,\n },\n menuItem: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n minWidth: 180,\n padding: theme.spacing(2, 2),\n },\n menuItemSelected: {\n backgroundColor: lighten(theme.palette.background.default, 0.3),\n },\n}));\n\nexport const useAlertCardActionHeaderStyles = makeStyles(theme =>\n createStyles({\n root: {\n paddingBottom: theme.spacing(2),\n borderRadius: 'unset',\n },\n title: {\n fontSize: theme.typography.fontSize,\n fontWeight: theme.typography.fontWeightBold,\n lineHeight: 1.5,\n },\n action: {\n margin: 0,\n },\n }),\n);\n\nexport const useCostGrowthStyles = makeStyles(theme =>\n createStyles({\n excess: {\n color: theme.palette.status.error,\n },\n savings: {\n color: theme.palette.status.ok,\n },\n indicator: {\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'center',\n justifyContent: 'flex-end',\n },\n }),\n);\n\nexport const useCostGrowthLegendStyles = makeStyles(theme => ({\n h5: {\n ...theme.typography.h5,\n fontWeight: 500,\n padding: 0,\n },\n marker: {\n display: 'inherit',\n marginRight: theme.spacing(1),\n },\n helpIcon: {\n display: 'inherit',\n },\n title: {\n ...theme.typography.overline,\n fontWeight: 500,\n lineHeight: 0,\n marginRight: theme.spacing(1),\n color: theme.palette.textSubtle,\n },\n tooltip: {\n display: 'block',\n padding: theme.spacing(1),\n backgroundColor: theme.palette.navigation.background,\n },\n tooltipText: {\n color: theme.palette.background.default,\n fontSize: theme.typography.fontSize,\n lineHeight: 1.5,\n },\n}));\n\nexport const useBarChartStepperStyles = makeStyles(theme =>\n createStyles({\n paper: {\n display: 'flex',\n flexDirection: 'row',\n justifyContent: 'space-around',\n alignItems: 'center',\n background: 'transparent',\n padding: 8,\n },\n step: {\n backgroundColor: theme.palette.action.disabled,\n borderRadius: '50%',\n width: 9,\n height: 9,\n margin: '0 2px',\n },\n stepActive: {\n backgroundColor: theme.palette.primary.main,\n },\n steps: {\n display: 'flex',\n flexDirection: 'row',\n },\n backButton: {\n position: 'absolute',\n left: 0,\n top: 'calc(50% - 60px)',\n zIndex: 100,\n },\n nextButton: {\n position: 'absolute',\n right: 0,\n top: 'calc(50% - 60px)',\n zIndex: 100,\n },\n }),\n);\n\nexport const useNavigationStyles = makeStyles<CostInsightsTheme>(\n (theme: CostInsightsTheme) =>\n createStyles({\n menuList: {\n borderRadius: theme.shape.borderRadius,\n backgroundColor: theme.palette.navigation.background,\n minWidth: 250,\n },\n menuItem: {\n background: 'transparent',\n border: 0,\n textTransform: 'none',\n width: '100%',\n minHeight: theme.spacing(6),\n margin: theme.spacing(0.5, 2, 0.5, 0),\n },\n listItemIcon: {\n minWidth: 40,\n },\n navigationIcon: {\n fill: theme.palette.navigationText,\n },\n title: {\n whiteSpace: 'nowrap',\n lineHeight: 1,\n color: theme.palette.navigationText,\n fontWeight: theme.typography.fontWeightBold,\n },\n }),\n);\n\nexport const useTooltipStyles = makeStyles<CostInsightsTheme>(\n (theme: CostInsightsTheme) =>\n createStyles({\n tooltip: {\n backgroundColor: theme.palette.tooltip.background,\n borderRadius: theme.shape.borderRadius,\n boxShadow: theme.shadows[1],\n color: theme.palette.tooltip.color,\n fontSize: theme.typography.fontSize,\n minWidth: 300,\n },\n maxWidth: {\n maxWidth: 300,\n },\n actions: {\n padding: theme.spacing(2),\n },\n header: {\n padding: theme.spacing(2),\n },\n content: {\n padding: theme.spacing(2),\n },\n lensIcon: {\n fontSize: `.75rem`,\n },\n divider: {\n backgroundColor: emphasize(theme.palette.divider, 1),\n },\n truncate: {\n maxWidth: 200,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n },\n subtitle: {\n fontStyle: 'italic',\n },\n }),\n);\n\nexport const useAlertInsightsSectionStyles = makeStyles(theme =>\n createStyles({\n button: {\n backgroundColor: theme.palette.textVerySubtle,\n color: theme.palette.text.primary,\n },\n }),\n);\n\nexport const useSelectStyles = makeStyles(theme =>\n createStyles({\n select: {\n minWidth: 200,\n textAlign: 'start',\n backgroundColor: theme.palette.background.paper,\n },\n menuItem: {\n minWidth: 200,\n padding: theme.spacing(2),\n '&.compact': {\n padding: theme.spacing(1, 2),\n },\n },\n }),\n);\n\nexport const useActionItemCardStyles = makeStyles<CostInsightsTheme>(\n (theme: CostInsightsTheme) =>\n createStyles({\n card: {\n boxShadow: 'none',\n },\n avatar: {\n backgroundColor: theme.palette.textVerySubtle,\n color: theme.palette.text.primary,\n },\n root: {\n minHeight: 80,\n paddingBottom: theme.spacing(2),\n borderRadius: theme.shape.borderRadius,\n },\n activeRoot: {\n cursor: 'pointer',\n transition: theme.transitions.create('background', {\n duration: theme.transitions.duration.short,\n }),\n '&:hover': {\n background: theme.palette.alertBackground,\n },\n },\n action: {\n margin: 0,\n },\n title: {\n fontSize: theme.typography.fontSize,\n fontWeight: theme.typography.fontWeightBold,\n },\n }),\n);\n\nexport const useProductInsightsCardStyles = makeStyles(theme =>\n createStyles({\n root: {\n padding: theme.spacing(2, 2, 2, 2.5), // restore backstage default padding\n },\n action: {\n margin: 0, // unset negative margins\n },\n }),\n);\n\nexport const useProductInsightsChartStyles = makeStyles(theme =>\n createStyles({\n indicator: {\n fontWeight: theme.typography.fontWeightBold,\n fontSize: '1.25rem',\n },\n actions: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n },\n }),\n);\n\nexport const useBackdropStyles = makeStyles(theme =>\n createStyles({\n root: {\n zIndex: theme.zIndex.modal,\n },\n }),\n);\n\nexport const useSubtleTypographyStyles = makeStyles(theme =>\n createStyles({\n root: {\n color: theme.palette.textSubtle,\n },\n }),\n);\n\nexport const useEntityDialogStyles = makeStyles(theme =>\n createStyles({\n dialogContent: {\n padding: 0,\n },\n dialogTitle: {\n padding: 0,\n },\n closeButton: {\n position: 'absolute',\n right: theme.spacing(1),\n top: theme.spacing(1),\n color: theme.palette.grey[500],\n zIndex: 100,\n },\n row: {\n fontSize: theme.typography.fontSize * 1.25,\n },\n rowTotal: {\n fontWeight: theme.typography.fontWeightBold,\n },\n colFirst: {\n paddingLeft: theme.spacing(2),\n },\n colLast: {\n paddingRight: theme.spacing(2),\n },\n column: {\n fontWeight: theme.typography.fontWeightBold,\n },\n growth: {\n display: 'flex',\n flexDirection: 'row',\n alignContent: 'center',\n justifyContent: 'flex-end',\n },\n }),\n);\n\nexport const useAlertDialogStyles = makeStyles(theme =>\n createStyles({\n content: {\n padding: theme.spacing(0, 5, 2, 5),\n },\n actions: {\n padding: theme.spacing(2, 5),\n },\n radio: {\n margin: theme.spacing(-0.5, 0, -0.5, 0),\n },\n icon: {\n color: theme.palette.primary.dark,\n margin: theme.spacing(2.5, 2.5, 0, 0),\n padding: 0,\n },\n }),\n);\n\nexport const useAlertStatusSummaryButtonStyles = makeStyles(() => ({\n icon: {\n transform: 'transform 5s',\n },\n clicked: {\n transform: 'rotate(180deg)',\n },\n}));\n","/*\n * Copyright 2020 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 */\n\nimport React, {\n createContext,\n Dispatch,\n PropsWithChildren,\n SetStateAction,\n useContext,\n useEffect,\n useMemo,\n useReducer,\n useState,\n} from 'react';\nimport Backdrop from '@material-ui/core/Backdrop';\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport { Loading } from '../types';\nimport {\n DefaultLoadingAction,\n getDefaultState,\n INITIAL_LOADING_ACTIONS,\n} from '../utils/loading';\nimport { useBackdropStyles as useStyles } from '../utils/styles';\nimport { useConfig } from './useConfig';\n\nexport type LoadingContextProps = {\n state: Loading;\n dispatch: Dispatch<Partial<SetStateAction<Loading>>>;\n actions: Array<string>;\n};\n\nexport type MapLoadingToProps<T> = (props: LoadingContextProps) => T;\n\nexport const LoadingContext = createContext<LoadingContextProps | undefined>(\n undefined,\n);\n\nfunction reducer(prevState: Loading, action: Partial<Loading>): Loading {\n return {\n ...prevState,\n ...action,\n } as Record<string, boolean>;\n}\n\nexport const LoadingProvider = ({ children }: PropsWithChildren<{}>) => {\n const classes = useStyles();\n const { products } = useConfig();\n const actions = useMemo(\n () =>\n INITIAL_LOADING_ACTIONS.filter(\n action =>\n products.length ||\n action !== DefaultLoadingAction.CostInsightsProducts,\n ),\n [products],\n );\n const [state, dispatch] = useReducer(reducer, getDefaultState(actions));\n const [isBackdropVisible, setBackdropVisible] = useState(false);\n\n useEffect(() => {\n function displayLoadingBackdrop() {\n // Initial page loading is handled by progress bar\n setBackdropVisible(\n !state[DefaultLoadingAction.CostInsightsInitial] &&\n Object.values(state).some(l => l),\n );\n }\n displayLoadingBackdrop();\n }, [state, setBackdropVisible]);\n\n return (\n <LoadingContext.Provider value={{ state, actions, dispatch }}>\n {children}\n <Backdrop open={isBackdropVisible} classes={classes}>\n <CircularProgress />\n </Backdrop>\n </LoadingContext.Provider>\n );\n};\n\nexport function useLoading<T>(mapLoadingToProps: MapLoadingToProps<T>): T {\n const context = useContext(LoadingContext);\n\n if (!context) {\n assertNever();\n }\n\n return mapLoadingToProps({\n state: context.state,\n actions: context.actions,\n dispatch: context.dispatch,\n });\n}\n\nfunction assertNever(): never {\n throw Error('useLoading cannot be used outside of LoadingProvider');\n}\n","/*\n * Copyright 2020 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 */\n\nimport React, {\n PropsWithChildren,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport Alert from '@material-ui/lab/Alert';\nimport { costInsightsApiRef } from '../api';\nimport { MapLoadingToProps, useLoading } from './useLoading';\nimport { Group, Maybe } from '@backstage-community/plugin-cost-insights-common';\nimport { DefaultLoadingAction } from '../utils/loading';\nimport { useApi, identityApiRef } from '@backstage/core-plugin-api';\nimport { DEFAULT_NAMESPACE, parseEntityRef } from '@backstage/catalog-model';\n\ntype GroupsProviderLoadingProps = {\n dispatchLoadingGroups: (isLoading: boolean) => void;\n};\n\nconst mapLoadingToProps: MapLoadingToProps<GroupsProviderLoadingProps> = ({\n dispatch,\n}) => ({\n dispatchLoadingGroups: (isLoading: boolean) =>\n dispatch({ [DefaultLoadingAction.UserGroups]: isLoading }),\n});\n\nexport type GroupsContextProps = {\n groups: Group[];\n};\n\nexport const GroupsContext = React.createContext<\n GroupsContextProps | undefined\n>(undefined);\n\nexport const GroupsProvider = ({ children }: PropsWithChildren<{}>) => {\n const identityApi = useApi(identityApiRef);\n const client = useApi(costInsightsApiRef);\n const [error, setError] = useState<Maybe<Error>>(null);\n const { dispatchLoadingGroups } = useLoading(mapLoadingToProps);\n\n const [groups, setGroups] = useState<Maybe<Group[]>>(null);\n\n useEffect(() => {\n dispatchLoadingGroups(true);\n\n async function getUserGroups() {\n try {\n const { userEntityRef } = await identityApi.getBackstageIdentity();\n const { name: userId } = parseEntityRef(userEntityRef, {\n defaultKind: 'User',\n defaultNamespace: DEFAULT_NAMESPACE,\n });\n const g = await client.getUserGroups(userId);\n setGroups(g);\n } catch (e) {\n setError(e);\n } finally {\n dispatchLoadingGroups(false);\n }\n }\n\n getUserGroups();\n }, [client]); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n if (!groups) return null;\n\n return (\n <GroupsContext.Provider value={{ groups: groups }}>\n {children}\n </GroupsContext.Provider>\n );\n};\n\nexport function useGroups(): Group[] {\n const context = useContext(GroupsContext);\n return context ? context.groups : assertNever();\n}\n\nfunction assertNever(): never {\n throw Error('Cannot use useGroups outside of GroupsProvider');\n}\n","/*\n * Copyright 2020 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 */\n\nimport React, {\n Dispatch,\n PropsWithChildren,\n SetStateAction,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport Alert from '@material-ui/lab/Alert';\nimport { PageFilters, ProductFilters } from '../types';\nimport { Maybe } from '@backstage-community/plugin-cost-insights-common';\nimport { useLocation, useNavigate } from 'react-router-dom';\nimport {\n stringify,\n validate,\n getInitialPageState,\n getInitialProductState,\n} from '../utils/history';\nimport { useGroups } from './useGroups';\nimport { useConfig } from './useConfig';\n\nexport type FilterContextProps = {\n pageFilters: PageFilters;\n productFilters: ProductFilters;\n setPageFilters: Dispatch<SetStateAction<Maybe<PageFilters>>>;\n setProductFilters: Dispatch<SetStateAction<Maybe<ProductFilters>>>;\n};\n\nexport type MapFiltersToProps<T> = (props: FilterContextProps) => T;\n\nexport const FilterContext = React.createContext<\n FilterContextProps | undefined\n>(undefined);\n\nexport const FilterProvider = ({ children }: PropsWithChildren<{}>) => {\n const config = useConfig();\n const navigate = useNavigate();\n const location = useLocation();\n const groups = useGroups();\n const [error, setError] = useState<Maybe<Error>>(null);\n const [pageFilters, setPageFilters] = useState<Maybe<PageFilters>>(null);\n const [productFilters, setProductFilters] =\n useState<Maybe<ProductFilters>>(null);\n\n useEffect(() => {\n async function setPageFiltersFromLocation() {\n try {\n // strip extraneous parameters, validate and transform\n const queryParams = await validate(location.search);\n const defaultMetric = config.metrics.find(m => m.default)?.kind ?? null;\n\n // Group or project parameters should override defaults\n const initialPageState = getInitialPageState(groups, queryParams);\n const initialProductState = getInitialProductState(config);\n\n setProductFilters(initialProductState);\n setPageFilters({ ...initialPageState, metric: defaultMetric });\n } catch (e) {\n setError(e);\n }\n }\n\n setPageFiltersFromLocation();\n }, [groups]); // eslint-disable-line react-hooks/exhaustive-deps\n\n useEffect(() => {\n function setLocationFromPageFilters(filters: PageFilters) {\n const queryString = stringify({\n group: filters.group,\n ...(filters.project ? { project: filters.project } : {}),\n });\n // TODO Remove workaround once issue is resolved in react-router\n // (https://github.com/ReactTraining/react-router/issues/7496)\n // navigate({ ...location, search: queryString });\n navigate({ ...location, search: `?${queryString}` });\n }\n\n if (pageFilters) {\n setLocationFromPageFilters(pageFilters);\n }\n }, [pageFilters]); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n // Wait for filters to load\n if (!pageFilters || !productFilters) {\n return null;\n }\n\n return (\n <FilterContext.Provider\n value={{ pageFilters, productFilters, setPageFilters, setProductFilters }}\n >\n {children}\n </FilterContext.Provider>\n );\n};\n\nexport function useFilters<T>(mapFiltersToProps: MapFiltersToProps<T>): T {\n const context = useContext(FilterContext);\n return context ? mapFiltersToProps(context) : assertNever();\n}\n\nfunction assertNever(): never {\n throw Error('Cannot use useFilters outside of FilterProvider');\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, {\n Dispatch,\n SetStateAction,\n useState,\n useContext,\n PropsWithChildren,\n} from 'react';\nimport { Maybe } from '@backstage-community/plugin-cost-insights-common';\n\nexport type ScrollTo = Maybe<string>;\n\nexport type ScrollContextProps = {\n scroll: ScrollTo;\n setScroll: Dispatch<SetStateAction<ScrollTo>>;\n};\n\nexport const ScrollContext = React.createContext<\n ScrollContextProps | undefined\n>(undefined);\n\nexport const ScrollProvider = ({ children }: PropsWithChildren<{}>) => {\n const [scroll, setScroll] = useState<ScrollTo>(null);\n return (\n <ScrollContext.Provider value={{ scroll, setScroll }}>\n {children}\n </ScrollContext.Provider>\n );\n};\n\nexport enum ScrollType {\n AlertSummary = 'alert-status-summary',\n}\n\nexport function useScroll() {\n const context = useContext(ScrollContext);\n\n if (!context) {\n assertNever();\n }\n\n return [context.scroll, context.setScroll] as const;\n}\n\nfunction assertNever(): never {\n throw new Error(`Cannot use useScroll outside ScrollProvider`);\n}\n","/*\n * Copyright 2020 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 */\n\nimport React, {\n PropsWithChildren,\n useContext,\n useEffect,\n useState,\n} from 'react';\nimport * as yup from 'yup';\nimport Alert from '@material-ui/lab/Alert';\nimport { costInsightsApiRef } from '../api';\nimport { MapLoadingToProps, useLoading } from './useLoading';\nimport { DefaultLoadingAction } from '../utils/loading';\nimport { Maybe } from '@backstage-community/plugin-cost-insights-common';\nimport { useApi } from '@backstage/core-plugin-api';\n\ntype BillingDateProviderLoadingProps = {\n dispatchLoadingBillingDate: (isLoading: boolean) => void;\n};\n\nconst mapLoadingToProps: MapLoadingToProps<BillingDateProviderLoadingProps> = ({\n dispatch,\n}) => ({\n dispatchLoadingBillingDate: (isLoading: boolean) =>\n dispatch({ [DefaultLoadingAction.LastCompleteBillingDate]: isLoading }),\n});\n\nexport type BillingDateContextProps = {\n lastCompleteBillingDate: string; // YYYY-MM-DD\n};\n\nexport const BillingDateContext = React.createContext<\n BillingDateContextProps | undefined\n>(undefined);\n\nexport const dateRegex: RegExp = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst dateFormatSchema = yup.string().matches(dateRegex, {\n message:\n 'Unsupported billing date format: ${value}. Date should be in YYYY-MM-DD format.',\n excludeEmptyString: true,\n});\n\nexport const BillingDateProvider = ({ children }: PropsWithChildren<{}>) => {\n const client = useApi(costInsightsApiRef);\n const [error, setError] = useState<Maybe<Error>>(null);\n const { dispatchLoadingBillingDate } = useLoading(mapLoadingToProps);\n\n const [lastCompleteBillingDate, setLastCompeteBillingDate] =\n useState<Maybe<string>>(null);\n\n useEffect(() => {\n dispatchLoadingBillingDate(true);\n\n async function getLastCompleteBillingDate() {\n try {\n const d = await client.getLastCompleteBillingDate();\n const validDate = await dateFormatSchema.validate(d);\n if (validDate) setLastCompeteBillingDate(validDate);\n } catch (e) {\n setError(e);\n } finally {\n dispatchLoadingBillingDate(false);\n }\n }\n\n getLastCompleteBillingDate();\n }, [client]); // eslint-disable-line react-hooks/exhaustive-deps\n\n if (error) {\n return <Alert severity=\"error\">{error.message}</Alert>;\n }\n\n if (!lastCompleteBillingDate) return null;\n\n return (\n <BillingDateContext.Provider\n value={\n {\n lastCompleteBillingDate: lastCompleteBillingDate,\n } as BillingDateContextProps\n }\n >\n {children}\n </BillingDateContext.Provider>\n );\n};\n\nexport function useLastCompleteBillingDate(): string {\n const context = useContext(BillingDateContext);\n return context ? context.lastCompleteBillingDate : assertNever();\n}\n\nfunction assertNever(): never {\n throw Error(\n 'Cannot use useLastCompleteBillingDate outside of BillingDateProvider',\n );\n}\n","/*\n * Copyright 2020 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 */\n\nimport React, {\n useState,\n forwardRef,\n ChangeEvent,\n FormEventHandler,\n} from 'react';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport { Alert, AlertFormProps } from '../types';\n\nexport type AlertAcceptFormProps = AlertFormProps<Alert, null>;\n\nexport const AlertAcceptForm = forwardRef<\n HTMLFormElement,\n AlertAcceptFormProps\n>(({ onSubmit, disableSubmit }, ref) => {\n const [checked, setChecked] = useState(false);\n\n const onFormSubmit: FormEventHandler = e => {\n e.preventDefault();\n onSubmit(null);\n };\n\n const onChecked = (_: ChangeEvent<HTMLInputElement>, isChecked: boolean) => {\n setChecked(isChecked);\n disableSubmit(!isChecked);\n };\n\n return (\n <form ref={ref} onSubmit={onFormSubmit}>\n <FormControl component=\"fieldset\" fullWidth>\n <FormControlLabel\n label=\"My team can commit to making this change soon, or has already.\"\n value={checked}\n control={\n <Checkbox color=\"primary\" checked={checked} onChange={onChecked} />\n }\n />\n </FormControl>\n </form>\n );\n});\n","/*\n * Copyright 2020 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 */\n\nimport React, {\n ChangeEvent,\n useEffect,\n useState,\n forwardRef,\n FormEventHandler,\n} from 'react';\nimport { DateTime } from 'luxon';\nimport Box from '@material-ui/core/Box';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport RadioGroup from '@material-ui/core/RadioGroup';\nimport Radio from '@material-ui/core/Radio';\nimport Typography from '@material-ui/core/Typography';\nimport {\n Alert,\n AlertFormProps,\n Duration,\n DEFAULT_DATE_FORMAT,\n AlertSnoozeFormData,\n AlertSnoozeOptions,\n} from '../types';\nimport { Maybe } from '@backstage-community/plugin-cost-insights-common';\nimport { useAlertDialogStyles as useStyles } from '../utils/styles';\nimport { intervalsOf } from '../utils/duration';\n\nexport type AlertSnoozeFormProps = AlertFormProps<Alert, AlertSnoozeFormData>;\n\nexport const AlertSnoozeForm = forwardRef<\n HTMLFormElement,\n AlertSnoozeFormProps\n>(({ onSubmit, disableSubmit }, ref) => {\n const classes = useStyles();\n const [duration, setDuration] = useState<Maybe<Duration>>(Duration.P7D);\n\n useEffect(() => disableSubmit(false), [disableSubmit]);\n\n const onFormSubmit: FormEventHandler = e => {\n e.preventDefault();\n if (duration) {\n const repeatInterval = 1;\n const today = DateTime.now().toFormat(DEFAULT_DATE_FORMAT);\n onSubmit({\n intervals: intervalsOf(duration, today, repeatInterval),\n });\n }\n };\n\n const onSnoozeDurationChange = (\n _: ChangeEvent<HTMLInputElement>,\n value: string,\n ) => {\n setDuration(value as Duration);\n };\n\n return (\n <form ref={ref} onSubmit={onFormSubmit}>\n <FormControl component=\"fieldset\" fullWidth>\n <Typography color=\"textPrimary\">\n <b>For how long?</b>\n </Typography>\n <Box mb={1}>\n <RadioGroup\n name=\"snooze-alert-options\"\n value={duration}\n onChange={onSnoozeDurationChange}\n >\n {AlertSnoozeOptions.map(option => (\n <FormControlLabel\n key={`snooze-alert-option-${option.duration}`}\n label={option.label}\n value={option.duration}\n control={<Radio className={classes.radio} />}\n />\n ))}\n </RadioGroup>\n </Box>\n </FormControl>\n </form>\n );\n});\n","/*\n * Copyright 2020 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 */\n\nimport React, {\n ChangeEvent,\n useEffect,\n useState,\n forwardRef,\n FormEventHandler,\n} from 'react';\nimport Box from '@material-ui/core/Box';\nimport Collapse from '@material-ui/core/Collapse';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport TextField from '@material-ui/core/TextField';\nimport Typography from '@material-ui/core/Typography';\nimport Radio from '@material-ui/core/Radio';\nimport RadioGroup from '@material-ui/core/RadioGroup';\nimport {\n Alert,\n AlertFormProps,\n AlertDismissReason,\n AlertDismissOptions,\n AlertDismissFormData,\n} from '../types';\nimport { Maybe } from '@backstage-community/plugin-cost-insights-common';\nimport { useAlertDialogStyles as useStyles } from '../utils/styles';\n\nexport type AlertDismissFormProps = AlertFormProps<Alert, AlertDismissFormData>;\n\nexport const AlertDismissForm = forwardRef<\n HTMLFormElement,\n AlertDismissFormProps\n>(({ onSubmit, disableSubmit }, ref) => {\n const classes = useStyles();\n const [other, setOther] = useState<Maybe<string>>(null);\n const [feedback, setFeedback] = useState<Maybe<string>>(null);\n const [reason, setReason] = useState<AlertDismissReason>(\n AlertDismissReason.Resolved,\n );\n\n const onFormSubmit: FormEventHandler = e => {\n e.preventDefault();\n if (reason) {\n onSubmit({\n other: other,\n reason: reason,\n feedback: feedback,\n });\n }\n };\n\n const onReasonChange = (_: ChangeEvent<HTMLInputElement>, value: string) => {\n if (other) {\n setOther(null);\n }\n setReason(value as AlertDismissReason);\n };\n\n const onOtherChange = (e: ChangeEvent<HTMLInputElement>) => {\n return e.target.value\n ? setOther(e.target.value as AlertDismissReason)\n : setOther(null);\n };\n\n const onFeedbackChange = (e: ChangeEvent<HTMLInputElement>) => {\n return e.target.value\n ? setFeedback(e.target.value as AlertDismissReason)\n : setFeedback(null);\n };\n\n useEffect(() => {\n function validateDismissForm() {\n if (reason === AlertDismissReason.Other) {\n if (other) {\n disableSubmit(false);\n } else {\n disableSubmit(true);\n }\n } else if (reason) {\n disableSubmit(false);\n } else {\n disableSubmit(true);\n }\n }\n\n validateDismissForm();\n }, [reason, other, disableSubmit]);\n\n return (\n <form ref={ref} onSubmit={onFormSubmit}>\n <FormControl component=\"fieldset\" fullWidth>\n <Typography color=\"textPrimary\">\n <b>Reason for dismissing?</b>\n </Typography>\n <Box mb={1}>\n <RadioGroup\n name=\"dismiss-alert-reasons\"\n value={reason}\n onChange={onReasonChange}\n >\n {AlertDismissOptions.map(option => (\n <FormControlLabel\n key={`dismiss-alert-option-${option.reason}`}\n label={option.label}\n value={option.reason}\n control={<Radio className={classes.radio} />}\n />\n ))}\n </RadioGroup>\n <Collapse in={reason === AlertDismissReason.Other}>\n <Box ml={4}>\n <TextField\n id=\"dismiss-alert-option-other\"\n variant=\"outlined\"\n multiline\n fullWidth\n rows={4}\n value={other ?? ''}\n onChange={onOtherChange}\n />\n </Box>\n </Collapse>\n </Box>\n <Typography gutterBottom>\n <b>Any other feedback you can provide?</b>\n </Typography>\n <TextField\n id=\"dismiss-alert-feedback\"\n variant=\"outlined\"\n multiline\n rows={4}\n fullWidth\n value={feedback ?? ''}\n onChange={onFeedbackChange}\n />\n </FormControl>\n </form>\n );\n});\n","/*\n * Copyright 2020 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 */\n\nimport { Alert, AlertForm, AlertStatus } from '../types';\nimport { Maybe } from '@backstage-community/plugin-cost-insights-common';\nimport { AlertAcceptForm, AlertDismissForm, AlertSnoozeForm } from '../forms';\n\nconst createAlertHandler = (status?: AlertStatus) => (alert: Alert) =>\n alert.status === status;\nexport const isAlertActive = (alert: Alert) => !hasProperty(alert, 'status');\nexport const isAlertSnoozed = createAlertHandler(AlertStatus.Snoozed);\nexport const isAlertAccepted = createAlertHandler(AlertStatus.Accepted);\nexport const isAlertDismissed = createAlertHandler(AlertStatus.Dismissed);\n\nconst createStatusHandler = (status: AlertStatus) => (s: Maybe<AlertStatus>) =>\n s === status;\nexport const isStatusSnoozed = createStatusHandler(AlertStatus.Snoozed);\nexport const isStatusAccepted = createStatusHandler(AlertStatus.Accepted);\nexport const isStatusDismissed = createStatusHandler(AlertStatus.Dismissed);\n\nconst createAlertEventHandler =\n (onEvent: 'onSnoozed' | 'onAccepted' | 'onDismissed') =>\n (alert: Maybe<Alert>): boolean =>\n hasProperty(alert, onEvent);\nexport const isSnoozeEnabled = createAlertEventHandler('onSnoozed');\nexport const isAcceptEnabled = createAlertEventHandler('onAccepted');\nexport const isDismissEnabled = createAlertEventHandler('onDismissed');\n\nconst createFormEnabledHandler =\n (Form: 'SnoozeForm' | 'AcceptForm' | 'DismissForm') =>\n (alert: Maybe<Alert>): boolean => {\n if (!alert) return false;\n if (alert[Form] === null) return false;\n switch (Form) {\n case 'SnoozeForm':\n return isSnoozeEnabled(alert);\n case 'AcceptForm':\n return isAcceptEnabled(alert);\n case 'DismissForm':\n return isDismissEnabled(alert);\n default:\n return false;\n }\n };\nexport const isSnoozeFormEnabled = createFormEnabledHandler('SnoozeForm');\nexport const isAcceptFormEnabled = createFormEnabledHandler('AcceptForm');\nexport const isDismissFormEnabled = createFormEnabledHandler('DismissForm');\n\n/**\n * Utility for determining if a form is disabled.\n * When a form is disabled, the dialog button's type should convert from submit to button.\n * @param alert\n * @param status\n */\nexport const isFormDisabled = (\n alert: Maybe<Alert>,\n status: Maybe<AlertStatus>,\n): boolean => {\n switch (status) {\n case AlertStatus.Snoozed:\n return alert?.SnoozeForm === null;\n case AlertStatus.Accepted:\n return alert?.AcceptForm === null;\n case AlertStatus.Dismissed:\n return alert?.DismissForm === null;\n default:\n return false;\n }\n};\n\nexport function formOf(\n alert: Maybe<Alert>,\n status: Maybe<AlertStatus>,\n): Maybe<AlertForm> {\n switch (status) {\n case AlertStatus.Snoozed: {\n const SnoozeForm = alert?.SnoozeForm ?? AlertSnoozeForm;\n return isSnoozeFormEnabled(alert) ? SnoozeForm : null;\n }\n case AlertStatus.Accepted: {\n const AcceptForm = alert?.AcceptForm ?? AlertAcceptForm;\n return isAcceptFormEnabled(alert) ? AcceptForm : null;\n }\n case AlertStatus.Dismissed: {\n const DismissForm = alert?.DismissForm ?? AlertDismissForm;\n return isDismissFormEnabled(alert) ? DismissForm : null;\n }\n default:\n return null;\n }\n}\n\n/**\n * Utility for choosing from a fixed set of values for a given alert status.\n * @param status\n * @param values\n */\nexport function choose<T>(\n status: Maybe<AlertStatus>,\n values: [T, T, T],\n none: T,\n): T {\n switch (status) {\n case AlertStatus.Snoozed:\n return values[0];\n case AlertStatus.Accepted:\n return values[1];\n case AlertStatus.Dismissed:\n return values[2];\n default:\n return none;\n }\n}\n\nexport function hasProperty(alert: Maybe<Alert>, prop: keyof Alert): boolean {\n return prop in (alert ?? {});\n}\n\nexport const sumOfAllAlerts = (sum: number, alerts: Alert[]) =>\n sum + alerts.length;\n","/*\n * Copyright 2020 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 */\n\nimport React, { PropsWithChildren } from 'react';\nimport {\n ThemeProvider,\n createTheme as createMuiTheme,\n} from '@material-ui/core/styles';\nimport { Theme } from '@material-ui/core/styles';\nimport {\n costInsightsDarkTheme,\n costInsightsLightTheme,\n} from '../../utils/styles';\nimport { CostInsightsTheme } from '../../types';\n\nexport const CostInsightsThemeProvider = ({\n children,\n}: PropsWithChildren<{}>) => {\n return (\n <ThemeProvider\n theme={(theme: Theme) =>\n createMuiTheme({\n ...theme,\n palette: {\n ...theme.palette,\n ...(theme.palette.type === 'dark'\n ? costInsightsDarkTheme.palette\n : costInsightsLightTheme.palette),\n },\n }) as CostInsightsTheme\n }\n >\n {children}\n </ThemeProvider>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { PropsWithChildren } from 'react';\nimport Box from '@material-ui/core/Box';\nimport Button from '@material-ui/core/Button';\nimport Container from '@material-ui/core/Container';\nimport { makeStyles } from '@material-ui/core/styles';\nimport ChevronLeftIcon from '@material-ui/icons/ChevronLeft';\nimport { CostInsightsThemeProvider } from '../CostInsightsPage/CostInsightsThemeProvider';\nimport { ConfigProvider, CurrencyProvider } from '../../hooks';\nimport { Header, Page } from '@backstage/core-components';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n gridArea: 'pageContent',\n padding: theme.spacing(4),\n },\n}));\n\ntype AlertInstructionsLayoutProps = {\n title: string;\n};\n\nexport const AlertInstructionsLayout = ({\n title,\n children,\n}: PropsWithChildren<AlertInstructionsLayoutProps>) => {\n const classes = useStyles();\n return (\n <CostInsightsThemeProvider>\n <ConfigProvider>\n <CurrencyProvider>\n <Page themeId=\"tool\">\n <Header\n title=\"Cost Insights\"\n pageTitleOverride={title}\n type=\"Tool\"\n />\n <Container maxWidth=\"md\" disableGutters className={classes.root}>\n <Box mb={3}>\n <Button\n variant=\"outlined\"\n startIcon={<ChevronLeftIcon />}\n href=\"/cost-insights\"\n >\n Back to Cost Insights\n </Button>\n </Box>\n {children}\n </Container>\n </Page>\n </CurrencyProvider>\n </ConfigProvider>\n </CostInsightsThemeProvider>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { PropsWithChildren } from 'react';\nimport Box from '@material-ui/core/Box';\nimport Typography from '@material-ui/core/Typography';\nimport { useBarChartLabelStyles } from '../../utils/styles';\n\ntype BarChartLabelProps = {\n x: number;\n y: number;\n height: number;\n width: number;\n details?: JSX.Element;\n};\n\nexport const BarChartLabel = ({\n x,\n y,\n height,\n width,\n details,\n children,\n}: PropsWithChildren<BarChartLabelProps>) => {\n const classes = useBarChartLabelStyles();\n const translateX = width * -0.5;\n\n return (\n <foreignObject\n className={classes.foreignObject}\n style={{ transform: `translateX(${translateX}px)` }}\n x={x}\n y={y}\n height={height}\n width={width}\n >\n <Box display=\"flex\" flexDirection=\"column\" justifyContent=\"center\">\n <Typography className={classes.label} gutterBottom>\n {children}\n </Typography>\n {details}\n </Box>\n </foreignObject>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport { BarChartLabel } from './BarChartLabel';\n\ntype BarChartTickProps = {\n x: number;\n y: number;\n height: number;\n width: number;\n payload: {\n value: any;\n };\n visibleTicksCount: number;\n details?: JSX.Element;\n};\n\nexport const BarChartTick = ({\n x,\n y,\n height,\n width,\n payload,\n visibleTicksCount,\n details,\n}: BarChartTickProps) => {\n const gutterWidth = 5;\n const labelWidth = width / visibleTicksCount - gutterWidth * 2;\n return (\n <BarChartLabel\n x={x}\n y={y}\n height={height}\n width={labelWidth}\n details={details}\n >\n {!payload.value ? 'Unlabeled' : payload.value}\n </BarChartLabel>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { forwardRef, PropsWithChildren, Ref } from 'react';\nimport ButtonBase, { ButtonBaseProps } from '@material-ui/core/ButtonBase';\nimport { useBarChartStepperButtonStyles as useStyles } from '../../utils/styles';\n\ninterface BarChartStepperButtonProps extends ButtonBaseProps {\n name: string;\n}\n\nexport const BarChartStepperButton = forwardRef(\n (\n {\n name,\n children,\n ...buttonBaseProps\n }: PropsWithChildren<BarChartStepperButtonProps>,\n ref: Ref<HTMLButtonElement>,\n ) => {\n const classes = useStyles();\n return (\n <ButtonBase\n ref={ref}\n classes={classes}\n disableRipple\n data-testid={`bar-chart-stepper-button-${name}`}\n {...buttonBaseProps}\n >\n {children}\n </ButtonBase>\n );\n },\n);\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport ButtonBase from '@material-ui/core/ButtonBase';\nimport { useBarChartStepperStyles as useStyles } from '../../utils/styles';\n\nexport type BarChartStepsProps = {\n steps: number;\n activeStep: number;\n onClick: (index: number) => void;\n};\n\nexport const BarChartSteps = ({\n steps,\n activeStep,\n onClick,\n}: BarChartStepsProps) => {\n const classes = useStyles();\n const handleOnClick =\n (index: number) =>\n (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {\n event.preventDefault();\n onClick(index);\n };\n\n return (\n <div className={classes.steps}>\n {[...new Array(steps)].map((_, index) => (\n <ButtonBase key={index} centerRipple onClick={handleOnClick(index)}>\n <div\n data-testid=\"bar-chart-step\"\n className={`${classes.step} ${\n index === activeStep ? classes.stepActive : ''\n }`}\n />\n </ButtonBase>\n ))}\n </div>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { useEffect, useState } from 'react';\nimport Paper from '@material-ui/core/Paper';\nimport Slide from '@material-ui/core/Slide';\nimport ChevronLeftIcon from '@material-ui/icons/ChevronLeft';\nimport ChevronRightIcon from '@material-ui/icons/ChevronRight';\nimport { BarChartStepperButton } from './BarChartStepperButton';\nimport { BarChartSteps } from './BarChartSteps';\nimport { useBarChartStepperStyles } from '../../utils/styles';\n\ntype BarChartStepperProps = {\n disableScroll: boolean;\n steps: number;\n onChange: (activeStep: number) => void;\n};\n\nexport const BarChartStepper = ({\n steps,\n disableScroll,\n onChange,\n}: BarChartStepperProps) => {\n const classes = useBarChartStepperStyles();\n const [activeStep, setActiveStep] = useState(0);\n\n /*\n * This calc determines how many active steps to display in the stepper.\n * If the chart is displaying a large amount of resources,\n * the total dots are truncated to 10. As the user clicks forward,\n * eventually, there might be resources \"left over\" in excess of the ten dot limit.\n * Once the user has reached that threshold, the difference should appear constant\n * as the user clicks through the remaining resources and no extra dots should be displayed.\n */\n\n const diff = steps % 10;\n const stepsRemaining = steps - activeStep <= diff ? diff : steps;\n const displayedStep = activeStep % 10;\n\n useEffect(() => {\n onChange(activeStep);\n }, [activeStep, onChange]);\n\n const handleNext = () => {\n setActiveStep(prevStep => prevStep + 1);\n };\n\n const handleBack = () => {\n setActiveStep(prevStep => prevStep - 1);\n };\n\n const handleClick = (index: number) => {\n setActiveStep(prevStep => {\n const offset = index - (prevStep % 10);\n return prevStep + offset;\n });\n };\n\n return (\n <Paper\n data-testid=\"bar-chart-stepper\"\n square\n elevation={0}\n className={classes.paper}\n >\n <Slide\n direction=\"right\"\n in={!disableScroll && activeStep !== 0}\n mountOnEnter\n unmountOnExit\n >\n <BarChartStepperButton\n name=\"back\"\n className={classes.backButton}\n onClick={handleBack}\n >\n <ChevronLeftIcon />\n </BarChartStepperButton>\n </Slide>\n <BarChartSteps\n steps={Math.min(10, stepsRemaining)}\n activeStep={displayedStep}\n onClick={handleClick}\n />\n <Slide\n direction=\"left\"\n in={!disableScroll && activeStep < steps - 1}\n mountOnEnter\n unmountOnExit\n >\n <BarChartStepperButton\n name=\"next\"\n className={classes.nextButton}\n onClick={handleNext}\n >\n <ChevronRightIcon />\n </BarChartStepperButton>\n </Slide>\n </Paper>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { ReactNode, PropsWithChildren } from 'react';\nimport classnames from 'classnames';\nimport Box from '@material-ui/core/Box';\nimport Divider from '@material-ui/core/Divider';\nimport Typography from '@material-ui/core/Typography';\nimport { useTooltipStyles as useStyles } from '../../utils/styles';\n\n/** @public */\nexport type BarChartTooltipProps = {\n title: string;\n content?: ReactNode | string;\n subtitle?: ReactNode;\n topRight?: ReactNode;\n actions?: ReactNode;\n};\n\n/** @public */\nexport const BarChartTooltip = (\n props: PropsWithChildren<BarChartTooltipProps>,\n) => {\n const { title, content, subtitle, topRight, actions, children } = props;\n\n const classes = useStyles();\n const titleClassName = classnames(classes.truncate, {\n [classes.maxWidth]: topRight === undefined,\n });\n\n return (\n <Box className={classes.tooltip} display=\"flex\" flexDirection=\"column\">\n <Box\n display=\"flex\"\n flexDirection=\"row\"\n justifyContent=\"space-between\"\n alignItems=\"baseline\"\n px={2}\n pt={2}\n >\n <Box display=\"flex\" flexDirection=\"column\">\n <Typography className={titleClassName} variant=\"h6\">\n {title}\n </Typography>\n {subtitle && (\n <Typography className={classes.subtitle} variant=\"subtitle1\">\n {subtitle}\n </Typography>\n )}\n </Box>\n {topRight && <Box ml={2}>{topRight}</Box>}\n </Box>\n {content && (\n <Box px={2} pt={2} className={classes.maxWidth}>\n <Typography variant=\"body1\" paragraph>\n {content}\n </Typography>\n </Box>\n )}\n <Box display=\"flex\" flexDirection=\"column\" p={2}>\n {children}\n </Box>\n {actions && (\n <>\n <Divider className={classes.divider} variant=\"fullWidth\" />\n <Box display=\"flex\" flexDirection=\"column\" p={2}>\n {actions}\n </Box>\n </>\n )}\n </Box>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport Box from '@material-ui/core/Box';\nimport Typography from '@material-ui/core/Typography';\nimport LensIcon from '@material-ui/icons/Lens';\nimport { useTooltipStyles as useStyles } from '../../utils/styles';\n\n/** @public */\nexport type TooltipItem = {\n fill: string;\n label?: string;\n value?: string;\n};\n\n/** @public */\nexport type BarChartTooltipItemProps = {\n item: TooltipItem;\n};\n\n/** @public */\nexport const BarChartTooltipItem = (props: BarChartTooltipItemProps) => {\n const { item } = props;\n\n const classes = useStyles();\n\n return (\n <Box\n display=\"flex\"\n alignItems=\"center\"\n justifyContent=\"space-between\"\n minHeight={25}\n >\n <Box display=\"flex\" alignContent=\"center\" marginRight=\".5em\">\n <Box display=\"flex\" alignItems=\"center\" marginRight=\".5em\">\n <LensIcon className={classes.lensIcon} style={{ fill: item.fill }} />\n </Box>\n <Typography>{item.label}</Typography>\n </Box>\n <Typography display=\"block\">{item.value}</Typography>\n </Box>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport { DateTime, Duration as LuxonDuration } from 'luxon';\nimport pluralize from 'pluralize';\nimport { Duration } from '../types';\nimport { ChangeStatistic } from '@backstage-community/plugin-cost-insights-common';\nimport { inclusiveEndDateOf, inclusiveStartDateOf } from './duration';\nimport { notEmpty } from './assert';\n\nexport type Period = {\n periodStart: string;\n periodEnd: string;\n};\n\nexport const currencyFormatter = (currency: Intl.NumberFormat) => {\n const options = currency.resolvedOptions();\n\n return new Intl.NumberFormat(options.locale, {\n style: 'currency',\n currency: options.currency,\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n });\n};\n\nexport const lengthyCurrencyFormatter = (currency: Intl.NumberFormat) => {\n const options = currency.resolvedOptions();\n\n return new Intl.NumberFormat(options.locale, {\n style: 'currency',\n currency: options.currency,\n minimumFractionDigits: 0,\n minimumSignificantDigits: 2,\n maximumSignificantDigits: 2,\n });\n};\n\nexport const numberFormatter = new Intl.NumberFormat('en-US', {\n minimumFractionDigits: 0,\n maximumFractionDigits: 0,\n});\n\nexport const monthFormatter = new Intl.DateTimeFormat('en-US', {\n timeZone: 'UTC',\n month: 'long',\n year: 'numeric',\n});\n\nexport const dateFormatter = new Intl.DateTimeFormat('en-US', {\n timeZone: 'UTC',\n day: 'numeric',\n month: 'short',\n});\n\nexport const monthOf = (date: string): string => {\n return monthFormatter.format(Date.parse(date));\n};\n\nexport const quarterOf = (date: string): string => {\n // Supports formatting yyyy-LL-dd and yyyy-'Q'q returned in alerts\n const d = DateTime.fromISO(date).isValid\n ? DateTime.fromISO(date)\n : DateTime.fromFormat(date, \"yyyy-'Q'q\");\n return d.toFormat(\"'Q'q yyyy\");\n};\n\nexport function formatCurrency(amount: number, currency?: string): string {\n const n = Math.round(amount);\n const numString = numberFormatter.format(n);\n\n return currency ? `${numString} ${pluralize(currency, n)}` : numString;\n}\n\nexport function formatChange(\n change: ChangeStatistic,\n options?: { absolute: boolean },\n): string {\n if (notEmpty(change.ratio)) {\n return formatPercent(\n options?.absolute ? Math.abs(change.ratio) : change.ratio,\n );\n }\n if (options?.absolute) {\n return '∞';\n }\n return change.amount >= 0 ? '∞' : '-∞';\n}\n\nexport function formatPercent(n: number): string {\n // Number.toFixed shows scientific notation for extreme numbers\n if (isNaN(n) || Math.abs(n) < 0.01) {\n return '0%';\n }\n\n if (Math.abs(n) > 10) {\n return `>${n < 0 ? '-' : ''}1000%`;\n }\n\n return `${(n * 100).toFixed(0)}%`;\n}\n\nexport function formatLastTwoLookaheadQuarters(inclusiveEndDate: string) {\n const start = DateTime.fromISO(\n inclusiveStartDateOf(Duration.P3M, inclusiveEndDate),\n ).toFormat(\"'Q'q yyyy\");\n const end = DateTime.fromISO(\n inclusiveEndDateOf(Duration.P3M, inclusiveEndDate),\n ).toFormat(\"'Q'q yyyy\");\n return `${start} vs ${end}`;\n}\n\nconst formatRelativePeriod = (\n duration: Duration,\n date: string,\n isEndDate: boolean,\n): string => {\n const periodStart = isEndDate ? inclusiveStartDateOf(duration, date) : date;\n const periodEnd = isEndDate ? date : inclusiveEndDateOf(duration, date);\n const days = LuxonDuration.fromISO(duration).days;\n if (![periodStart, periodEnd].includes(date)) {\n throw new Error(`Invalid relative date ${date} for duration ${duration}`);\n }\n return date === periodStart ? `First ${days} Days` : `Last ${days} Days`;\n};\n\nexport function formatPeriod(\n duration: Duration,\n date: string,\n isEndDate: boolean,\n) {\n switch (duration) {\n case Duration.P3M:\n return quarterOf(\n isEndDate\n ? inclusiveEndDateOf(duration, date)\n : inclusiveStartDateOf(duration, date),\n );\n default:\n return formatRelativePeriod(duration, date, isEndDate);\n }\n}\n","/*\n * Copyright 2020 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 { ResourceData } from '../types';\nimport { DateAggregation } from '@backstage-community/plugin-cost-insights-common';\nimport { ProductState } from './loading';\n\nexport const aggregationSort = (\n a: DateAggregation,\n b: DateAggregation,\n): number => a.date.localeCompare(b.date);\n\nexport const resourceSort = (a: ResourceData, b: ResourceData) =>\n b.previous + b.current - (a.previous + a.current);\n\nexport function totalAggregationSort(a: ProductState, b: ProductState): number {\n const [prevA, currA] = a.entity?.aggregation ?? [0, 0];\n const [prevB, currB] = b.entity?.aggregation ?? [0, 0];\n return prevB + currB - (prevA + currA);\n}\n","/*\n * Copyright 2020 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 */\n\nimport { TooltipProps } from 'recharts';\nimport { Payload } from 'recharts/types/component/DefaultTooltipContent';\nimport { AlertCost, DataKey, ResourceData } from '../types';\nimport { Entity } from '@backstage-community/plugin-cost-insights-common';\nimport {\n currencyFormatter,\n dateFormatter,\n lengthyCurrencyFormatter,\n} from './formatters';\n\nexport const formatGraphValue =\n (baseCurrency: Intl.NumberFormat) =>\n (value: number, _index: number, format?: string) => {\n if (format === 'number') {\n return value.toLocaleString();\n }\n\n if (value < 1) {\n return lengthyCurrencyFormatter(baseCurrency).format(value);\n }\n\n return currencyFormatter(baseCurrency).format(value);\n };\n\nexport const overviewGraphTickFormatter = (millis: string | number) =>\n typeof millis === 'number' ? dateFormatter.format(millis) : millis;\n\nexport const tooltipItemOf =\n (baseCurrency: Intl.NumberFormat) => (payload: Payload<string, string>) => {\n const value =\n payload.value && !isNaN(Number(payload.value))\n ? baseCurrency.format(Number(payload.value))\n : payload.value;\n const fill = payload.color as string;\n\n switch (payload.dataKey) {\n case DataKey.Current:\n case DataKey.Previous:\n return {\n label: payload.name,\n value: value,\n fill: fill,\n };\n default:\n return null;\n }\n };\n\nexport const resourceOf = (entity: Entity | AlertCost): ResourceData => ({\n name: entity.id,\n previous: entity.aggregation[0],\n current: entity.aggregation[1],\n});\n\nexport const titleOf = (label?: string | number) => {\n return label ? String(label) : 'Unlabeled';\n};\n\nexport const isInvalid = ({ label, payload }: TooltipProps<string, string>) => {\n // null labels are empty strings, which are valid\n return label === undefined || !payload || !payload.length;\n};\n\nexport const isLabeled = (data?: Record<'activeLabel', string | undefined>) => {\n return data?.activeLabel && data?.activeLabel !== '';\n};\n\nexport const isUnlabeled = (\n data?: Record<'activeLabel', string | undefined>,\n) => {\n return data?.activeLabel === '';\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { useState, useCallback } from 'react';\nimport {\n Bar,\n BarChart as RechartsBarChart,\n CartesianGrid,\n Tooltip as RechartsTooltip,\n ResponsiveContainer,\n XAxis,\n YAxis,\n} from 'recharts';\nimport Box from '@material-ui/core/Box';\nimport { useTheme } from '@material-ui/core/styles';\nimport { BarChartTick } from './BarChartTick';\nimport { BarChartStepper } from './BarChartStepper';\nimport { BarChartTooltip } from './BarChartTooltip';\nimport { BarChartTooltipItem } from './BarChartTooltipItem';\nimport { currencyFormatter } from '../../utils/formatters';\nimport {\n ResourceData,\n DataKey,\n CostInsightsTheme,\n BarChartOptions,\n} from '../../types';\nimport { notEmpty } from '../../utils/assert';\nimport { useBarChartStyles } from '../../utils/styles';\nimport { resourceSort } from '../../utils/sort';\nimport { isInvalid, titleOf, tooltipItemOf } from '../../utils/graphs';\nimport { TooltipRenderer } from '../../types';\nimport { useConfig } from '../../hooks';\n\nconst defaultTooltip = (baseCurrency: Intl.NumberFormat) => {\n const tooltip: TooltipRenderer = ({ label, payload = [] }) => {\n if (isInvalid({ label, payload })) return null;\n\n const title = titleOf(label);\n const items = payload.map(tooltipItemOf(baseCurrency)).filter(notEmpty);\n return (\n <BarChartTooltip title={title}>\n {items.map((item, index) => (\n <BarChartTooltipItem key={`${item.label}-${index}`} item={item} />\n ))}\n </BarChartTooltip>\n );\n };\n return tooltip;\n};\n\n/** @public */\nexport type BarChartProps = {\n resources: ResourceData[];\n responsive?: boolean;\n displayAmount?: number;\n options?: Partial<BarChartOptions>;\n tooltip?: TooltipRenderer;\n onClick?: (...args: any[]) => void;\n onMouseMove?: (...args: any[]) => void;\n};\n\n/** @public */\nexport const BarChart = (props: BarChartProps) => {\n const { baseCurrency } = useConfig();\n\n const {\n resources,\n responsive = true,\n displayAmount = 6,\n options = {},\n tooltip = defaultTooltip(baseCurrency),\n onClick,\n onMouseMove,\n } = props;\n\n const theme = useTheme<CostInsightsTheme>();\n const styles = useBarChartStyles(theme);\n const [activeChart, setActiveChart] = useState(false);\n const [stepWindow, setStepWindow] = useState(() => [0, displayAmount]);\n\n const data = Object.assign(\n {\n previousFill: theme.palette.lightBlue,\n currentFill: theme.palette.darkBlue,\n previousName: 'Previous',\n currentName: 'Current',\n },\n options,\n );\n\n const [stepStart, stepEnd] = stepWindow;\n const steps = Math.ceil(resources.length / displayAmount);\n const disableStepper = resources.length <= displayAmount;\n\n const sortedResources = resources\n .sort(resourceSort)\n .slice(stepStart, stepEnd);\n\n // Pin the domain to the largest value in the series.\n // Intentionally redundant - This could simply be derived from the first element in the already sorted list,\n // but that may not be the case in the future when custom sorting is implemented.\n const globalResourcesMax = resources.reduce(\n (max, r: ResourceData) => Math.max(max, r.current, r.previous),\n 0,\n );\n\n const onStepChange = useCallback(\n (activeStep: number) => {\n const start = activeStep * displayAmount;\n const end = start + displayAmount;\n if (end > resources.length) {\n setStepWindow([start, resources.length]);\n } else {\n setStepWindow([start, end]);\n }\n },\n [setStepWindow, resources, displayAmount],\n );\n\n return (\n <Box\n position=\"relative\"\n onMouseLeave={() => setActiveChart(false)}\n onMouseEnter={() => setActiveChart(true)}\n data-testid=\"bar-chart-wrapper\"\n >\n {/* Setting fixed values for height and width generates a console warning in testing but enables ResponsiveContainer to render its children. */}\n <ResponsiveContainer\n height={styles.container.height}\n width={responsive ? '100%' : styles.container.width}\n >\n <RechartsBarChart\n style={{ cursor: onClick ? 'pointer' : null }}\n onClick={onClick}\n onMouseMove={onMouseMove}\n data={sortedResources}\n margin={styles.barChart.margin}\n barSize={45}\n data-testid=\"bar-chart\"\n >\n {tooltip && (\n <RechartsTooltip\n filterNull\n cursor={styles.cursor}\n animationDuration={100}\n content={tooltip}\n />\n )}\n <CartesianGrid\n vertical={false}\n stroke={styles.cartesianGrid.stroke}\n />\n <XAxis\n dataKey={DataKey.Name}\n tickLine={false}\n interval={0}\n height={styles.xAxis.height}\n tick={BarChartTick}\n />\n <YAxis\n tickFormatter={currencyFormatter(baseCurrency).format}\n domain={[() => 0, globalResourcesMax]}\n tick={styles.axis}\n />\n <Bar\n dataKey={DataKey.Previous}\n name={data.previousName}\n fill={data.previousFill}\n isAnimationActive={false}\n />\n <Bar\n dataKey={DataKey.Current}\n name={data.currentName}\n fill={data.currentFill}\n isAnimationActive={false}\n />\n </RechartsBarChart>\n </ResponsiveContainer>\n {!disableStepper && (\n <BarChartStepper\n steps={steps}\n disableScroll={!activeChart}\n onChange={onStepChange}\n />\n )}\n </Box>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { PropsWithChildren } from 'react';\nimport Box from '@material-ui/core/Box';\nimport Typography from '@material-ui/core/Typography';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport LensIcon from '@material-ui/icons/Lens';\nimport HelpOutlineOutlinedIcon from '@material-ui/icons/HelpOutlineOutlined';\nimport { useCostGrowthLegendStyles } from '../../utils/styles';\n\n/** @public */\nexport type LegendItemProps = {\n title: string;\n tooltipText?: string;\n markerColor?: string;\n};\n\n/** @public */\nexport const LegendItem = (props: PropsWithChildren<LegendItemProps>) => {\n const { title, tooltipText, markerColor, children } = props;\n\n const classes = useCostGrowthLegendStyles();\n\n return (\n <Box display=\"flex\" flexDirection=\"column\">\n <Box\n minHeight={25}\n display=\"flex\"\n flexDirection=\"row\"\n alignItems=\"center\"\n >\n {markerColor && (\n <div className={classes.marker}>\n <LensIcon style={{ fontSize: '1em', fill: markerColor }} />\n </div>\n )}\n <Typography className={classes.title} variant=\"overline\">\n {title}\n </Typography>\n {tooltipText && (\n <Tooltip\n classes={{ tooltip: classes.tooltip }}\n title={\n <Typography className={classes.tooltipText}>\n {tooltipText}\n </Typography>\n }\n placement=\"top-start\"\n >\n <Typography\n component=\"span\"\n role=\"img\"\n aria-label=\"help\"\n className={classes.helpIcon}\n >\n <HelpOutlineOutlinedIcon fontSize=\"small\" />\n </Typography>\n </Tooltip>\n )}\n </Box>\n <Box marginLeft={markerColor ? '1.5em' : 0}>\n <Typography className={classes.h5} variant=\"h5\">\n {children}\n </Typography>\n </Box>\n </Box>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { PropsWithChildren } from 'react';\nimport Box from '@material-ui/core/Box';\nimport { useTheme } from '@material-ui/core/styles';\nimport { LegendItem } from '../LegendItem';\nimport { currencyFormatter } from '../../utils/formatters';\nimport { CostInsightsTheme } from '../../types';\nimport { useBarChartLayoutStyles as useStyles } from '../../utils/styles';\nimport { useConfig } from '../../hooks';\n\n/** @public */\nexport type BarChartLegendOptions = {\n previousName: string;\n previousFill: string;\n currentName: string;\n currentFill: string;\n hideMarker?: boolean;\n};\n\n/** @public */\nexport type BarChartLegendProps = {\n costStart: number;\n costEnd: number;\n options?: Partial<BarChartLegendOptions>;\n};\n\n/** @public */\nexport const BarChartLegend = (\n props: PropsWithChildren<BarChartLegendProps>,\n) => {\n const { costStart, costEnd, options = {}, children } = props;\n\n const theme = useTheme<CostInsightsTheme>();\n const classes = useStyles();\n const { baseCurrency } = useConfig();\n\n const data = Object.assign(\n {\n previousName: 'Previous',\n previousFill: theme.palette.lightBlue,\n currentName: 'Current',\n currentFill: theme.palette.darkBlue,\n },\n options,\n );\n\n return (\n <Box className={classes.legend} display=\"flex\" flexDirection=\"row\">\n <Box marginRight={2}>\n <LegendItem\n title={data.previousName}\n markerColor={options.hideMarker ? undefined : data.previousFill}\n >\n {currencyFormatter(baseCurrency).format(costStart)}\n </LegendItem>\n </Box>\n <Box marginRight={2}>\n <LegendItem\n title={data.currentName}\n markerColor={options.hideMarker ? undefined : data.currentFill}\n >\n {currencyFormatter(baseCurrency).format(costEnd)}\n </LegendItem>\n </Box>\n {children}\n </Box>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport { ChangeThreshold, GrowthType, Duration } from '../types';\nimport {\n Cost,\n ChangeStatistic,\n MetricData,\n DateAggregation,\n} from '@backstage-community/plugin-cost-insights-common';\nimport { DateTime, Duration as LuxonDuration } from 'luxon';\nimport { inclusiveStartDateOf } from './duration';\nimport { notEmpty } from './assert';\n\n// Used for displaying status colors\nexport function growthOf(\n change: ChangeStatistic,\n engineerThreshold: number,\n): GrowthType {\n const exceedsEngineerThreshold = Math.abs(change.amount) >= engineerThreshold;\n\n if (notEmpty(change.ratio)) {\n if (exceedsEngineerThreshold && change.ratio >= ChangeThreshold.upper) {\n return GrowthType.Excess;\n }\n\n if (exceedsEngineerThreshold && change.ratio <= ChangeThreshold.lower) {\n return GrowthType.Savings;\n }\n } else {\n if (exceedsEngineerThreshold && change.amount > 0) {\n return GrowthType.Excess;\n }\n if (exceedsEngineerThreshold && change.amount < 0) {\n return GrowthType.Savings;\n }\n }\n\n return GrowthType.Negligible;\n}\n\n// Used by <CostOverviewCard /> for displaying engineer totals\nexport function getComparedChange(\n dailyCost: Cost,\n metricData: MetricData,\n duration: Duration,\n lastCompleteBillingDate: string, // YYYY-MM-DD,\n): ChangeStatistic {\n const dailyCostRatio = dailyCost.change?.ratio;\n const metricDataRatio = metricData.change?.ratio;\n const previousPeriodTotal = getPreviousPeriodTotalCost(\n dailyCost.aggregation,\n duration,\n lastCompleteBillingDate,\n );\n\n // if either ratio cannot be calculated, no compared ratio can be calculated\n if (!notEmpty(dailyCostRatio) || !notEmpty(metricDataRatio)) {\n return {\n amount: previousPeriodTotal,\n };\n }\n\n return {\n ratio: dailyCostRatio - metricDataRatio,\n amount: previousPeriodTotal * (dailyCostRatio - metricDataRatio),\n };\n}\n\nexport function getPreviousPeriodTotalCost(\n aggregation: DateAggregation[],\n duration: Duration,\n inclusiveEndDate: string,\n): number {\n const luxonDuration = LuxonDuration.fromISO(duration);\n const startDate = inclusiveStartDateOf(duration, inclusiveEndDate);\n const nextPeriodStart = DateTime.fromISO(startDate).plus(luxonDuration);\n // Add up costs that incurred before the start of the next period.\n return aggregation.reduce((acc, costByDate) => {\n return DateTime.fromISO(costByDate.date) < nextPeriodStart\n ? acc + costByDate.amount\n : acc;\n }, 0);\n}\n\nexport function choose<T>(\n [savings, excess]: [T, T],\n change: ChangeStatistic,\n): T {\n const isSavings = (change.ratio ?? change.amount) <= 0;\n return isSavings ? savings : excess;\n}\n","/*\n * Copyright 2020 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 */\n\nconst vowels = {\n a: 'A',\n e: 'E',\n i: 'I',\n o: 'O',\n u: 'U',\n};\n\nexport const indefiniteArticleOf = (\n articles: [string, string],\n word: string,\n) => {\n const firstChar = word.charAt(0).toLocaleLowerCase('en-US');\n return firstChar in vowels\n ? `${articles[1]} ${word}`\n : `${articles[0]} ${word}`;\n};\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport classnames from 'classnames';\nimport Typography from '@material-ui/core/Typography';\nimport { CurrencyType, Duration, GrowthType } from '../../types';\nimport { ChangeStatistic } from '@backstage-community/plugin-cost-insights-common';\nimport { rateOf } from '../../utils/currency';\nimport { growthOf } from '../../utils/change';\nimport { useCostGrowthStyles as useStyles } from '../../utils/styles';\nimport { formatPercent, formatCurrency } from '../../utils/formatters';\nimport { indefiniteArticleOf } from '../../utils/grammar';\nimport { useConfig, useCurrency } from '../../hooks';\nimport { notEmpty } from '../../utils/assert';\n\n/** @public */\nexport type CostGrowthProps = {\n change: ChangeStatistic;\n duration: Duration;\n};\n\n/** @public */\nexport const CostGrowth = (props: CostGrowthProps) => {\n const { change, duration } = props;\n\n const styles = useStyles();\n const { engineerCost, engineerThreshold } = useConfig();\n const [currency] = useCurrency();\n\n // Only display costs in absolute values\n const amount = Math.abs(change.amount);\n const ratio = Math.abs(change.ratio ?? NaN);\n\n const rate = rateOf(engineerCost, duration);\n const engineers = amount / rate;\n const converted = amount / (currency.rate ?? rate);\n\n // If a ratio cannot be calculated, don't format.\n const growth = notEmpty(change.ratio)\n ? growthOf({ ratio: change.ratio, amount: engineers }, engineerThreshold)\n : null;\n // Determine if growth is significant enough to highlight\n const classes = classnames({\n [styles.excess]: growth === GrowthType.Excess,\n [styles.savings]: growth === GrowthType.Savings,\n });\n\n if (engineers < engineerThreshold) {\n return (\n <Typography component=\"span\" className={classes}>\n Negligible\n </Typography>\n );\n }\n\n if (currency.kind === CurrencyType.USD) {\n // Do not display percentage if ratio cannot be calculated\n if (isNaN(ratio)) {\n return (\n <Typography component=\"span\" className={classes}>\n ~{currency.prefix}\n {formatCurrency(converted)}\n </Typography>\n );\n }\n\n return (\n <Typography component=\"span\" className={classes}>\n {formatPercent(ratio)} or ~{currency.prefix}\n {formatCurrency(converted)}\n </Typography>\n );\n }\n\n if (amount < 1) {\n return (\n <Typography component=\"span\" className={classes}>\n less than {indefiniteArticleOf(['a', 'an'], currency.unit)}\n </Typography>\n );\n }\n\n // Do not display percentage if ratio cannot be calculated\n if (isNaN(ratio)) {\n return (\n <Typography component=\"span\" className={classes}>\n ~{formatCurrency(converted, currency.unit)}\n </Typography>\n );\n }\n\n return (\n <Typography component=\"span\" className={classes}>\n {formatPercent(ratio)} or ~{formatCurrency(converted, currency.unit)}\n </Typography>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport classnames from 'classnames';\nimport Typography, { TypographyProps } from '@material-ui/core/Typography';\nimport { default as ArrowDropUp } from '@material-ui/icons/ArrowDropUp';\nimport { default as ArrowDropDown } from '@material-ui/icons/ArrowDropDown';\nimport { growthOf } from '../../utils/change';\nimport { GrowthType } from '../../types';\nimport { useCostGrowthStyles as useStyles } from '../../utils/styles';\nimport {\n ChangeStatistic,\n Maybe,\n} from '@backstage-community/plugin-cost-insights-common';\nimport { useConfig } from '../../hooks';\n\n/** @public */\nexport type CostGrowthIndicatorProps = TypographyProps & {\n change: ChangeStatistic;\n formatter?: (\n change: ChangeStatistic,\n options?: { absolute: boolean },\n ) => Maybe<string>;\n};\n\n/** @public */\nexport const CostGrowthIndicator = (props: CostGrowthIndicatorProps) => {\n const { engineerThreshold } = useConfig();\n const { change, formatter, className, ...extraProps } = props;\n\n const classes = useStyles();\n\n const growth = growthOf(change, engineerThreshold);\n\n const classNames = classnames(classes.indicator, className, {\n [classes.excess]: growth === GrowthType.Excess,\n [classes.savings]: growth === GrowthType.Savings,\n });\n\n return (\n <Typography className={classNames} component=\"span\" {...extraProps}>\n {formatter ? formatter(change, { absolute: true }) : change.ratio}\n {growth === GrowthType.Excess && <ArrowDropUp aria-label=\"excess\" />}\n {growth === GrowthType.Savings && <ArrowDropDown aria-label=\"savings\" />}\n </Typography>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport { MapFiltersToProps } from '../../hooks/useFilters';\nimport { MapLoadingToProps } from '../../hooks/useLoading';\nimport { PageFilters } from '../../types';\nimport { Group } from '@backstage-community/plugin-cost-insights-common';\nimport { getResetStateWithoutInitial } from '../../utils/loading';\n\ntype CostInsightsTabsFilterProps = PageFilters & {\n setGroup: (group: Group) => void;\n};\n\ntype CostInsightsTabsLoadingProps = {\n loadingActions: Array<string>;\n dispatchReset: (loadingActions: string[]) => void;\n};\n\nexport const mapFiltersToProps: MapFiltersToProps<\n CostInsightsTabsFilterProps\n> = ({ pageFilters, setPageFilters }) => ({\n ...pageFilters,\n setGroup: (group: Group) =>\n setPageFilters({\n ...pageFilters,\n group: group.id,\n project: null,\n }),\n});\n\nexport const mapLoadingToProps: MapLoadingToProps<\n CostInsightsTabsLoadingProps\n> = ({ actions, dispatch }) => ({\n loadingActions: actions,\n dispatchReset: (loadingActions: string[]) =>\n dispatch(getResetStateWithoutInitial(loadingActions)),\n});\n","/*\n * Copyright 2020 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 */\n\nimport React, { useState } from 'react';\nimport Menu from '@material-ui/core/Menu';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Tab from '@material-ui/core/Tab';\nimport Tabs from '@material-ui/core/Tabs';\nimport Typography from '@material-ui/core/Typography';\nimport ExpandMoreIcon from '@material-ui/icons/ExpandMore';\nimport { mapLoadingToProps, mapFiltersToProps } from './selector';\nimport { Group } from '@backstage-community/plugin-cost-insights-common';\nimport { useFilters, useLoading } from '../../hooks';\nimport { useCostInsightsTabsStyles as useStyles } from '../../utils/styles';\n\nexport type CostInsightsTabsProps = {\n groups: Group[];\n};\n\nexport const CostInsightsTabs = ({ groups }: CostInsightsTabsProps) => {\n const classes = useStyles();\n const [index] = useState(0); // index is fixed for now until other tabs are added\n const [groupMenuEl, setGroupMenuEl] = useState<Element | null>(null);\n const { group, setGroup } = useFilters(mapFiltersToProps);\n const { loadingActions, dispatchReset } = useLoading(mapLoadingToProps);\n\n const openGroupMenu = (e: any) => setGroupMenuEl(e.currentTarget as Element);\n\n const closeGroupMenu = () => setGroupMenuEl(null);\n\n const updateGroupFilterAndCloseMenu = (g: Group) => () => {\n dispatchReset(loadingActions);\n closeGroupMenu();\n setGroup(g);\n };\n\n const renderTabLabel = () => (\n <div className={classes.tabLabel}>\n <Typography className={classes.tabLabelText} variant=\"overline\">\n {`${groups.length} teams`}\n </Typography>\n <ExpandMoreIcon fontSize=\"small\" />\n </div>\n );\n\n const hasAtLeastTwoGroups = groups.length >= 2;\n\n if (!hasAtLeastTwoGroups) return null;\n\n return (\n <>\n <Tabs\n className={`cost-insights-tabs ${classes.tabs}`}\n data-testid=\"cost-insights-tabs\"\n classes={{ indicator: classes.indicator }}\n value={index}\n >\n <Tab\n className={classes.tab}\n data-testid=\"cost-insights-groups-tab\"\n key=\"cost-insights-groups-tab\"\n label={renderTabLabel()}\n onClick={openGroupMenu}\n component=\"button\"\n />\n </Tabs>\n <Menu\n id=\"group-menu\"\n data-testid=\"group-menu\"\n className={classes.menu}\n getContentAnchorEl={null}\n anchorEl={groupMenuEl}\n keepMounted\n open={Boolean(groupMenuEl)}\n onClose={closeGroupMenu}\n anchorOrigin={{\n vertical: 'bottom',\n horizontal: 'left',\n }}\n transformOrigin={{\n vertical: 'top',\n horizontal: 'left',\n }}\n >\n {groups.map((g: Group) => (\n <MenuItem\n className={classes.menuItem}\n classes={{ selected: classes.menuItemSelected }}\n selected={g.id === group}\n key={g.id}\n data-testid={g.id}\n onClick={updateGroupFilterAndCloseMenu(g)}\n >\n {g.name ?? g.id}\n </MenuItem>\n ))}\n </Menu>\n </>\n );\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nimport React, { PropsWithChildren } from 'react';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { Group } from '@backstage-community/plugin-cost-insights-common';\nimport { CostInsightsTabs } from '../CostInsightsTabs';\nimport { Header, Page } from '@backstage/core-components';\n\nconst useStyles = makeStyles(theme => ({\n root: {\n gridArea: 'pageContent',\n },\n header: {\n boxShadow: 'none',\n },\n content: {\n padding: theme.spacing(4),\n },\n}));\n\ntype CostInsightsLayoutProps = {\n title?: string;\n groups: Group[];\n};\n\nexport const CostInsightsLayout = ({\n title = 'Cost Insights',\n groups,\n children,\n}: PropsWithChildren<CostInsightsLayoutProps>) => {\n const classes = useStyles();\n return (\n <Page themeId=\"tool\">\n <Header\n style={{ boxShadow: 'none' }}\n title=\"Cost Insights\"\n pageTitleOverride={title}\n type=\"Tool\"\n />\n <div className={classes.root}>\n <CostInsightsTabs groups={groups} />\n <div className={classes.content}>{children}</div>\n </div>\n </Page>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { useEffect, useState } from 'react';\nimport Collapse from '@material-ui/core/Collapse';\nimport MenuList from '@material-ui/core/MenuList';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport Typography from '@material-ui/core/Typography';\nimport Badge from '@material-ui/core/Badge';\nimport { useNavigationStyles as useStyles } from '../../utils/styles';\nimport { useConfig, useScroll } from '../../hooks';\nimport { findAlways } from '../../utils/assert';\nimport {\n DefaultNavigation,\n NavigationItem,\n getDefaultNavigationItems,\n} from '../../utils/navigation';\nimport {\n Maybe,\n Product,\n} from '@backstage-community/plugin-cost-insights-common';\n\ntype CostInsightsNavigationProps = {\n alerts: number;\n products: Maybe<Product[]>;\n};\n\nconst NavigationMenuItem = ({ navigation, icon, title }: NavigationItem) => {\n const classes = useStyles();\n const [, setScroll] = useScroll();\n return (\n <MenuItem\n data-testid={`menu-item-${navigation}`}\n className={classes.menuItem}\n onClick={() => setScroll(navigation)}\n >\n <ListItemIcon className={classes.listItemIcon}>{icon}</ListItemIcon>\n <ListItemText\n primary={<Typography className={classes.title}>{title}</Typography>}\n />\n </MenuItem>\n );\n};\n\nexport const CostInsightsNavigation = React.memo(\n ({ alerts, products }: CostInsightsNavigationProps) => {\n const classes = useStyles();\n const { icons } = useConfig();\n const [isOpen, setOpen] = useState(false);\n\n const defaultNavigationItems = getDefaultNavigationItems(alerts);\n const productNavigationItems: NavigationItem[] =\n products?.map(product => ({\n title: product.name,\n navigation: product.kind,\n icon: findAlways(icons, i => i.kind === product.kind).component,\n })) ?? [];\n\n useEffect(\n function toggleProductMenuItems() {\n if (products?.length) {\n setOpen(true);\n } else {\n setOpen(false);\n }\n },\n [products],\n );\n\n return (\n <MenuList className={classes.menuList}>\n {defaultNavigationItems.map(item => (\n <NavigationMenuItem\n key={`navigation-menu-item-${item.navigation}`}\n navigation={item.navigation}\n title={item.title}\n icon={\n item.navigation === DefaultNavigation.AlertInsightsHeader ? (\n <Badge badgeContent={alerts} color=\"secondary\">\n {React.cloneElement(item.icon, {\n className: classes.navigationIcon,\n })}\n </Badge>\n ) : (\n React.cloneElement(item.icon, {\n className: classes.navigationIcon,\n })\n )\n }\n />\n ))}\n <Collapse in={isOpen} timeout={850}>\n {productNavigationItems.map((item: NavigationItem) => (\n <NavigationMenuItem\n key={`navigation-menu-item-${item.navigation}`}\n navigation={item.navigation}\n icon={React.cloneElement(item.icon, {\n className: classes.navigationIcon,\n })}\n title={item.title}\n />\n ))}\n </Collapse>\n </MenuList>\n );\n },\n);\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport classnames from 'classnames';\nimport Typography from '@material-ui/core/Typography';\nimport { formatChange } from '../../utils/formatters';\nimport { useEntityDialogStyles as useStyles } from '../../utils/styles';\nimport { CostGrowthIndicator } from '../CostGrowth';\nimport { BarChartOptions } from '../../types';\nimport {\n ChangeStatistic,\n Entity,\n} from '@backstage-community/plugin-cost-insights-common';\nimport { Table, TableColumn } from '@backstage/core-components';\nimport { useConfig } from '../../hooks';\n\nexport type ProductEntityTableOptions = Partial<\n Pick<BarChartOptions, 'previousName' | 'currentName'>\n>;\n\ntype RowData = {\n id: string;\n label: string;\n previous: number;\n current: number;\n change: ChangeStatistic;\n};\n\nconst createRenderer =\n (baseCurrency: Intl.NumberFormat) =>\n (col: keyof RowData, classes: Record<string, string>) => {\n return function render(rowData: {}): JSX.Element {\n const row = rowData as RowData;\n const rowStyles = classnames(classes.row, {\n [classes.rowTotal]: row.id === 'total',\n [classes.colFirst]: col === 'label',\n [classes.colLast]: col === 'change',\n });\n\n switch (col) {\n case 'previous':\n case 'current':\n return (\n <Typography className={rowStyles}>\n {baseCurrency.format(row[col])}\n </Typography>\n );\n case 'change':\n return (\n <CostGrowthIndicator\n className={rowStyles}\n change={row.change}\n formatter={formatChange}\n />\n );\n default:\n return <Typography className={rowStyles}>{row.label}</Typography>;\n }\n };\n };\n\n// material-table does not support fixed rows. Override the sorting algorithm\n// to force Total row to bottom by default or when a user sort toggles a column.\nfunction createSorter(field?: keyof Omit<RowData, 'id'>) {\n return function rowSort(data1: {}, data2: {}): number {\n const a = data1 as RowData;\n const b = data2 as RowData;\n if (a.id === 'total') return 1;\n if (b.id === 'total') return 1;\n if (field === 'label') return a.label.localeCompare(b.label);\n if (field === 'change') {\n if (formatChange(a[field]) === '∞' || formatChange(b[field]) === '-∞')\n return 1;\n if (formatChange(a[field]) === '-∞' || formatChange(b[field]) === '∞')\n return -1;\n return a[field].ratio! - b[field].ratio!;\n }\n\n return b.previous + b.current - (a.previous + a.current);\n };\n}\n\ntype ProductEntityTableProps = {\n entityLabel: string;\n entity: Entity;\n options: ProductEntityTableOptions;\n};\n\nexport const ProductEntityTable = ({\n entityLabel,\n entity,\n options,\n}: ProductEntityTableProps) => {\n const classes = useStyles();\n const { baseCurrency } = useConfig();\n const entities = entity.entities[entityLabel];\n\n const data = Object.assign(\n {\n previousName: 'Previous',\n currentName: 'Current',\n },\n options,\n );\n\n const firstColClasses = classnames(classes.column, classes.colFirst);\n const lastColClasses = classnames(classes.column, classes.colLast);\n\n const columns: TableColumn[] = [\n {\n field: 'label',\n title: <Typography className={firstColClasses}>{entityLabel}</Typography>,\n render: createRenderer(baseCurrency)('label', classes),\n customSort: createSorter('label'),\n width: '33.33%',\n },\n {\n field: 'previous',\n title: (\n <Typography className={classes.column}>{data.previousName}</Typography>\n ),\n align: 'right',\n render: createRenderer(baseCurrency)('previous', classes),\n customSort: createSorter('previous'),\n },\n {\n field: 'current',\n title: (\n <Typography className={classes.column}>{data.currentName}</Typography>\n ),\n align: 'right',\n render: createRenderer(baseCurrency)('current', classes),\n customSort: createSorter('current'),\n },\n {\n field: 'change',\n title: <Typography className={lastColClasses}>Change</Typography>,\n align: 'right',\n render: createRenderer(baseCurrency)('change', classes),\n customSort: createSorter('change'),\n },\n ];\n\n const rowData: RowData[] = entities\n .map(e => ({\n id: e.id || 'Unknown',\n label: e.id || 'Unknown',\n previous: e.aggregation[0],\n current: e.aggregation[1],\n change: e.change,\n }))\n .concat({\n id: 'total',\n label: 'Total',\n previous: entity.aggregation[0],\n current: entity.aggregation[1],\n change: entity.change,\n })\n .sort(createSorter());\n\n return (\n <Table\n columns={columns}\n data={rowData}\n title={entity.id || 'Unlabeled'}\n options={{\n paging: false,\n search: false,\n hideFilterIcons: true,\n }}\n />\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { useState } from 'react';\nimport Dialog from '@material-ui/core/Dialog';\nimport IconButton from '@material-ui/core/IconButton';\nimport { default as CloseButton } from '@material-ui/icons/Close';\nimport { useEntityDialogStyles as useStyles } from '../../utils/styles';\nimport { Entity } from '@backstage-community/plugin-cost-insights-common';\nimport {\n ProductEntityTable,\n ProductEntityTableOptions,\n} from './ProductEntityTable';\nimport { findAlways } from '../../utils/assert';\nimport { HeaderTabs } from '@backstage/core-components';\n\ntype ProductEntityDialogProps = {\n open: boolean;\n entity: Entity;\n options?: ProductEntityTableOptions;\n onClose: () => void;\n};\n\nexport const ProductEntityDialog = ({\n open,\n entity,\n options = {},\n onClose,\n}: ProductEntityDialogProps) => {\n const classes = useStyles();\n const labels = Object.keys(entity.entities);\n const [selectedLabel, setSelectedLabel] = useState(\n findAlways(labels, _ => true),\n );\n\n const tabs = labels.map((label, index) => ({\n id: index.toString(),\n label: `Breakdown by ${label}`,\n }));\n\n return (\n <Dialog open={open} onClose={onClose} scroll=\"body\" fullWidth maxWidth=\"lg\">\n <IconButton className={classes.closeButton} onClick={onClose}>\n <CloseButton />\n </IconButton>\n <HeaderTabs\n tabs={tabs}\n onChange={index => setSelectedLabel(labels[index])}\n />\n <ProductEntityTable\n entityLabel={selectedLabel}\n entity={entity}\n options={options}\n />\n </Dialog>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { useMemo, useState } from 'react';\nimport pluralize from 'pluralize';\nimport Box from '@material-ui/core/Box';\nimport Typography from '@material-ui/core/Typography';\nimport { default as FullScreenIcon } from '@material-ui/icons/Fullscreen';\nimport { LegendItem } from '../LegendItem';\nimport { ProductEntityDialog } from './ProductEntityDialog';\nimport { CostGrowth, CostGrowthIndicator } from '../CostGrowth';\nimport {\n BarChart,\n BarChartLegend,\n BarChartTooltip,\n BarChartTooltipItem,\n BarChartLegendOptions,\n} from '../BarChart';\nimport {\n findAlways,\n notEmpty,\n isUndefined,\n findAnyKey,\n assertAlways,\n} from '../../utils/assert';\nimport { formatPeriod, formatChange } from '../../utils/formatters';\nimport {\n titleOf,\n tooltipItemOf,\n resourceOf,\n isInvalid,\n isLabeled,\n isUnlabeled,\n} from '../../utils/graphs';\nimport {\n useProductInsightsChartStyles as useStyles,\n useBarChartLayoutStyles as useLayoutStyles,\n} from '../../utils/styles';\nimport { Duration } from '../../types';\nimport {\n Entity,\n Maybe,\n} from '@backstage-community/plugin-cost-insights-common';\nimport { choose } from '../../utils/change';\nimport { TooltipRenderer } from '../../types';\nimport { useConfig } from '../../hooks';\n\nexport type ProductInsightsChartProps = {\n billingDate: string;\n entity: Entity;\n duration: Duration;\n};\n\nexport const ProductInsightsChart = ({\n billingDate,\n entity,\n duration,\n}: ProductInsightsChartProps) => {\n const classes = useStyles();\n const layoutClasses = useLayoutStyles();\n const { baseCurrency } = useConfig();\n\n // Only a single entities Record for the root product entity is supported\n const entities = useMemo(() => {\n const entityLabel = assertAlways(findAnyKey(entity.entities));\n return entity.entities[entityLabel] ?? [];\n }, [entity]);\n\n const [activeLabel, setActive] = useState<Maybe<string>>();\n const [selectLabel, setSelected] = useState<Maybe<string>>();\n const isSelected = useMemo(() => !isUndefined(selectLabel), [selectLabel]);\n\n const isClickable = useMemo(() => {\n const breakdowns = Object.keys(\n entities.find(e => e.id === activeLabel)?.entities ?? {},\n );\n return breakdowns.length > 0;\n }, [entities, activeLabel]);\n\n const costStart = entity.aggregation[0];\n const costEnd = entity.aggregation[1];\n const resources = entities.map(resourceOf);\n\n const options: Partial<BarChartLegendOptions> = {\n previousName: formatPeriod(duration, billingDate, false),\n currentName: formatPeriod(duration, billingDate, true),\n };\n\n const onMouseMove: (...args: any[]) => void = (\n data: Record<'activeLabel', string | undefined>,\n ) => {\n if (isLabeled(data)) {\n setActive(data.activeLabel!);\n } else if (isUnlabeled(data)) {\n setActive(null);\n } else {\n setActive(undefined);\n }\n };\n\n const onClick: (...args: any[]) => void = (\n data: Record<'activeLabel', string>,\n ) => {\n if (isLabeled(data)) {\n setSelected(data.activeLabel);\n } else if (isUnlabeled(data)) {\n setSelected(null);\n } else {\n setSelected(undefined);\n }\n };\n\n const renderProductInsightsTooltip: TooltipRenderer = ({\n label,\n payload = [],\n }) => {\n /* Labels and payloads may be undefined or empty */\n if (isInvalid({ label, payload })) return null;\n\n /*\n * recharts coerces null values to strings\n * entity -> resource -> payload\n * { id: null } -> { name: null } -> { label: '' }\n */\n const id = label === '' ? null : label;\n\n const title = titleOf(label);\n const items = payload.map(tooltipItemOf(baseCurrency)).filter(notEmpty);\n\n const activeEntity = findAlways(entities, e => e.id === id);\n const breakdowns = Object.keys(activeEntity.entities);\n\n if (breakdowns.length) {\n const subtitle = breakdowns\n .map(b => pluralize(b, activeEntity.entities[b].length, true))\n .join(', ');\n return (\n <BarChartTooltip\n title={title}\n subtitle={subtitle}\n topRight={\n !!activeEntity.change.ratio && (\n <CostGrowthIndicator\n formatter={formatChange}\n change={activeEntity.change}\n className={classes.indicator}\n />\n )\n }\n actions={\n <Box className={classes.actions}>\n <FullScreenIcon />\n <Typography>Click for breakdown</Typography>\n </Box>\n }\n >\n {items.map((item, index) => (\n <BarChartTooltipItem key={`${item.label}-${index}`} item={item} />\n ))}\n </BarChartTooltip>\n );\n }\n\n // If an entity doesn't have any sub-entities, there aren't any costs to break down.\n return (\n <BarChartTooltip\n title={title}\n topRight={\n !!activeEntity.change.ratio && (\n <CostGrowthIndicator\n formatter={formatChange}\n change={activeEntity.change}\n className={classes.indicator}\n />\n )\n }\n content={\n id\n ? null\n : \"This product has costs that are not labeled and therefore can't be attributed to a specific entity.\"\n }\n >\n {items.map((item, index) => (\n <BarChartTooltipItem key={`${item.label}-${index}`} item={item} />\n ))}\n </BarChartTooltip>\n );\n };\n\n const barChartProps = isClickable ? { onClick } : {};\n\n return (\n <Box className={layoutClasses.wrapper}>\n <BarChartLegend costStart={costStart} costEnd={costEnd} options={options}>\n <LegendItem\n title={choose(['Cost Savings', 'Cost Excess'], entity.change)}\n >\n <CostGrowth change={entity.change} duration={duration} />\n </LegendItem>\n </BarChartLegend>\n <BarChart\n resources={resources}\n tooltip={renderProductInsightsTooltip}\n onMouseMove={onMouseMove}\n options={options}\n {...barChartProps}\n />\n {isSelected && entities.length && (\n <ProductEntityDialog\n open={isSelected}\n onClose={() => setSelected(undefined)}\n entity={findAlways(entities, e => e.id === selectLabel)}\n options={options}\n />\n )}\n </Box>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport { DateTime } from 'luxon';\nimport Box from '@material-ui/core/Box';\nimport { BarChart, BarChartLegend, BarChartLegendOptions } from '../BarChart';\nimport { LegendItem } from '../LegendItem';\nimport { CostGrowth } from '../CostGrowth';\nimport { Duration, ProjectGrowthData } from '../../types';\nimport { useBarChartLayoutStyles as useStyles } from '../../utils/styles';\nimport { resourceOf } from '../../utils/graphs';\n\ntype ProjectGrowthAlertChartProps = {\n alert: ProjectGrowthData;\n};\n\nexport const ProjectGrowthAlertChart = ({\n alert,\n}: ProjectGrowthAlertChartProps) => {\n const classes = useStyles();\n\n const costStart = alert.aggregation[0];\n const costEnd = alert.aggregation[1];\n const resourceData = alert.products.map(resourceOf);\n\n const options: Partial<BarChartLegendOptions> = {\n previousName: DateTime.fromFormat(alert.periodStart, \"yyyy-'Q'q\").toFormat(\n \"'Q'q yyyy\",\n ),\n currentName: DateTime.fromFormat(alert.periodEnd, \"yyyy-'Q'q\").toFormat(\n \"'Q'q yyyy\",\n ),\n };\n\n return (\n <Box className={classes.wrapper}>\n <BarChartLegend costStart={costStart} costEnd={costEnd} options={options}>\n <LegendItem title=\"Cost Growth\">\n <CostGrowth change={alert.change} duration={Duration.P3M} />\n </LegendItem>\n </BarChartLegend>\n <BarChart resources={resourceData} options={options} />\n </Box>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport pluralize from 'pluralize';\nimport { ProjectGrowthAlertChart } from './ProjectGrowthAlertChart';\nimport { ProjectGrowthData } from '../../types';\nimport { InfoCard } from '@backstage/core-components';\n\ntype ProjectGrowthAlertProps = {\n alert: ProjectGrowthData;\n};\n\nexport const ProjectGrowthAlertCard = ({ alert }: ProjectGrowthAlertProps) => {\n const subheader = `\n ${pluralize('product', alert.products.length, true)}${\n alert.products.length > 1 ? ', sorted by cost' : ''\n }`;\n\n return (\n <InfoCard\n title={`Project growth for ${alert.project}`}\n subheader={subheader}\n >\n <ProjectGrowthAlertChart alert={alert} />\n </InfoCard>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport { ProjectGrowthAlertCard } from '../components/ProjectGrowthAlertCard';\nimport { Alert, ProjectGrowthData } from '../types';\n\n/**\n * The alert below is an example of an Alert implementation; the CostInsightsApi permits returning\n * any implementation of the Alert type, so adopters can create their own. The CostInsightsApi\n * fetches alert data from the backend, then creates Alert classes with the data.\n *\n * @public\n */\nexport class ProjectGrowthAlert implements Alert {\n data: ProjectGrowthData;\n\n constructor(data: ProjectGrowthData) {\n this.data = data;\n }\n\n get url() {\n return '/cost-insights/investigating-growth';\n }\n\n get title() {\n return `Investigate cost growth in project ${this.data.project}`;\n }\n\n get subtitle() {\n return 'Cost growth outpacing business growth is unsustainable long-term.';\n }\n\n get element() {\n return <ProjectGrowthAlertCard alert={this.data} />;\n }\n}\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport pluralize from 'pluralize';\nimport Box from '@material-ui/core/Box';\nimport { BarChart, BarChartLegend } from '../BarChart';\nimport { UnlabeledDataflowData, ResourceData } from '../../types';\nimport { useBarChartLayoutStyles as useStyles } from '../../utils/styles';\nimport { InfoCard } from '@backstage/core-components';\n\ntype UnlabeledDataflowAlertProps = {\n alert: UnlabeledDataflowData;\n};\n\nexport const UnlabeledDataflowAlertCard = ({\n alert,\n}: UnlabeledDataflowAlertProps) => {\n const classes = useStyles();\n const projects = pluralize('project', alert.projects.length, true);\n const subheader = `\n Showing costs from ${projects} with unlabeled Dataflow jobs in the last 30 days.\n `;\n const options = {\n previousName: 'Unlabeled Cost',\n currentName: 'Labeled Cost',\n };\n\n const resources: ResourceData[] = alert.projects.map(project => ({\n name: project.id,\n previous: project.unlabeledCost,\n current: project.labeledCost,\n }));\n\n return (\n <InfoCard title=\"Label Dataflow\" subheader={subheader}>\n <Box className={classes.wrapper}>\n <BarChartLegend\n costStart={alert.unlabeledCost}\n costEnd={alert.labeledCost}\n options={options}\n />\n <BarChart resources={resources} options={options} />\n </Box>\n </InfoCard>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport { UnlabeledDataflowAlertCard } from '../components/UnlabeledDataflowAlertCard';\nimport { Alert, AlertStatus, UnlabeledDataflowData } from '../types';\n\n/**\n * The alert below is an example of an Alert implementation; the CostInsightsApi permits returning\n * any implementation of the Alert type, so adopters can create their own. The CostInsightsApi\n * fetches alert data from the backend, then creates Alert classes with the data.\n *\n * @public\n */\nexport class UnlabeledDataflowAlert implements Alert {\n data: UnlabeledDataflowData;\n status?: AlertStatus;\n\n constructor(data: UnlabeledDataflowData) {\n this.data = data;\n }\n\n get url() {\n return '/cost-insights/labeling-jobs';\n }\n\n get title() {\n return 'Add labels to workflows';\n }\n\n get subtitle() {\n return 'Labels show in billing data, enabling cost insights for each workflow.';\n }\n\n get element() {\n return <UnlabeledDataflowAlertCard alert={this.data} />;\n }\n}\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport { DateTime } from 'luxon';\nimport Box from '@material-ui/core/Box';\nimport Typography from '@material-ui/core/Typography';\nimport { AlertInstructionsLayout } from '../AlertInstructionsLayout';\nimport { ProductInsightsChart } from '../ProductInsightsCard';\nimport {\n Alert,\n DEFAULT_DATE_FORMAT,\n Duration,\n ProjectGrowthData,\n} from '../../types';\nimport {\n Entity,\n Product,\n} from '@backstage-community/plugin-cost-insights-common';\nimport { ProjectGrowthAlert } from '../../alerts';\nimport { InfoCard } from '@backstage/core-components';\n\nconst today = DateTime.now().toFormat(DEFAULT_DATE_FORMAT);\n\nexport const ProjectGrowthInstructionsPage = () => {\n const alertData: ProjectGrowthData = {\n project: 'example-project',\n periodStart: 'Q1 2020',\n periodEnd: 'Q2 2020',\n aggregation: [60000, 120000],\n change: {\n ratio: 1,\n amount: 60000,\n },\n products: [\n {\n id: 'Compute Engine',\n aggregation: [58000, 118000],\n },\n {\n id: 'Cloud Dataflow',\n aggregation: [1200, 1500],\n },\n {\n id: 'Cloud Storage',\n aggregation: [800, 500],\n },\n ],\n };\n\n const projectGrowthAlert: Alert = new ProjectGrowthAlert(alertData);\n\n const product: Product = {\n kind: 'ComputeEngine',\n name: 'Compute Engine',\n };\n\n const entity: Entity = {\n id: 'example-id',\n aggregation: [20_000, 60_000],\n change: {\n ratio: 3,\n amount: 40_000,\n },\n entities: {\n service: [\n {\n id: 'service-one',\n aggregation: [18_200, 58_500],\n entities: {},\n change: { ratio: 2.21, amount: 40_300 },\n },\n {\n id: 'service-two',\n aggregation: [1200, 1300],\n entities: {},\n change: { ratio: 0.083, amount: 100 },\n },\n {\n id: 'service-three',\n aggregation: [600, 200],\n entities: {},\n change: { ratio: -0.666, amount: -400 },\n },\n ],\n },\n };\n\n return (\n <AlertInstructionsLayout title=\"Investigating Growth\">\n <Typography variant=\"h1\">Investigating cloud cost growth</Typography>\n <Typography paragraph>\n Cost Insights shows an alert when costs for a particular billing entity,\n such as a GCP project, have grown at a rate faster than our alerting\n threshold. The responsible team should follow this guide to decide\n whether this warrants further investigation.\n </Typography>\n\n <Box mt={4}>\n <Typography variant=\"h3\">Is the growth expected?</Typography>\n <Typography paragraph>\n The first question to ask is whether growth is expected. Perhaps a new\n product has been deployed, or additional regions added for\n reliability.\n </Typography>\n <Typography paragraph>\n Many services increase cost linearly with load. Has the demand\n increased? This may happen as you open new markets, or run marketing\n offers. Costs should be compared against a business metric, such as\n daily users, to normalize natural increases from business growth.\n </Typography>\n <Typography paragraph>\n Seasonal variance may also cause cost growth; yearly campaigns, an\n increase in demand during certain times of year.\n </Typography>\n <Typography paragraph>\n Cloud costs will often go up before they go down, in the case of\n migrations. Teams moving to new infrastructure may run in both the old\n and new environment during the migration.\n </Typography>\n </Box>\n\n <Box mt={4}>\n <Typography variant=\"h3\">Is the growth significant?</Typography>\n <Typography paragraph>\n Next, evaluate whether the growth is significant. This helps avoid\n premature optimization, where cost in engineering time is more than\n would be saved from the optimization over a reasonable time frame.\n </Typography>\n <Typography paragraph>\n We recommend reframing the cost growth itself in terms of engineering\n time. How much engineering time, for an <i>average</i> fully-loaded\n engineer cost at the company, is being overspent each month? Compare\n this to expected engineering time for optimization to decide whether\n the optimization is worthwhile.\n </Typography>\n </Box>\n\n <Box mt={4}>\n <Typography variant=\"h3\">\n Identifying which cloud product contributed most\n </Typography>\n <Typography paragraph>\n For projects meeting the alert threshold, Cost Insights shows a cost\n comparison of cloud products over the examined time period:\n </Typography>\n <Box mt={2} mb={2}>\n {projectGrowthAlert.element}\n </Box>\n <Typography paragraph>\n This allows you to quickly see which cloud products contributed to the\n growth in cloud costs.\n </Typography>\n </Box>\n\n <Box mt={4}>\n <Typography variant=\"h3\">\n Identifying the responsible workload\n </Typography>\n <Typography paragraph>\n After identifying the cloud product, use the corresponding product\n panel in Cost Insights to find a particular workload (or <i>entity</i>\n ) that has grown in cost:\n </Typography>\n <Box mt={2} mb={2}>\n <InfoCard title={product.name} subheader=\"3 entities, sorted by cost\">\n <ProductInsightsChart\n billingDate={today}\n duration={Duration.P3M}\n entity={entity}\n />\n </InfoCard>\n </Box>\n <Typography paragraph>\n From here, you can dig into commit history or deployment logs to find\n probable causes of an unexpected spike in cost.\n </Typography>\n </Box>\n\n <Box mt={4}>\n <Typography variant=\"h3\">Optimizing the workload</Typography>\n <Typography paragraph>\n Workload optimization varies between cloud products, but there are a\n few general optimization areas to consider:\n </Typography>\n <Typography variant=\"h5\">Retention</Typography>\n <Typography paragraph>\n Is the workload or storage necessary? Truly idle or unused resources\n can be cleaned up for immediate cost savings. For storage, how long do\n we need the data? Many cloud products support retention policies to\n automatically delete data after a certain time period.\n </Typography>\n <Typography variant=\"h5\">Efficiency</Typography>\n <Typography paragraph>\n Is the workload using cloud resources efficiently? For compute\n resources, do the utilization metrics look reasonable? Autoscaling\n infrastructure, such as Kubernetes, can run workloads more efficiently\n without compromising reliability.\n </Typography>\n <Typography variant=\"h5\">Lifecycle</Typography>\n <Typography paragraph>\n Is the workload using an optimal pricing model? Some cloud products\n offer better pricing for data that is accessed less frequently.\n </Typography>\n </Box>\n </AlertInstructionsLayout>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport Box from '@material-ui/core/Box';\nimport { useTheme } from '@material-ui/core/styles';\nimport { CostGrowth, LegendItem } from '../../../components';\nimport { CostInsightsTheme, Duration } from '../../../types';\nimport { ChangeStatistic } from '@backstage-community/plugin-cost-insights-common';\nimport { monthOf } from '../../../utils/formatters';\n\nexport type MigrationBarChartLegendProps = {\n change: ChangeStatistic;\n startDate: string;\n currentProduct: string;\n comparedProduct: string;\n};\n\nexport const KubernetesMigrationBarChartLegend = ({\n currentProduct,\n comparedProduct,\n change,\n startDate,\n}: MigrationBarChartLegendProps) => {\n const theme = useTheme<CostInsightsTheme>();\n return (\n <Box display=\"flex\" flexDirection=\"row\">\n <Box marginRight={2}>\n <LegendItem\n title={monthOf(startDate)}\n markerColor={theme.palette.magenta}\n >\n {currentProduct}\n </LegendItem>\n </Box>\n <Box marginRight={2}>\n <LegendItem title=\"Estimated Cost\" markerColor={theme.palette.yellow}>\n {comparedProduct}\n </LegendItem>\n </Box>\n <LegendItem title=\"Total Savings\">\n <CostGrowth change={change} duration={Duration.P30D} />\n </LegendItem>\n </Box>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport { BarChart } from '../../../components';\nimport {\n BarChartOptions,\n CostInsightsTheme,\n ResourceData,\n} from '../../../types';\nimport { Entity } from '@backstage-community/plugin-cost-insights-common';\nimport { useTheme } from '@material-ui/core/styles';\n\ntype MigrationBarChartProps = {\n currentProduct: string;\n comparedProduct: string;\n services: Array<Entity>;\n};\n\nexport const KubernetesMigrationBarChart = ({\n currentProduct,\n comparedProduct,\n services,\n}: MigrationBarChartProps) => {\n const theme = useTheme<CostInsightsTheme>();\n\n const options: BarChartOptions = {\n previousFill: theme.palette.magenta,\n currentFill: theme.palette.yellow,\n previousName: comparedProduct,\n currentName: currentProduct,\n };\n\n const resources: ResourceData[] = services.map(service => ({\n name: service.id,\n previous: service.aggregation[0],\n current: service.aggregation[1],\n }));\n\n return <BarChart resources={resources} options={options} />;\n};\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport Box from '@material-ui/core/Box';\nimport { KubernetesMigrationBarChartLegend } from './KubernetesMigrationBarChartLegend';\nimport { KubernetesMigrationBarChart } from './KubernetesMigrationBarChart';\nimport { KubernetesMigrationData } from '../../alerts';\nimport { InfoCard } from '@backstage/core-components';\n\ntype KubernetesMigrationAlertProps = {\n data: KubernetesMigrationData;\n title: string;\n subheader: string;\n currentProduct: string;\n comparedProduct: string;\n};\n\nexport const KubernetesMigrationAlertCard = ({\n data,\n title,\n subheader,\n currentProduct,\n comparedProduct,\n}: KubernetesMigrationAlertProps) => {\n return (\n <InfoCard title={title} subheader={subheader}>\n <Box display=\"flex\" flexDirection=\"column\">\n <Box paddingY={1}>\n <KubernetesMigrationBarChartLegend\n startDate={data.startDate}\n change={data.change}\n currentProduct={currentProduct}\n comparedProduct={comparedProduct}\n />\n </Box>\n <Box paddingY={1}>\n <KubernetesMigrationBarChart\n services={data.services}\n currentProduct={currentProduct}\n comparedProduct={comparedProduct}\n />\n </Box>\n </Box>\n </InfoCard>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, {\n useEffect,\n useState,\n forwardRef,\n FormEventHandler,\n ChangeEvent,\n} from 'react';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\nimport FormGroup from '@material-ui/core/FormGroup';\nimport Typography from '@material-ui/core/Typography';\nimport { AlertFormProps } from '../../types';\nimport { Entity } from '@backstage-community/plugin-cost-insights-common';\nimport { KubernetesMigrationAlert } from '../alerts';\nimport { findAlways } from '../../utils/assert';\n\nexport type KubernetesMigrationDismissFormData = {\n services: Entity[];\n};\n\nexport type KubernetesMigrationDismissFormProps = AlertFormProps<\n KubernetesMigrationAlert,\n KubernetesMigrationDismissFormData\n>;\n\nexport const KubernetesMigrationDismissForm = forwardRef<\n HTMLFormElement,\n KubernetesMigrationDismissFormProps\n>(({ onSubmit, disableSubmit, alert }, ref) => {\n const [services, setServices] = useState<Entity[]>(alert.data.services);\n\n const onFormSubmit: FormEventHandler = e => {\n /* Remember to prevent default form behavior */\n e.preventDefault();\n onSubmit({ services: services });\n };\n\n const onCheckboxChange = (\n e: ChangeEvent<HTMLInputElement>,\n checked: boolean,\n ) => {\n if (checked) {\n const service = findAlways(\n alert.data.services,\n s => s.id === e.target.value,\n );\n setServices(prevServices => prevServices.concat(service));\n } else {\n setServices(prevServices =>\n prevServices.filter(p => p.id !== e.target.value),\n );\n }\n };\n\n /* Submit button is disabled by default. Use props.disableSubmit to toggle disabled state. */\n useEffect(() => {\n if (services.length) {\n disableSubmit(false);\n } else {\n disableSubmit(true);\n }\n }, [services, disableSubmit]);\n\n return (\n /* All custom forms must accept a ref and implement an onSubmit handler. */\n <form ref={ref} onSubmit={onFormSubmit}>\n <FormControl component=\"fieldset\" fullWidth>\n <Typography color=\"textPrimary\">\n <b>Or choose which services to dismiss this alert for.</b>\n </Typography>\n <FormGroup>\n {alert.data.services.map((service, index) => (\n <FormControlLabel\n key={`example-option-${index}`}\n label={service.id}\n value={service.id}\n control={\n <Checkbox\n color=\"primary\"\n checked={services.some(p => p.id === service.id)}\n onChange={onCheckboxChange}\n />\n }\n />\n ))}\n </FormGroup>\n </FormControl>\n </form>\n );\n});\n","/*\n * Copyright 2020 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 */\n\nimport React from 'react';\nimport pluralize from 'pluralize';\nimport Typography from '@material-ui/core/Typography';\nimport { KubernetesMigrationAlertCard } from '../components';\nimport { CostInsightsApi } from '../../api';\nimport {\n Alert,\n AlertForm,\n AlertOptions,\n AlertStatus,\n AlertSnoozeFormData,\n} from '../../types';\nimport {\n ChangeStatistic,\n Entity,\n} from '@backstage-community/plugin-cost-insights-common';\nimport {\n KubernetesMigrationDismissForm,\n KubernetesMigrationDismissFormData,\n} from '../forms';\nimport { Lifecycle } from '@backstage/core-components';\n\nexport interface KubernetesMigrationData {\n startDate: string;\n endDate: string;\n change: ChangeStatistic;\n services: Array<Entity>;\n}\n\nexport interface KubernetesMigrationApi extends Alert {\n api: CostInsightsApi;\n data: KubernetesMigrationData;\n}\n\n/**\n * This is an example of an Alert implementation using optional event hooks.\n *\n * Event hooks can be used to enable users to dismiss, snooze, or accept an action item\n * - or any combination thereof. Defining a hook will generate default UI - button, dialog and\n * form. Cost Insights does not preserve client side alert state - each hook is expected to return a new set of alerts.\n *\n * Snoozed, accepted, etc. alerts should define a corresponding status property. Alerts will be aggregated\n * by status in a collapsed view below Alert Insights section and a badge will appear in Action Items\n * showing the total alerts of that status.\n *\n * Customizing Alerts\n * Default forms can be overridden in two ways - by setting a form property to null or defining a custom component.\n *\n * If a form property is set to null, the Dialog will not render a form. This can be useful in scenarios\n * where data isn't needed from the user such as when a user accepts an action item's recommendation.\n *\n * If a form property is set to a React component, the Dialog will render the form component in place of the default form.\n * Form components must return valid form elements, and accept a ref and onSubmit event handler.\n * Custom forms must implement the corresponding event hook. See /forms for example implementations.\n */\n\nexport class KubernetesMigrationAlert implements KubernetesMigrationApi {\n api: CostInsightsApi;\n data: KubernetesMigrationData;\n\n subtitle =\n 'Services running on Kubernetes are estimated to save 50% or more compared to Compute Engine.';\n\n // Dialog will not render a form if form property set to null.\n AcceptForm = null;\n // Overrides default Dismiss form with a custom form component.\n DismissForm: AlertForm<\n KubernetesMigrationAlert,\n KubernetesMigrationDismissFormData\n > = KubernetesMigrationDismissForm;\n\n constructor(api: CostInsightsApi, data: KubernetesMigrationData) {\n this.api = api;\n this.data = data;\n }\n\n get title() {\n return (\n <Typography component=\"span\">\n Consider migrating{' '}\n {pluralize('service', this.data.services.length, true)} to Kubernetes{' '}\n <Lifecycle shorthand />\n </Typography>\n );\n }\n\n get element() {\n const subheader = `${pluralize(\n 'Service',\n this.data.services.length,\n true,\n )}, sorted by cost`;\n return (\n <KubernetesMigrationAlertCard\n data={this.data}\n title=\"Migrate to Kubernetes\"\n subheader={subheader}\n currentProduct=\"Compute Engine\"\n comparedProduct=\"Kubernetes\"\n />\n );\n }\n\n /* Fires when the onSubmit event is raised on a Dismiss form. Displays custom dismiss form. */\n async onDismissed(\n options: AlertOptions<KubernetesMigrationDismissFormData>,\n ): Promise<Alert[]> {\n const alerts = await this.api.getAlerts(options.group);\n return new Promise(resolve =>\n setTimeout(resolve, 750, [\n ...alerts.filter(a => a.title !== this.title),\n {\n title: this.title,\n subtitle: this.subtitle,\n status: AlertStatus.Dismissed,\n },\n ]),\n );\n }\n\n /* Fires when the onSubmit event is raised on a Snooze form. Displays default snooze form. */\n async onSnoozed(\n options: AlertOptions<AlertSnoozeFormData>,\n ): Promise<Alert[]> {\n const alerts = await this.api.getAlerts(options.group);\n return new Promise(resolve =>\n setTimeout(resolve, 750, [\n ...alerts.filter(a => a.title !== this.title),\n {\n title: this.title,\n subtitle: this.subtitle,\n status: AlertStatus.Snoozed,\n },\n ]),\n );\n }\n\n /* Fires when the Accept button is clicked. Dialog does not render a form. See KubernetesMigrationAlert.AcceptForm */\n async onAccepted(options: AlertOptions<null>): Promise<Alert[]> {\n const alerts = await this.api.getAlerts(options.group);\n return new Promise(resolve =>\n setTimeout(resolve, 750, [\n ...alerts.filter(a => a.title !== this.title),\n {\n title: this.title,\n subtitle: this.subtitle,\n status: AlertStatus.Accepted,\n },\n ]),\n );\n }\n}\n","/*\n * Copyright 2020 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 */\n\nimport {\n Entity,\n Product,\n} from '@backstage-community/plugin-cost-insights-common';\nimport { findAlways } from '../utils/assert';\n\ntype mockEntityRenderer<T> = (entity: T) => T;\n\nexport const createMockEntity = (\n callback?: mockEntityRenderer<Entity>,\n): Entity => {\n const defaultEntity: Entity = {\n id: 'test-entity',\n aggregation: [100, 200],\n entities: {},\n change: {\n ratio: 0,\n amount: 0,\n },\n };\n\n if (typeof callback === 'function') {\n return callback({ ...defaultEntity });\n }\n return { ...defaultEntity };\n};\n\nexport const createMockProduct = (\n callback?: mockEntityRenderer<Product>,\n): Product => {\n const defaultProduct: Product = {\n kind: 'compute-engine',\n name: 'Compute Engine',\n };\n if (typeof callback === 'function') {\n return callback({ ...defaultProduct });\n }\n return { ...defaultProduct };\n};\n\nexport const MockProductTypes: Record<string, string> = {\n 'compute-engine': 'Compute Engine',\n 'cloud-dataflow': 'Cloud Dataflow',\n 'cloud-storage': 'Cloud Storage',\n 'big-query': 'Big Query',\n 'big-table': 'BigTable',\n 'cloud-pub-sub': 'Cloud Pub/Sub',\n};\n\nexport const MockProducts: Product[] = Object.keys(MockProductTypes).map(\n productType =>\n createMockProduct(() => ({\n kind: productType,\n name: MockProductTypes[productType],\n })),\n);\n\nexport const MockComputeEngine = findAlways(\n MockProducts,\n p => p.kind === 'compute-engine',\n);\nexport const MockCloudDataflow = findAlways(\n MockProducts,\n p => p.kind === 'cloud-dataflow',\n);\nexport const MockCloudStorage = findAlways(\n MockProducts,\n p => p.kind === 'cloud-storage',\n);\nexport const MockBigQuery = findAlways(\n MockProducts,\n p => p.kind === 'big-query',\n);\nexport const MockBigtable = findAlways(\n MockProducts,\n p => p.kind === 'big-table',\n);\n","/*\n * Copyright 2020 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 */\n\nimport { Duration, ProductFilters } from '../types';\nimport { MockProductTypes } from './products';\n\nexport const MockProductFilters: ProductFilters = Object.keys(\n MockProductTypes,\n).map(productType => ({ duration: Duration.P30D, productType }));\n","/*\n * Copyright 2020 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 { MockProducts } from './products';\nimport {\n DefaultLoadingAction,\n getDefaultState as getDefaultLoadingState,\n} from '../utils/loading';\n\nexport const MockDefaultLoadingActions = (\n [\n DefaultLoadingAction.UserGroups,\n DefaultLoadingAction.CostInsightsInitial,\n DefaultLoadingAction.CostInsightsPage,\n ] as string[]\n).concat(MockProducts.map(product => product.kind));\n\nexport const mockDefaultLoadingState = getDefaultLoadingState(\n MockDefaultLoadingActions,\n);\n","/*\n * Copyright 2020 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 */\n\nimport {\n DateAggregation,\n Entity,\n} from '@backstage-community/plugin-cost-insights-common';\n\nexport const MockAggregatedDailyCosts: DateAggregation[] = [\n {\n date: '2020-08-07',\n amount: 3500,\n },\n {\n date: '2020-08-06',\n amount: 2500,\n },\n {\n date: '2020-08-05',\n amount: 1400,\n },\n {\n date: '2020-08-04',\n amount: 3800,\n },\n {\n date: '2020-08-09',\n amount: 1900,\n },\n {\n date: '2020-08-08',\n amount: 2400,\n },\n {\n date: '2020-08-03',\n amount: 4000,\n },\n {\n date: '2020-08-02',\n amount: 3700,\n },\n {\n date: '2020-08-01',\n amount: 2500,\n },\n {\n date: '2020-08-18',\n amount: 4300,\n },\n {\n date: '2020-08-17',\n amount: 1500,\n },\n {\n date: '2020-08-16',\n amount: 3600,\n },\n {\n date: '2020-08-15',\n amount: 2200,\n },\n {\n date: '2020-08-19',\n amount: 3900,\n },\n {\n date: '2020-08-10',\n amount: 4100,\n },\n {\n date: '2020-08-14',\n amount: 3600,\n },\n {\n date: '2020-08-13',\n amount: 2900,\n },\n {\n date: '2020-08-12',\n amount: 2700,\n },\n {\n date: '2020-08-11',\n amount: 5100,\n },\n {\n date: '2020-09-19',\n amount: 1200,\n },\n {\n date: '2020-09-18',\n amount: 6500,\n },\n {\n date: '2020-09-17',\n amount: 2500,\n },\n {\n date: '2020-09-16',\n amount: 1400,\n },\n {\n date: '2020-09-11',\n amount: 2300,\n },\n {\n date: '2020-09-10',\n amount: 1900,\n },\n {\n date: '2020-09-15',\n amount: 3100,\n },\n {\n date: '2020-09-14',\n amount: 4500,\n },\n {\n date: '2020-09-13',\n amount: 3300,\n },\n {\n date: '2020-09-12',\n amount: 2800,\n },\n {\n date: '2020-09-29',\n amount: 2600,\n },\n {\n date: '2020-09-28',\n amount: 4100,\n },\n {\n date: '2020-09-27',\n amount: 3800,\n },\n {\n date: '2020-09-22',\n amount: 3700,\n },\n {\n date: '2020-09-21',\n amount: 2700,\n },\n {\n date: '2020-09-20',\n amount: 2200,\n },\n {\n date: '2020-09-26',\n amount: 3300,\n },\n {\n date: '2020-09-25',\n amount: 4000,\n },\n {\n date: '2020-09-24',\n amount: 3800,\n },\n {\n date: '2020-09-23',\n amount: 4100,\n },\n {\n date: '2020-08-29',\n amount: 4400,\n },\n {\n date: '2020-08-28',\n amount: 5000,\n },\n {\n date: '2020-08-27',\n amount: 4900,\n },\n {\n date: '2020-08-26',\n amount: 4100,\n },\n {\n date: '2020-08-21',\n amount: 3700,\n },\n {\n date: '2020-08-20',\n amount: 2200,\n },\n {\n date: '2020-08-25',\n amount: 1700,\n },\n {\n date: '2020-08-24',\n amount: 2100,\n },\n {\n date: '2020-08-23',\n amount: 3100,\n },\n {\n date: '2020-08-22',\n amount: 1500,\n },\n {\n date: '2020-09-08',\n amount: 2900,\n },\n {\n date: '2020-09-07',\n amount: 4100,\n },\n {\n date: '2020-09-06',\n amount: 3600,\n },\n {\n date: '2020-09-05',\n amount: 3300,\n },\n {\n date: '2020-09-09',\n amount: 2800,\n },\n {\n date: '2020-08-31',\n amount: 3400,\n },\n {\n date: '2020-08-30',\n amount: 4300,\n },\n {\n date: '2020-09-04',\n amount: 6100,\n },\n {\n date: '2020-09-03',\n amount: 2500,\n },\n {\n date: '2020-09-02',\n amount: 4900,\n },\n {\n date: '2020-09-01',\n amount: 6100,\n },\n {\n date: '2020-09-30',\n amount: 5500,\n },\n];\n\nexport const MockBigQueryInsights: Entity = {\n id: 'bigQuery',\n aggregation: [10_000, 30_000],\n change: {\n ratio: 3,\n amount: 20_000,\n },\n entities: {\n dataset: [\n {\n id: 'dataset-a',\n aggregation: [5_000, 10_000],\n change: {\n ratio: 1,\n amount: 5_000,\n },\n entities: {},\n },\n {\n id: 'dataset-b',\n aggregation: [5_000, 10_000],\n change: {\n ratio: 1,\n amount: 5_000,\n },\n entities: {},\n },\n {\n id: 'dataset-c',\n aggregation: [0, 10_000],\n change: {\n amount: 10_000,\n },\n entities: {},\n },\n ],\n },\n};\n\nexport const MockCloudDataflowInsights: Entity = {\n id: 'cloudDataflow',\n aggregation: [100_000, 158_000],\n change: {\n ratio: 0.58,\n amount: 58_000,\n },\n entities: {\n pipeline: [\n {\n id: null,\n aggregation: [10_000, 12_000],\n change: {\n ratio: 0.2,\n amount: 2_000,\n },\n entities: {\n SKU: [\n {\n id: 'Mock SKU A',\n aggregation: [3_000, 4_000],\n change: {\n ratio: 0.333333,\n amount: 1_000,\n },\n entities: {},\n },\n {\n id: 'Mock SKU B',\n aggregation: [7_000, 8_000],\n change: {\n ratio: 0.14285714,\n amount: 1_000,\n },\n entities: {},\n },\n ],\n },\n },\n {\n id: 'pipeline-a',\n aggregation: [60_000, 70_000],\n change: {\n ratio: 0.16666666666666666,\n amount: 10_000,\n },\n entities: {\n SKU: [\n {\n id: 'Mock SKU A',\n aggregation: [20_000, 15_000],\n change: {\n ratio: -0.25,\n amount: -5_000,\n },\n entities: {},\n },\n {\n id: 'Mock SKU B',\n aggregation: [30_000, 35_000],\n change: {\n ratio: -0.16666666666666666,\n amount: -5_000,\n },\n entities: {},\n },\n {\n id: 'Mock SKU C',\n aggregation: [10_000, 20_000],\n change: {\n ratio: 1,\n amount: 10_000,\n },\n entities: {},\n },\n ],\n },\n },\n {\n id: 'pipeline-b',\n aggregation: [12_000, 8_000],\n change: {\n ratio: -0.33333,\n amount: -4_000,\n },\n entities: {\n SKU: [\n {\n id: 'Mock SKU A',\n aggregation: [4_000, 4_000],\n change: {\n ratio: 0,\n amount: 0,\n },\n entities: {},\n },\n {\n id: 'Mock SKU B',\n aggregation: [8_000, 4_000],\n change: {\n ratio: -0.5,\n amount: -4_000,\n },\n entities: {},\n },\n ],\n },\n },\n {\n id: 'pipeline-c',\n aggregation: [0, 10_000],\n change: {\n amount: 10_000,\n },\n entities: {},\n },\n ],\n },\n};\n\nexport const MockCloudStorageInsights: Entity = {\n id: 'cloudStorage',\n aggregation: [45_000, 45_000],\n change: {\n ratio: 0,\n amount: 0,\n },\n entities: {\n bucket: [\n {\n id: 'bucket-a',\n aggregation: [15_000, 20_000],\n change: {\n ratio: 0.333,\n amount: 5_000,\n },\n entities: {\n SKU: [\n {\n id: 'Mock SKU A',\n aggregation: [10_000, 11_000],\n change: {\n ratio: 0.1,\n amount: 1_000,\n },\n entities: {},\n },\n {\n id: 'Mock SKU B',\n aggregation: [2_000, 5_000],\n change: {\n ratio: 1.5,\n amount: 3_000,\n },\n entities: {},\n },\n {\n id: 'Mock SKU C',\n aggregation: [3_000, 4_000],\n change: {\n ratio: 0.3333,\n amount: 1_000,\n },\n entities: {},\n },\n ],\n },\n },\n {\n id: 'bucket-b',\n aggregation: [30_000, 25_000],\n change: {\n ratio: -0.16666,\n amount: -5_000,\n },\n entities: {\n SKU: [\n {\n id: 'Mock SKU A',\n aggregation: [12_000, 13_000],\n change: {\n ratio: 0.08333333333333333,\n amount: 1_000,\n },\n entities: {},\n },\n {\n id: 'Mock SKU B',\n aggregation: [16_000, 12_000],\n change: {\n ratio: -0.25,\n amount: -4_000,\n },\n entities: {},\n },\n {\n id: 'Mock SKU C',\n aggregation: [2_000, 0],\n change: {\n amount: -2000,\n },\n entities: {},\n },\n ],\n },\n },\n {\n id: 'bucket-c',\n aggregation: [0, 0],\n change: {\n amount: 0,\n },\n entities: {},\n },\n ],\n },\n};\n\nexport const MockComputeEngineInsights: Entity = {\n id: 'computeEngine',\n aggregation: [80_000, 90_000],\n change: {\n ratio: 0.125,\n amount: 10_000,\n },\n entities: {\n service: [\n {\n id: 'service-a',\n aggregation: [20_000, 10_000],\n change: {\n ratio: -0.5,\n amount: -10_000,\n },\n entities: {\n SKU: [\n {\n id: 'Mock SKU A',\n aggregation: [4_000, 2_000],\n change: {\n ratio: -0.5,\n amount: -2_000,\n },\n entities: {},\n },\n {\n id: 'Mock SKU B',\n aggregation: [7_000, 6_000],\n change: {\n ratio: -0.14285714285714285,\n amount: -1_000,\n },\n entities: {},\n },\n {\n id: 'Mock SKU C',\n aggregation: [9_000, 2_000],\n change: {\n ratio: -0.7777777777777778,\n amount: -7000,\n },\n entities: {},\n },\n ],\n deployment: [\n {\n id: 'Compute Engine',\n aggregation: [7_000, 6_000],\n change: {\n ratio: -0.5,\n amount: -2_000,\n },\n entities: {},\n },\n {\n id: 'Kubernetes',\n aggregation: [4_000, 2_000],\n change: {\n ratio: -0.14285714285714285,\n amount: -1_000,\n },\n entities: {},\n },\n ],\n },\n },\n {\n id: 'service-b',\n aggregation: [10_000, 20_000],\n change: {\n ratio: 1,\n amount: 10_000,\n },\n entities: {\n SKU: [\n {\n id: 'Mock SKU A',\n aggregation: [1_000, 2_000],\n change: {\n ratio: 1,\n amount: 1_000,\n },\n entities: {},\n },\n {\n id: 'Mock SKU B',\n aggregation: [4_000, 8_000],\n change: {\n ratio: 1,\n amount: 4_000,\n },\n entities: {},\n },\n {\n id: 'Mock SKU C',\n aggregation: [5_000, 10_000],\n change: {\n ratio: 1,\n amount: 5_000,\n },\n entities: {},\n },\n ],\n deployment: [\n {\n id: 'Compute Engine',\n aggregation: [7_000, 6_000],\n change: {\n ratio: -0.5,\n amount: -2_000,\n },\n entities: {},\n },\n {\n id: 'Kubernetes',\n aggregation: [4_000, 2_000],\n change: {\n ratio: -0.14285714285714285,\n amount: -1_000,\n },\n entities: {},\n },\n ],\n },\n },\n {\n id: 'service-c',\n aggregation: [0, 10_000],\n change: {\n amount: 10_000,\n },\n entities: {},\n },\n ],\n },\n};\n\nexport const MockEventsInsights: Entity = {\n id: 'events',\n aggregation: [20_000, 10_000],\n change: {\n ratio: -0.5,\n amount: -10_000,\n },\n entities: {\n event: [\n {\n id: 'event-a',\n aggregation: [15_000, 7_000],\n change: {\n ratio: -0.53333333333,\n amount: -8_000,\n },\n entities: {\n product: [\n {\n id: 'Mock Product A',\n aggregation: [5_000, 2_000],\n change: {\n ratio: -0.6,\n amount: -3_000,\n },\n entities: {},\n },\n {\n id: 'Mock Product B',\n aggregation: [7_000, 2_500],\n change: {\n ratio: -0.64285714285,\n amount: -4_500,\n },\n entities: {},\n },\n {\n id: 'Mock Product C',\n aggregation: [3_000, 2_500],\n change: {\n ratio: -0.16666666666,\n amount: -500,\n },\n entities: {},\n },\n ],\n },\n },\n {\n id: 'event-b',\n aggregation: [5_000, 3_000],\n change: {\n ratio: -0.4,\n amount: -2_000,\n },\n entities: {\n product: [\n {\n id: 'Mock Product A',\n aggregation: [2_000, 1_000],\n change: {\n ratio: -0.5,\n amount: -1_000,\n },\n entities: {},\n },\n {\n id: 'Mock Product B',\n aggregation: [1_000, 1_500],\n change: {\n ratio: 0.5,\n amount: 500,\n },\n entities: {},\n },\n {\n id: 'Mock Product C',\n aggregation: [2_000, 500],\n change: {\n ratio: -0.75,\n amount: -1_500,\n },\n entities: {},\n },\n ],\n },\n },\n ],\n },\n};\n","/*\n * Copyright 2020 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 */\n\nimport React, { PropsWithChildren } from 'react';\nimport {\n LoadingContext,\n LoadingContextProps,\n GroupsContext,\n GroupsContextProps,\n FilterContext,\n FilterContextProps,\n ConfigContext,\n ConfigContextProps,\n CurrencyContext,\n CurrencyContextProps,\n BillingDateContext,\n BillingDateContextProps,\n ScrollContext,\n ScrollContextProps,\n} from '../hooks';\nimport { Duration, EngineerThreshold } from '../types';\nimport { createCurrencyFormat } from '../utils/currency';\n\nexport type MockFilterProviderProps = PropsWithChildren<\n Partial<FilterContextProps>\n>;\n\nexport const MockFilterProvider = ({\n children,\n ...context\n}: MockFilterProviderProps) => {\n const defaultContext: FilterContextProps = {\n pageFilters: {\n group: 'tech',\n project: null,\n duration: Duration.P90D,\n metric: null,\n },\n productFilters: [],\n setPageFilters: jest.fn(),\n setProductFilters: jest.fn(),\n };\n return (\n <FilterContext.Provider value={{ ...defaultContext, ...context }}>\n {children}\n </FilterContext.Provider>\n );\n};\n\nexport type MockLoadingProviderProps = PropsWithChildren<\n Partial<LoadingContextProps>\n>;\n\nexport const MockLoadingProvider = ({\n children,\n ...context\n}: MockLoadingProviderProps) => {\n const defaultContext: LoadingContextProps = {\n state: {},\n actions: [],\n dispatch: jest.fn(),\n };\n return (\n <LoadingContext.Provider value={{ ...defaultContext, ...context }}>\n {children}\n </LoadingContext.Provider>\n );\n};\n\n/** @public */\nexport type MockConfigProviderProps = PropsWithChildren<\n Partial<ConfigContextProps>\n>;\n\n/** @public */\nexport const MockConfigProvider = (props: MockConfigProviderProps) => {\n const { children, ...context } = props;\n\n const defaultContext: ConfigContextProps = {\n baseCurrency: createCurrencyFormat(),\n metrics: [],\n products: [],\n icons: [],\n engineerCost: 0,\n engineerThreshold: EngineerThreshold,\n hideTrendLine: false,\n currencies: [],\n };\n\n return (\n <ConfigContext.Provider value={{ ...defaultContext, ...context }}>\n {children}\n </ConfigContext.Provider>\n );\n};\n\n/** @public */\nexport type MockCurrencyProviderProps = PropsWithChildren<\n Partial<CurrencyContextProps>\n>;\n\n/** @public */\nexport const MockCurrencyProvider = (props: MockCurrencyProviderProps) => {\n const { children, ...context } = props;\n\n const defaultContext: CurrencyContextProps = {\n currency: {\n kind: null,\n label: 'Engineers 🛠',\n unit: 'engineer',\n },\n setCurrency: jest.fn(),\n };\n\n return (\n <CurrencyContext.Provider value={{ ...defaultContext, ...context }}>\n {children}\n </CurrencyContext.Provider>\n );\n};\n\nexport type MockBillingDateProviderProps = PropsWithChildren<\n Partial<BillingDateContextProps>\n>;\n\nexport const MockBillingDateProvider = ({\n children,\n ...context\n}: MockBillingDateProviderProps) => {\n const defaultContext: BillingDateContextProps = {\n lastCompleteBillingDate: '2020-10-01',\n };\n return (\n <BillingDateContext.Provider value={{ ...defaultContext, ...context }}>\n {children}\n </BillingDateContext.Provider>\n );\n};\n\nexport type MockScrollProviderProps = PropsWithChildren<{}>;\n\nexport const MockScrollProvider = ({ children }: MockScrollProviderProps) => {\n const defaultContext: ScrollContextProps = {\n scroll: null,\n setScroll: jest.fn(),\n };\n return (\n <ScrollContext.Provider value={defaultContext}>\n {children}\n </ScrollContext.Provider>\n );\n};\n\nexport type MockGroupsProviderProps = PropsWithChildren<\n Partial<GroupsContextProps>\n>;\n\nexport const MockGroupsProvider = ({\n children,\n ...context\n}: MockGroupsProviderProps) => {\n const defaultContext: GroupsContextProps = {\n groups: [],\n };\n return (\n <GroupsContext.Provider value={{ ...defaultContext, ...context }}>\n {children}\n </GroupsContext.Provider>\n );\n};\n","/*\n * Copyright 2020 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 */\n\nimport { DateTime } from 'luxon';\nimport regression, { DataPoint } from 'regression';\nimport { Duration, DEFAULT_DATE_FORMAT } from '../types';\nimport {\n ChangeStatistic,\n Entity,\n Trendline,\n DateAggregation,\n} from '@backstage-community/plugin-cost-insights-common';\nimport { inclusiveEndDateOf, inclusiveStartDateOf } from '../utils/duration';\nimport {\n MockComputeEngineInsights,\n MockCloudDataflowInsights,\n MockCloudStorageInsights,\n MockBigQueryInsights,\n MockEventsInsights,\n} from './mockData';\n\ntype IntervalFields = {\n duration: Duration;\n endDate: string;\n};\n\nfunction parseIntervals(intervals: string): IntervalFields {\n const match = intervals.match(\n /\\/(?<duration>P\\d+[DM])\\/(?<date>\\d{4}-\\d{2}-\\d{2})/,\n );\n if (Object.keys(match?.groups || {}).length !== 2) {\n throw new Error(`Invalid intervals: ${intervals}`);\n }\n const { duration, date } = match!.groups!;\n return {\n duration: duration as Duration,\n endDate: date,\n };\n}\n\nexport function aggregationFor(\n intervals: string,\n baseline: number,\n): DateAggregation[] {\n const { duration, endDate } = parseIntervals(intervals);\n const inclusiveEndDate = inclusiveEndDateOf(duration, endDate);\n const days = DateTime.fromISO(endDate).diff(\n DateTime.fromISO(inclusiveStartDateOf(duration, inclusiveEndDate)),\n 'days',\n ).days;\n\n function nextDelta(): number {\n const varianceFromBaseline = 0.15;\n // Let's give positive vibes in trendlines - higher change for positive delta with >0.5 value\n const positiveTrendChance = 0.55;\n const normalization = positiveTrendChance - 1;\n return baseline * (Math.random() + normalization) * varianceFromBaseline;\n }\n\n return [...Array(days).keys()].reduce(\n (values: DateAggregation[], i: number): DateAggregation[] => {\n const last = values.length ? values[values.length - 1].amount : baseline;\n const date = DateTime.fromISO(\n inclusiveStartDateOf(duration, inclusiveEndDate),\n )\n .plus({ days: i })\n .toFormat(DEFAULT_DATE_FORMAT);\n const amount = Math.max(0, last + nextDelta());\n values.push({\n date: date,\n amount: amount,\n });\n return values;\n },\n [],\n );\n}\n\nexport function changeOf(aggregation: DateAggregation[]): ChangeStatistic {\n const firstAmount = aggregation.length ? aggregation[0].amount : 0;\n const lastAmount = aggregation.length\n ? aggregation[aggregation.length - 1].amount\n : 0;\n\n // if either the first or last amounts are zero, the rate of increase/decrease is infinite\n if (!firstAmount || !lastAmount) {\n return {\n amount: lastAmount - firstAmount,\n };\n }\n\n return {\n ratio: (lastAmount - firstAmount) / firstAmount,\n amount: lastAmount - firstAmount,\n };\n}\n\nexport function trendlineOf(aggregation: DateAggregation[]): Trendline {\n const data: ReadonlyArray<DataPoint> = aggregation.map(a => [\n Date.parse(a.date) / 1000,\n a.amount,\n ]);\n const result = regression.linear(data, { precision: 5 });\n return {\n slope: result.equation[0],\n intercept: result.equation[1],\n };\n}\n\nexport function entityOf(product: string): Entity {\n switch (product) {\n case 'computeEngine':\n return MockComputeEngineInsights;\n case 'cloudDataflow':\n return MockCloudDataflowInsights;\n case 'cloudStorage':\n return MockCloudStorageInsights;\n case 'bigQuery':\n return MockBigQueryInsights;\n case 'events':\n return MockEventsInsights;\n default:\n throw new Error(\n `Cannot get insights for ${product}. Make sure product matches product property in app-info.yaml`,\n );\n }\n}\n\nexport const getGroupedProducts = (intervals: string) => [\n {\n id: 'Cloud Dataflow',\n aggregation: aggregationFor(intervals, 1_700),\n },\n {\n id: 'Compute Engine',\n aggregation: aggregationFor(intervals, 350),\n },\n {\n id: 'Cloud Storage',\n aggregation: aggregationFor(intervals, 1_300),\n },\n {\n id: 'BigQuery',\n aggregation: aggregationFor(intervals, 2_000),\n },\n {\n id: 'Cloud SQL',\n aggregation: aggregationFor(intervals, 750),\n },\n {\n id: 'Cloud Spanner',\n aggregation: aggregationFor(intervals, 50),\n },\n {\n id: 'Cloud Pub/Sub',\n aggregation: aggregationFor(intervals, 1_000),\n },\n {\n id: 'Cloud Bigtable',\n aggregation: aggregationFor(intervals, 250),\n },\n];\n\nexport const getGroupedProjects = (intervals: string) => [\n {\n id: 'project-a',\n aggregation: aggregationFor(intervals, 1_700),\n },\n {\n id: 'project-b',\n aggregation: aggregationFor(intervals, 350),\n },\n {\n id: 'project-c',\n aggregation: aggregationFor(intervals, 1_300),\n },\n];\n","/*\n * Copyright 2020 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 */\n/* eslint-disable no-restricted-imports */\n\nimport { DateTime } from 'luxon';\nimport { CostInsightsApi, ProductInsightsOptions } from '../api';\nimport {\n Alert,\n DEFAULT_DATE_FORMAT,\n ProjectGrowthData,\n UnlabeledDataflowData,\n} from '../types';\nimport {\n Entity,\n Group,\n MetricData,\n Project,\n Cost,\n} from '@backstage-community/plugin-cost-insights-common';\nimport { KubernetesMigrationAlert } from './alerts';\nimport { ProjectGrowthAlert, UnlabeledDataflowAlert } from '../alerts';\nimport {\n aggregationFor,\n changeOf,\n entityOf,\n getGroupedProducts,\n getGroupedProjects,\n trendlineOf,\n} from '../testUtils';\n\n/** @public */\nexport class ExampleCostInsightsClient implements CostInsightsApi {\n private request(_: any, res: any): Promise<any> {\n return new Promise(resolve => setTimeout(resolve, 0, res));\n }\n\n getLastCompleteBillingDate(): Promise<string> {\n return Promise.resolve(\n DateTime.now().minus({ days: 1 }).toFormat(DEFAULT_DATE_FORMAT),\n );\n }\n\n async getUserGroups(userId: string): Promise<Group[]> {\n const groups: Group[] = await this.request({ userId }, [\n { id: 'group-a', name: 'Group A' },\n { id: 'group-b', name: 'Group B' },\n ]);\n\n return groups;\n }\n\n async getGroupProjects(group: string): Promise<Project[]> {\n const projects: Project[] = await this.request({ group }, [\n { id: 'project-a' },\n { id: 'project-b' },\n { id: 'project-c' },\n ]);\n\n return projects;\n }\n\n async getDailyMetricData(\n metric: string,\n intervals: string,\n ): Promise<MetricData> {\n const aggregation = aggregationFor(intervals, 100_000).map(entry => ({\n ...entry,\n amount: Math.round(entry.amount),\n }));\n\n const cost: MetricData = await this.request(\n { metric, intervals },\n {\n format: 'number',\n aggregation: aggregation,\n change: changeOf(aggregation),\n trendline: trendlineOf(aggregation),\n },\n );\n\n return cost;\n }\n\n async getCatalogEntityDailyCost(\n entityRef: string,\n intervals: string,\n ): Promise<Cost> {\n const aggregation = aggregationFor(intervals, 8_000);\n const groupDailyCost: Cost = await this.request(\n { entityRef, intervals },\n {\n aggregation: aggregation,\n change: changeOf(aggregation),\n trendline: trendlineOf(aggregation),\n // Optional field providing cost groupings / breakdowns keyed by the type. In this example,\n // daily cost grouped by cloud product OR by project / billing account.\n groupedCosts: {\n product: getGroupedProducts(intervals),\n project: getGroupedProjects(intervals),\n },\n },\n );\n\n return groupDailyCost;\n }\n\n async getGroupDailyCost(group: string, intervals: string): Promise<Cost> {\n const aggregation = aggregationFor(intervals, 8_000);\n const groupDailyCost: Cost = await this.request(\n { group, intervals },\n {\n aggregation: aggregation,\n change: changeOf(aggregation),\n trendline: trendlineOf(aggregation),\n // Optional field providing cost groupings / breakdowns keyed by the type. In this example,\n // daily cost grouped by cloud product OR by project / billing account.\n groupedCosts: {\n product: getGroupedProducts(intervals),\n project: getGroupedProjects(intervals),\n },\n },\n );\n\n return groupDailyCost;\n }\n\n async getProjectDailyCost(project: string, intervals: string): Promise<Cost> {\n const aggregation = aggregationFor(intervals, 1_500);\n const projectDailyCost: Cost = await this.request(\n { project, intervals },\n {\n id: 'project-a',\n aggregation: aggregation,\n change: changeOf(aggregation),\n trendline: trendlineOf(aggregation),\n // Optional field providing cost groupings / breakdowns keyed by the type. In this example,\n // daily project cost grouped by cloud product.\n groupedCosts: {\n product: getGroupedProducts(intervals),\n },\n },\n );\n\n return projectDailyCost;\n }\n\n async getProductInsights(options: ProductInsightsOptions): Promise<Entity> {\n const productInsights: Entity = await this.request(\n options,\n entityOf(options.product),\n );\n\n return productInsights;\n }\n\n async getAlerts(group: string): Promise<Alert[]> {\n const projectGrowthData: ProjectGrowthData = {\n project: 'example-project',\n periodStart: '2020-Q2',\n periodEnd: '2020-Q3',\n aggregation: [60_000, 120_000],\n change: {\n ratio: 1,\n amount: 60_000,\n },\n products: [\n { id: 'Compute Engine', aggregation: [58_000, 118_000] },\n { id: 'Cloud Dataflow', aggregation: [1200, 1500] },\n { id: 'Cloud Storage', aggregation: [800, 500] },\n ],\n };\n\n const unlabeledDataflowData: UnlabeledDataflowData = {\n periodStart: '2020-09-01',\n periodEnd: '2020-09-30',\n labeledCost: 6_200,\n unlabeledCost: 7_000,\n projects: [\n {\n id: 'example-project-1',\n unlabeledCost: 5_000,\n labeledCost: 3_000,\n },\n {\n id: 'example-project-2',\n unlabeledCost: 2_000,\n labeledCost: 3_200,\n },\n ],\n };\n\n const today = DateTime.now();\n const alerts: Alert[] = await this.request({ group }, [\n new ProjectGrowthAlert(projectGrowthData),\n new UnlabeledDataflowAlert(unlabeledDataflowData),\n new KubernetesMigrationAlert(this, {\n startDate: today.minus({ days: 30 }).toFormat(DEFAULT_DATE_FORMAT),\n endDate: today.toFormat(DEFAULT_DATE_FORMAT),\n change: {\n ratio: 0,\n amount: 0,\n },\n services: [\n {\n id: 'service-a',\n aggregation: [20_000, 10_000],\n change: {\n ratio: -0.5,\n amount: -10_000,\n },\n entities: {},\n },\n {\n id: 'service-b',\n aggregation: [30_000, 15_000],\n change: {\n ratio: -0.5,\n amount: -15_000,\n },\n entities: {},\n },\n ],\n }),\n ]);\n\n return alerts;\n }\n}\n"],"names":["Duration","AlertStatus","AlertDismissReason","DataKey","ChangeThreshold","GrowthType","CurrencyType","IconType","DefaultNavigation","assertNever","currency","LuxonDuration","DefaultLoadingAction","useStyles","mapLoadingToProps","ScrollType","choose","createMuiTheme","RechartsBarChart","RechartsTooltip","Tooltip","CloseButton","useLayoutStyles","__publicField","getDefaultLoadingState"],"mappings":"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"}