import { Controller } from "@hotwired/stimulus"import { subscription } from "~/javascripts/store/mixins/subscription"import { targetLineValues } from "~/javascripts/dashboard/utils"/** * @class Dashboard.MeanBuildTimesController * @classdesc Stimulus controller that populates the mean build time per build context. * @extends Controller **/export default class extends Controller { static targets = [ "production", "deployPreview", "cms" ] static values = { loading: String, storeId: String } static classes = [ "success", "warning", "error", "unavailable" ] /** * Subscribe to the store. * * @instance * @memberof Dashboard.MeanBuildTimesController **/ connect() { subscription(this) this.subscribe() this.reconnect() } /** * Handles a repeated Turbo visit to the dashboard page. * * @instance * @memberof Dashboard.MeanBuildTimesController **/ reconnect() { if (this.store("selectedDataVizData")) { this.storeUpdated("selectedDataVizData", this.storeIdValue) } } /** * Sets the text for the mean build time and changes the color to match the KPI * * @instance * @memberof Dashboard.MeanBuildTimesController **/ updateMeanBuildTimesValue(target, text, context) { const meanBuildTime = this.calculateMeanBuildTime(context) target.innerHTML = `${text} ${meanBuildTime}` this.removeAlertColors(target) target.classList.add(this.alertColor(meanBuildTime, context)) } /** * Sets the text whilst waiting for the mean build time * * @instance * @memberof Dashboard.MeanBuildTimesController **/ loadingMeanBuildTimesValue(target, text) { target.innerHTML = `${text} ${this.loadingValue}` this.removeAlertColors(target) } /** * @instance * @memberof Dashboard.MeanBuildTimesController **/ calculateMeanBuildTime(context) { const totals = this.store("selectedDataVizData").reduce((acc , data) => { return data.context === context ? { count: acc.count + 1, time: acc.time + data.deploy_time } : acc }, { count: 0, time: 0 }) return Math.round((totals.time / totals.count) * 100) / 100 || "N/A" } /** * Remove all of the color classes for the mean build time * * @instance * @memberof Dashboard.MeanBuildTimesController **/ removeAlertColors(target) { target.classList.remove(this.successClass, this.warningClass, this.errorClass, this.unavailableClass) } /** * Return the color depending on the time in relation to the KPI * * @instance * @memberof Dashboard.MeanBuildTimesController **/ alertColor(value, context) { const lineValues = targetLineValues(context) if (value == "N/A") return this.unavailableClass if (value <= lineValues.successLineValue) return this.successClass if (value <= lineValues.failLineValue) return this.warningClass return this.errorClass } /** * Triggered by the store whenever any store data changes. Controls whether the mean build time should * be populated or display the loading indicator * * @instance * @memberof Dashboard.MeanBuildTimesController **/ storeUpdated(prop, storeId) { if (this.store("fetchingDataVizData")) { this.loadingMeanBuildTimesValue(this.productionTarget, "Production") this.loadingMeanBuildTimesValue(this.deployPreviewTarget, "Deploy preview") this.loadingMeanBuildTimesValue(this.cmsTarget, "CMS") } if (prop === "selectedDataVizData" && storeId === this.storeIdValue) { this.updateMeanBuildTimesValue(this.productionTarget, "Production ...", "production") this.updateMeanBuildTimesValue(this.deployPreviewTarget, "Deploy preview ...", "deploy-preview") this.updateMeanBuildTimesValue(this.cmsTarget, "CMS ...", "cms") } } /** * Unsubscribe from the store * * @instance * @memberof Dashboard.MeanBuildTimesController **/ disconnect() { this.unsubscribe() }}