controllers/dashboard/mean_build_times_controller.js

  1. import { Controller } from "@hotwired/stimulus"
  2. import { subscription } from "~/javascripts/store/mixins/subscription"
  3. import { targetLineValues } from "~/javascripts/dashboard/utils"
  4. /**
  5. * @class Dashboard.MeanBuildTimesController
  6. * @classdesc Stimulus controller that populates the mean build time per build context.
  7. * @extends Controller
  8. **/
  9. export default class extends Controller {
  10. static targets = [ "production", "deployPreview", "cms" ]
  11. static values = {
  12. loading: String,
  13. storeId: String
  14. }
  15. static classes = [ "success", "warning", "error", "unavailable" ]
  16. /**
  17. * Subscribe to the store.
  18. *
  19. * @instance
  20. * @memberof Dashboard.MeanBuildTimesController
  21. **/
  22. connect() {
  23. subscription(this)
  24. this.subscribe()
  25. this.reconnect()
  26. }
  27. /**
  28. * Handles a repeated Turbo visit to the dashboard page.
  29. *
  30. * @instance
  31. * @memberof Dashboard.MeanBuildTimesController
  32. **/
  33. reconnect() {
  34. if (this.store("selectedDataVizData")) {
  35. this.storeUpdated("selectedDataVizData", this.storeIdValue)
  36. }
  37. }
  38. /**
  39. * Sets the text for the mean build time and changes the color to match the KPI
  40. *
  41. * @instance
  42. * @memberof Dashboard.MeanBuildTimesController
  43. **/
  44. updateMeanBuildTimesValue(target, text, context) {
  45. const meanBuildTime = this.calculateMeanBuildTime(context)
  46. target.innerHTML = `${text} ${meanBuildTime}`
  47. this.removeAlertColors(target)
  48. target.classList.add(this.alertColor(meanBuildTime, context))
  49. }
  50. /**
  51. * Sets the text whilst waiting for the mean build time
  52. *
  53. * @instance
  54. * @memberof Dashboard.MeanBuildTimesController
  55. **/
  56. loadingMeanBuildTimesValue(target, text) {
  57. target.innerHTML = `${text} ${this.loadingValue}`
  58. this.removeAlertColors(target)
  59. }
  60. /**
  61. * @instance
  62. * @memberof Dashboard.MeanBuildTimesController
  63. **/
  64. calculateMeanBuildTime(context) {
  65. const totals = this.store("selectedDataVizData").reduce((acc , data) => {
  66. return data.context === context ? { count: acc.count + 1, time: acc.time + data.deploy_time } : acc
  67. }, { count: 0, time: 0 })
  68. return Math.round((totals.time / totals.count) * 100) / 100 || "N/A"
  69. }
  70. /**
  71. * Remove all of the color classes for the mean build time
  72. *
  73. * @instance
  74. * @memberof Dashboard.MeanBuildTimesController
  75. **/
  76. removeAlertColors(target) {
  77. target.classList.remove(this.successClass, this.warningClass, this.errorClass, this.unavailableClass)
  78. }
  79. /**
  80. * Return the color depending on the time in relation to the KPI
  81. *
  82. * @instance
  83. * @memberof Dashboard.MeanBuildTimesController
  84. **/
  85. alertColor(value, context) {
  86. const lineValues = targetLineValues(context)
  87. if (value == "N/A") return this.unavailableClass
  88. if (value <= lineValues.successLineValue) return this.successClass
  89. if (value <= lineValues.failLineValue) return this.warningClass
  90. return this.errorClass
  91. }
  92. /**
  93. * Triggered by the store whenever any store data changes. Controls whether the mean build time should
  94. * be populated or display the loading indicator
  95. *
  96. * @instance
  97. * @memberof Dashboard.MeanBuildTimesController
  98. **/
  99. storeUpdated(prop, storeId) {
  100. if (this.store("fetchingDataVizData")) {
  101. this.loadingMeanBuildTimesValue(this.productionTarget, "Production")
  102. this.loadingMeanBuildTimesValue(this.deployPreviewTarget, "Deploy preview")
  103. this.loadingMeanBuildTimesValue(this.cmsTarget, "CMS")
  104. }
  105. if (prop === "selectedDataVizData" && storeId === this.storeIdValue) {
  106. this.updateMeanBuildTimesValue(this.productionTarget, "Production ...", "production")
  107. this.updateMeanBuildTimesValue(this.deployPreviewTarget, "Deploy preview ...", "deploy-preview")
  108. this.updateMeanBuildTimesValue(this.cmsTarget, "CMS ...", "cms")
  109. }
  110. }
  111. /**
  112. * Unsubscribe from the store
  113. *
  114. * @instance
  115. * @memberof Dashboard.MeanBuildTimesController
  116. **/
  117. disconnect() {
  118. this.unsubscribe()
  119. }
  120. }