@fleetbase/ember-ui
Version:
Fleetbase UI provides all the interface components, helpers, services and utilities for building a Fleetbase extension into the Console.
189 lines (164 loc) • 5.72 kB
JavaScript
import Component from '@glimmer/component';
import { tracked } from '@glimmer/tracking';
import { formatDuration, intervalToDuration } from 'date-fns';
import { isArray } from '@ember/array';
import { run } from '@ember/runloop';
import { computed } from '@ember/object';
export default class CountdownComponent extends Component {
/**
* An array that defines the units to display in the countdown.
*
* @memberof CountdownComponent
* @type {Array<string>}
* @default ['seconds']
*/
display = ['seconds'];
/**
* The remaining time in the countdown.
*
* @memberof CountdownComponent
* @type {string}
*/
remaining;
/**
* The duration of the countdown, specified in days, hours, minutes, and seconds.
*
* @memberof CountdownComponent
* @type {Object}
*/
duration = {};
/**
* The interval ID for the countdown timer.
*
* @memberof CountdownComponent
* @type {number}
*/
interval;
/**
* Creates an instance of CountdownComponent.
*
* @param {Object} owner - The owning object.
* @param {Object} options - Options for configuring the countdown.
* @param {Date} options.expiry - The expiration date for the countdown.
* @param {number} options.hours - The initial hours for the countdown.
* @param {number} options.minutes - The initial minutes for the countdown.
* @param {number} options.seconds - The initial seconds for the countdown.
* @param {number} options.days - The initial days for the countdown.
* @param {(string|Array<string>)} options.display - The units to display in the countdown.
*/
constructor(owner, { expiry, hours, minutes, seconds, days, display }) {
super(...arguments);
this.setDuration(
{
days,
hours,
minutes,
seconds,
},
expiry
);
if (display) {
if (typeof display === 'string' && display.includes(',')) {
display = display.split(',');
}
if (isArray(display)) {
this.display = display;
}
}
this.startCountdown();
}
get remainingClass() {
// Customize the threshold and class names as needed
if (this.remaining && this.durationToSeconds(this.duration) <= 5) {
return 'remaining-low'; // Add a CSS class for low time
} else {
return 'remaining-normal'; // Add a default CSS class
}
}
setDuration(duration = {}, expiry) {
if (expiry instanceof Date) {
// use the date provided to set the hours minutes seconds
duration = intervalToDuration({ start: new Date(), end: expiry });
}
// handle when only 2 minutes
if (duration && duration.minutes < 3) {
duration = {
...duration,
seconds: duration.seconds + duration.minutes * 60,
minutes: 0,
};
}
this.duration = duration;
}
/**
* Starts the countdown timer.
*
* @memberof CountdownComponent
* @method
*/
startCountdown() {
this.interval = setInterval(() => {
run(() => {
let { duration } = this;
// if onlyDisplaySeconds === true
if (this.args.onlyDisplaySeconds === true) {
duration = {
seconds: this.durationToSeconds(this.duration),
};
}
this.remaining = formatDuration(duration);
// decrement seconds
duration.seconds--;
// set duration
if (duration.seconds < 0) {
duration.seconds = 0; // Stop the countdown at 0
clearInterval(this.interval);
if (typeof this.args.onCountdownEnd === 'function') {
this.args.onCountdownEnd();
}
if (typeof this.args.onEnd === 'function') {
this.args.onEnd();
}
}
});
}, 1000);
}
/**
* Converts the duration object to total seconds.
*
* @memberof CountdownComponent
* @method
* @param {Object} duration - The duration object.
* @returns {number} - The total seconds.
*/
durationToSeconds(duration) {
const { years = 0, months = 0, weeks = 0, days = 0, hours = 0, minutes = 0, seconds = 0 } = duration;
const totalSeconds = years * 365 * 24 * 60 * 60 + months * 30 * 24 * 60 * 60 + weeks * 7 * 24 * 60 * 60 + days * 24 * 60 * 60 + hours * 60 * 60 + minutes * 60 + seconds;
return totalSeconds;
}
/**
* Restarts the countdown by resetting the timeRemaining property and clearing the interval.
*
* @method restartCountdown
*/
restartCountdown() {
clearInterval(this.interval);
// Reset properties
this.remaining = null;
this.duration = {
days: this.args.days || 0,
hours: this.args.hours || 0,
minutes: this.args.minutes || 0,
seconds: this.args.seconds || 0,
};
this.startCountdown();
}
/**
* Cleans up the interval when the component is being destroyed.
* @method willDestroy
*/
willDestroy() {
super.willDestroy(...arguments);
clearInterval(this.interval);
}
}