Repository: louislam/uptime-kuma
File: src/components/HeartbeatBar.vue (Vue)

Code before:
                transform: "translateX(0)",
            };

        },

        beatStyle() {
            return {
                width: this.beatWidth + "px",
                height: this.beatHeight + "px",
                margin: this.beatMargin + "px",
                "--hover-scale": this.hoverScale,
            };
        },

        timeStyle() {
            return {
                "margin-left": this.numPadding * (this.beatWidth + this.beatMargin * 2) + "px",
            };
        },

        /**
         * Calculates the time elapsed since the first valid beat.
         *
         * @return {string} The time elapsed in minutes or hours.
         */
        firstBeatElapsed() {
            const firstValidBeat = this.shortBeatList.at(this.numPadding);
            const minutes = dayjs().diff(dayjs.utc(firstValidBeat?.time), "minutes");
            if (minutes > 60) {
                return (minutes / 60).toFixed(0) + "h";
            } else {
                return minutes + "m";
            }
        },

        /**
         * Calculates the elapsed time since the last valid beat was registered.
         *
         * @return {string} The elapsed time in a human-readable format.
         */
        lastBeatElapsed() {
            const lastValidBeat = this.shortBeatList.at(-1);
            const seconds = dayjs().diff(dayjs.utc(lastValidBeat?.time), "seconds");

            let tolerance = 60 * 2; // default for when monitorList not available
            if (this.$root.monitorList[this.monitorId] != null) {
                tolerance = this.$root.monitorList[this.monitorId].interval * 2;
            }

            if (seconds < tolerance) {
                return "now";

Review comment (suggestion):
Not a strong opinion, but I would prefer `timeSinceFirstBeat` or `elapsedTimeSinceFirstBeat`, as this would be a bit more obvious what is meant just from the name

Code after:
                transform: "translateX(0)",
            };

        },

        beatStyle() {
            return {
                width: this.beatWidth + "px",
                height: this.beatHeight + "px",
                margin: this.beatMargin + "px",
                "--hover-scale": this.hoverScale,
            };
        },

        /**
         * Returns the style object for positioning the time element.
         * @return {Object} The style object containing the CSS properties for positioning the time element.
         */
        timeStyle() {
            return {
                "margin-left": this.numPadding * (this.beatWidth + this.beatMargin * 2) + "px",
            };
        },

        /**
         * Calculates the time elapsed since the first valid beat.
         *
         * @return {string} The time elapsed in minutes or hours.
         */
        timeSinceFirstBeat() {
            const firstValidBeat = this.shortBeatList.at(this.numPadding);
            const minutes = dayjs().diff(dayjs.utc(firstValidBeat?.time), "minutes");
            if (minutes > 60) {
                return (minutes / 60).toFixed(0) + "h";
            } else {
                return minutes + "m";
            }
        },

        /**
         * Calculates the elapsed time since the last valid beat was registered.
         *
         * @return {string} The elapsed time in a minutes, hours or "now".
         */
        timeSinceLastBeat() {
            const lastValidBeat = this.shortBeatList.at(-1);
            const seconds = dayjs().diff(dayjs.utc(lastValidBeat?.time), "seconds");

            let tolerance = 60 * 2; // default for when monitorList not available
            if (this.$root.monitorList[this.monitorId] != null) {
                tolerance = this.$root.monitorList[this.monitorId].interval * 2;