commit 77a65ef6ecf0e5683914bd467e4aa99b83c2e656
parent 1828052daf6a5ed1eb59f78af31dd120f0232755
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date: Sun, 22 Jun 2025 13:38:41 -0700
Convert remaining utils to TypeScript
Diffstat:
11 files changed, 435 insertions(+), 365 deletions(-)
diff --git a/src/components/DoubleOutputTable.vue b/src/components/DoubleOutputTable.vue
@@ -30,15 +30,19 @@
import { computed } from 'vue';
import type { PropType } from 'vue';
+import { ResultType } from '@/utils/calculators';
+import type { TargetResult } from '@/utils/calculators';
import { formatDuration, formatNumber } from '@/utils/format';
-import { DISTANCE_UNITS, DISTANCE_UNIT_KEYS } from '@/utils/units';
+import type { Target } from '@/utils/targets';
+import { DistanceUnitData } from '@/utils/units';
+import type { Distance, DistanceTime } from '@/utils/units';
const props = defineProps({
/**
* The method that generates the target table rows
*/
calculateResult: {
- type: Function,
+ type: Function as PropType<(x: DistanceTime, y: Target) => TargetResult>,
required: true,
},
@@ -46,7 +50,7 @@ const props = defineProps({
* The target set
*/
targets: {
- type: Array,
+ type: Array<Target>,
default: () => [],
},
@@ -62,7 +66,7 @@ const props = defineProps({
* The input distance
*/
inputDistance: {
- type: Object as PropType<{ distanceValue: number, distanceUnit: DISTANCE_UNIT_KEYS }>,
+ type: Object as PropType<Distance>,
default: () => ({
distanceValue: 5,
distanceUnit: 'kilometers',
@@ -75,9 +79,9 @@ const props = defineProps({
*/
const results = computed(() => {
// Calculate results
- const results = [[
+ const results: Array<Array<string>> = [[
formatNumber(props.inputDistance.distanceValue, 0, 2, false) + ' '
- + DISTANCE_UNITS[props.inputDistance.distanceUnit].symbol
+ + DistanceUnitData[props.inputDistance.distanceUnit].symbol
]];
props.inputTimes.forEach((input, y) => {
@@ -87,7 +91,7 @@ const results = computed(() => {
const result = props.calculateResult({ ...props.inputDistance, time: input }, target);
if (y === 0) {
- results[0].push(result[result.result === 'key' ? 'value' : 'key']);
+ results[0].push(result[result.result === ResultType.Key ? 'value' : 'key']);
}
row.push(result[result.result]);
diff --git a/src/components/PaceInput.vue b/src/components/PaceInput.vue
@@ -5,8 +5,8 @@
<decimal-input v-model="model.distanceValue"
:aria-label="label + ' distance value'" :min="0" :digits="2"/>
<select v-model="model.distanceUnit" :aria-label="label + ' distance unit'">
- <option v-for="key in DISTANCE_UNIT_KEYS" :key="key" :value="key">
- {{ DISTANCE_UNITS[key].name }}
+ <option v-for="key in DistanceUnits" :key="key" :value="key">
+ {{ DistanceUnitData[key].name }}
</option>
</select>
</div>
@@ -20,18 +20,13 @@
<script setup lang="ts">
import type { PropType } from 'vue';
-import { DISTANCE_UNITS, DISTANCE_UNIT_KEYS } from '@/utils/units';
+import { DistanceUnits, DistanceUnitData } from '@/utils/units';
+import type { DistanceTime } from '@/utils/units';
import DecimalInput from '@/components/DecimalInput.vue';
import TimeInput from '@/components/TimeInput.vue';
import useObjectModel from '@/composables/useObjectModel';
-interface Pace {
- distanceValue: number,
- distanceUnit: DISTANCE_UNIT_KEYS,
- time: number,
-};
-
const props = defineProps({
/**
* The prefix for each field's aria-label
@@ -45,7 +40,7 @@ const props = defineProps({
* The component value
*/
modelValue: {
- type: Object as PropType<Pace>,
+ type: Object as PropType<DistanceTime>,
default: () => ({
distanceValue: 5,
distanceUnit: 'kilometers',
@@ -56,7 +51,8 @@ const props = defineProps({
// Generate internal ref tied to modelValue prop
const emit = defineEmits(['update:modelValue']);
-const model = useObjectModel<Pace>(() => props.modelValue, (x) => emit('update:modelValue', x));
+const model = useObjectModel<DistanceTime>(() => props.modelValue,
+ (x) => emit('update:modelValue', x));
</script>
<style scoped>
diff --git a/src/components/RaceOptions.vue b/src/components/RaceOptions.vue
@@ -20,16 +20,11 @@
<script setup lang="ts">
import type { PropType } from 'vue';
-import { RacePredictionModel } from '@/utils/races';
+import type { RaceOptions } from '@/utils/calculators';
import DecimalInput from '@/components/DecimalInput.vue';
import useObjectModel from '@/composables/useObjectModel';
-interface RaceOptions {
- model: RacePredictionModel,
- riegelExponent: number,
-}
-
const props = defineProps({
/**
* The component value
diff --git a/src/components/SingleOutputTable.vue b/src/components/SingleOutputTable.vue
@@ -36,15 +36,19 @@
</div>
</template>
-<script setup>
+<script setup lang="ts">
import { computed } from 'vue';
+import type { PropType } from 'vue';
+
+import type { TargetResult } from '@/utils/calculators';
+import type { Target } from '@/utils/targets';
const props = defineProps({
/**
* The method that generates the target table rows
*/
calculateResult: {
- type: Function,
+ type: Function as PropType<(x: Target) => TargetResult>,
required: true,
},
@@ -52,7 +56,7 @@ const props = defineProps({
* The target set
*/
targets: {
- type: Array,
+ type: Array<Target>,
default: () => [],
},
@@ -70,7 +74,7 @@ const props = defineProps({
*/
const results = computed(() => {
// Calculate results
- const result = [];
+ const result: Array<TargetResult> = [];
props.targets.forEach((row) => {
// Add result
result.push(props.calculateResult(row));
diff --git a/src/components/SplitOutputTable.vue b/src/components/SplitOutputTable.vue
@@ -19,7 +19,7 @@
<tr v-for="(item, index) in results" :key="index">
<td>
{{ formatNumber(item.distanceValue, 0, 2, false) }}
- {{ DISTANCE_UNITS[item.distanceUnit].symbol }}
+ {{ DistanceUnitData[item.distanceUnit].symbol }}
</td>
<td>
@@ -32,7 +32,7 @@
<td>
{{ formatDuration(item.pace, 3, 0, true) }}
- / {{ DISTANCE_UNITS[getDefaultDistanceUnit(defaultUnitSystem)]
+ / {{ DistanceUnitData[getDefaultDistanceUnit(defaultUnitSystem)]
.symbol }}
</td>
</tr>
@@ -50,7 +50,7 @@
import { computed } from 'vue';
import { formatDuration, formatNumber } from '@/utils/format';
-import { DISTANCE_UNITS, convertDistance, getDefaultDistanceUnit } from '@/utils/units';
+import { DistanceUnitData, convertDistance, getDefaultDistanceUnit } from '@/utils/units';
import TimeInput from '@/components/TimeInput.vue';
import useObjectModel from '@/composables/useObjectModel';
diff --git a/src/components/TargetEditor.vue b/src/components/TargetEditor.vue
@@ -32,7 +32,7 @@
<decimal-input v-model="item.splitValue" aria-label="Split distance value"
:min="0" :digits="2"/>
<select v-model="item.splitUnit" aria-label="Split distance unit">
- <option v-for="(value, key) in DISTANCE_UNITS" :key="key" :value="key">
+ <option v-for="(value, key) in DistanceUnitData" :key="key" :value="key">
{{ value.name }}
</option>
</select>
@@ -46,7 +46,7 @@
<decimal-input v-model="item.distanceValue" aria-label="Target distance value"
:min="0" :digits="2"/>
<select v-model="item.distanceUnit" aria-label="Target distance unit">
- <option v-for="(value, key) in DISTANCE_UNITS" :key="key" :value="key">
+ <option v-for="(value, key) in DistanceUnitData" :key="key" :value="key">
{{ value.name }}
</option>
</select>
@@ -90,7 +90,7 @@
import VueFeather from 'vue-feather';
import { workoutTargetToString } from '@/utils/targets';
-import { DISTANCE_UNITS, getDefaultDistanceUnit } from '@/utils/units';
+import { DistanceUnitData, getDefaultDistanceUnit } from '@/utils/units';
import DecimalInput from '@/components/DecimalInput.vue';
import TimeInput from '@/components/TimeInput.vue';
diff --git a/src/utils/calculators.js b/src/utils/calculators.js
@@ -1,178 +0,0 @@
-import { formatDuration, formatNumber } from '@/utils/format';
-import * as paceUtils from '@/utils/paces';
-import * as raceUtils from '@/utils/races';
-import { workoutTargetToString } from '@/utils/targets';
-import { DISTANCE_UNITS, convertDistance, getDefaultDistanceUnit } from '@/utils/units';
-
-/**
- * Format a distance/time result as a key/value result
- * @param {Object} result The distance/time result
- * @param {String} defaultUnitSystem The default unit system (imperial or metric)
- * @param {Boolean} preciseDurations Whether to return precise, unrounded, durations
- * @returns {Object} The key/value result
- */
-export function formatDistTimeResult(result, defaultUnitSystem, preciseDurations = true) {
- // Calculate numerical pace
- const pace = result.time / convertDistance(result.distanceValue, result.distanceUnit,
- getDefaultDistanceUnit(defaultUnitSystem));
-
- return {
- // Convert distance to key string
- key: formatNumber(result.distanceValue, 0, 2, result.result === 'distance') + ' ' +
- DISTANCE_UNITS[result.distanceUnit].symbol,
-
- // Convert time to time string
- value: formatDuration(result.time, 3, preciseDurations ? 2 : 0, result.result === 'time'),
-
- // Convert pace to pace string
- pace: formatDuration(pace, 3, 0, true) + ' / '
- + DISTANCE_UNITS[getDefaultDistanceUnit(defaultUnitSystem)].symbol,
-
- // Convert dist/time result to key/value
- result: result.result === 'time' ? 'value' : 'key',
-
- // Use time (in seconds) as sort key
- sort: result.time,
- };
-}
-
-/**
- * Calculate paces from a target
- * @param {Object} input The input pace
- * @param {Object} target The pace target
- * @param {String} defaultUnitSystem The default unit system (imperial or metric)
- * @param {Boolean} preciseDurations Whether to return precise, unrounded, durations
- * @returns {Object} The result
- */
-export function calculatePaceResults(input, target, defaultUnitSystem, preciseDurations = true) {
- const result = {
- distanceValue: target.distanceValue,
- distanceUnit: target.distanceUnit,
- time: target.time,
- result: target.type === 'distance' ? 'time' : 'distance',
- };
-
- const d1 = convertDistance(input.distanceValue, input.distanceUnit, 'meters');
-
- // Add missing value to result
- if (target.type === 'distance') {
- // Convert target distance into meters
- const d2 = convertDistance(target.distanceValue, target.distanceUnit, 'meters');
-
- // Calculate time to travel distance at input pace
- result.time = paceUtils.calculateTime(d1, input.time, d2);
- } else {
- // Calculate distance traveled in time at input pace
- const d2 = paceUtils.calculateDistance(input.time, d1, target.time);
-
- // Convert output distance into default distance unit
- const units = getDefaultDistanceUnit(defaultUnitSystem);
- result.distanceValue = convertDistance(d2, 'meters', units);
- result.distanceUnit = units;
- }
-
- // Return result
- return formatDistTimeResult(result, defaultUnitSystem, preciseDurations);
-}
-
-/**
- * Predict race results from a target
- * @param {Object} input The input race
- * @param {Object} target The race target
- * @param {Object} options The race prediction options
- * @param {String} defaultUnitSystem The default unit system (imperial or metric)
- * @param {Boolean} preciseDurations Whether to return precise, unrounded, durations
- * @returns {Object} The result
- */
-export function calculateRaceResults(input, target, options, defaultUnitSystem,
- preciseDurations = true) {
-
- const result = {
- distanceValue: target.distanceValue,
- distanceUnit: target.distanceUnit,
- time: target.time,
- result: target.type === 'distance' ? 'time' : 'distance',
- };
-
- const d1 = convertDistance(input.distanceValue, input.distanceUnit, 'meters');
-
- // Add missing value to result
- if (target.type === 'distance') {
- // Convert target distance into meters
- const d2 = convertDistance(target.distanceValue, target.distanceUnit, 'meters');
-
- // Get prediction
- result.time = raceUtils.predictTime(d1, input.time, d2, options.model, options.riegelExponent);
- } else {
- // Get prediction
- let distance = raceUtils.predictDistance(input.time, d1, target.time, options.model,
- options.riegelExponent);
-
- // Convert output distance into default distance unit
- distance = convertDistance(distance, 'meters',
- getDefaultDistanceUnit(defaultUnitSystem));
-
- // Update result
- result.distanceValue = distance;
- result.distanceUnit = getDefaultDistanceUnit(defaultUnitSystem);
- }
-
- // Return result
- return formatDistTimeResult(result, defaultUnitSystem, preciseDurations);
-}
-
-/**
- * Calculate race statistics from an input race
- * @param {Object} input The input race
- * @returns {Object} The race statistics
- */
-export function calculateRaceStats(input) {
- const d1 = convertDistance(input.distanceValue, input.distanceUnit, 'meters');
-
- return {
- purdyPoints: raceUtils.getPurdyPoints(d1, input.time),
- vo2Max: raceUtils.getVO2Max(d1, input.time),
- vo2: raceUtils.getVO2(d1, input.time),
- vo2MaxPercentage: raceUtils.getVO2Percentage(input.time) * 100,
- }
-}
-
-/**
- * Predict workout results from a target
- * @param {Object} input The input race
- * @param {Object} target The workout target
- * @param {Object} options The workout options
- * @param {Boolean} preciseDurations Whether to return precise, unrounded, durations
- * @returns {Object} The result
- */
-export function calculateWorkoutResults(input, target, options, preciseDurations = true) {
- // Initialize distance and time variables
- const d1 = convertDistance(input.distanceValue, input.distanceUnit, 'meters');
- const t1 = input.time;
- const d3 = convertDistance(target.splitValue, target.splitUnit, 'meters');
- let d2, t2, t3;
-
- // Calculate result
- if (target.type === 'distance') {
- // Convert target distance into meters
- d2 = convertDistance(target.distanceValue, target.distanceUnit, 'meters');
-
- // Get workout split prediction
- t2 = raceUtils.predictTime(d1, input.time, d2, options.model, options.riegelExponent);
- } else {
- t2 = target.time;
-
- // Get workout split prediction
- d2 = raceUtils.predictDistance(t1, d1, t2, options.model, options.riegelExponent);
- }
- t3 = paceUtils.calculateTime(d2, t2, d3);
-
- // Return result
- return {
- key: (options.customTargetNames && target.customName) || workoutTargetToString(target),
- value: formatDuration(t3, 3, preciseDurations ? 2 : 0, true),
- pace: '', // Pace not used in workout calculator
- result: 'value',
- sort: t3,
- }
-}
diff --git a/src/utils/calculators.ts b/src/utils/calculators.ts
@@ -0,0 +1,234 @@
+import { formatDuration, formatNumber } from '@/utils/format';
+import * as paceUtils from '@/utils/paces';
+import * as raceUtils from '@/utils/races';
+import { TargetType, workoutTargetToString } from '@/utils/targets';
+import type { StandardTarget, WorkoutTarget } from '@/utils/targets';
+import { DistanceUnits, DistanceUnitData, UnitSystems, convertDistance,
+ getDefaultDistanceUnit } from '@/utils/units';
+import type { DistanceTime } from '@/utils/units';
+
+export enum ResultType {
+ Key = 'key',
+ Value = 'value',
+};
+
+interface PreResult {
+ distanceValue: number,
+ distanceUnit: DistanceUnits,
+ result: TargetType,
+ time: number,
+};
+
+export interface TargetResult {
+ key: string,
+ value: string,
+ pace: string,
+ result: ResultType,
+ sort: number,
+};
+
+export interface RaceOptions {
+ model: raceUtils.RacePredictionModel,
+ riegelExponent: number,
+}
+
+export interface RaceStats {
+ purdyPoints: number,
+ vo2Max: number,
+ vo2: number,
+ vo2MaxPercentage: number,
+}
+
+export interface WorkoutOptions extends RaceOptions {
+ customTargetNames: boolean,
+}
+
+/**
+ * Format a distance/time result as a key/value result
+ * @param {PreResult} result The distance/time result
+ * @param {UnitSystems} defaultUnitSystem The default unit system (imperial or metric)
+ * @param {Boolean} preciseDurations Whether to return precise, unrounded, durations
+ * @returns {TargetResult} The key/value result
+ */
+export function formatTargetResult(result: PreResult, defaultUnitSystem: UnitSystems,
+ preciseDurations: boolean = true): TargetResult {
+ // Calculate numerical pace
+ const pace = result.time / convertDistance(result.distanceValue, result.distanceUnit,
+ getDefaultDistanceUnit(defaultUnitSystem));
+
+ return {
+ // Convert distance to key string
+ key: formatNumber(result.distanceValue, 0, 2, result.result === 'distance') + ' ' +
+ DistanceUnitData[result.distanceUnit].symbol,
+
+ // Convert time to time string
+ value: formatDuration(result.time, 3, preciseDurations ? 2 : 0, result.result === 'time'),
+
+ // Convert pace to pace string
+ pace: formatDuration(pace, 3, 0, true) + ' / '
+ + DistanceUnitData[getDefaultDistanceUnit(defaultUnitSystem)].symbol,
+
+ // Convert dist/time result to key/value
+ result: result.result === TargetType.Time ? ResultType.Value : ResultType.Key,
+
+ // Use time (in seconds) as sort key
+ sort: result.time,
+ };
+}
+
+/**
+ * Calculate paces from a target
+ * @param {DistanceTime } input The input pace
+ * @param {StandardTarget} target The pace target
+ * @param {UnitSystems} defaultUnitSystem The default unit system (imperial or metric)
+ * @param {Boolean} preciseDurations Whether to return precise, unrounded, durations
+ * @returns {TargetResult} The result
+ */
+export function calculatePaceResults(input: DistanceTime, target: StandardTarget,
+ defaultUnitSystem: UnitSystems,
+ preciseDurations: boolean = true): TargetResult {
+ const result: PreResult = {
+ distanceValue: 0,
+ distanceUnit: DistanceUnits.Meters,
+ time: 0,
+ result: target.type === TargetType.Distance ? TargetType.Time : TargetType.Distance,
+ };
+
+ const d1 = convertDistance(input.distanceValue, input.distanceUnit, DistanceUnits.Meters);
+
+ // Add missing value to result
+ if (target.type === 'distance') {
+ // Add target distance to result
+ result.distanceValue = target.distanceValue;
+ result.distanceUnit = target.distanceUnit;
+
+ // Convert target distance into meters
+ const d2 = convertDistance(target.distanceValue, target.distanceUnit, DistanceUnits.Meters);
+
+ // Calculate time to travel distance at input pace
+ result.time = paceUtils.calculateTime(d1, input.time, d2);
+ } else {
+ // Add target time to result
+ result.time = target.time;
+
+ // Calculate distance traveled in time at input pace
+ const d2 = paceUtils.calculateDistance(input.time, d1, target.time);
+
+ // Convert output distance into default distance unit
+ const units = getDefaultDistanceUnit(defaultUnitSystem);
+ result.distanceValue = convertDistance(d2, DistanceUnits.Meters, units);
+ result.distanceUnit = units;
+ }
+
+ // Return result
+ return formatTargetResult(result, defaultUnitSystem, preciseDurations);
+}
+
+/**
+ * Predict race results from a target
+ * @param {DistanceTime} input The input race
+ * @param {StandardTarget} target The race target
+ * @param {RaceOptions} options The race prediction options
+ * @param {UnitSystems} defaultUnitSystem The default unit system (imperial or metric)
+ * @param {Boolean} preciseDurations Whether to return precise, unrounded, durations
+ * @returns {TargetResult} The result
+ */
+export function calculateRaceResults(input: DistanceTime, target: StandardTarget,
+ options: RaceOptions, defaultUnitSystem: UnitSystems,
+ preciseDurations: boolean = true): TargetResult {
+
+ const result: PreResult = {
+ distanceValue: 0,
+ distanceUnit: DistanceUnits.Meters,
+ time: 0,
+ result: target.type === TargetType.Distance ? TargetType.Time : TargetType.Distance,
+ };
+
+ const d1 = convertDistance(input.distanceValue, input.distanceUnit, DistanceUnits.Meters);
+
+ // Add missing value to result
+ if (target.type === 'distance') {
+ // Add target distance to result
+ result.distanceValue = target.distanceValue;
+ result.distanceUnit = target.distanceUnit;
+
+ // Convert target distance into meters
+ const d2 = convertDistance(target.distanceValue, target.distanceUnit, DistanceUnits.Meters);
+
+ // Get prediction
+ result.time = raceUtils.predictTime(d1, input.time, d2, options.model, options.riegelExponent);
+ } else {
+ // Add target time to result
+ result.time = target.time;
+
+ // Get prediction
+ const distance = raceUtils.predictDistance(input.time, d1, target.time, options.model,
+ options.riegelExponent);
+
+ // Convert output distance into default distance unit
+ const units = getDefaultDistanceUnit(defaultUnitSystem);
+ result.distanceValue = convertDistance(distance, DistanceUnits.Meters, units);
+ result.distanceUnit = getDefaultDistanceUnit(defaultUnitSystem);
+ }
+
+ // Return result
+ return formatTargetResult(result, defaultUnitSystem, preciseDurations);
+}
+
+/**
+ * Calculate race statistics from an input race
+ * @param {DistanceTime} input The input race
+ * @returns {RaceStats} The race statistics
+ */
+export function calculateRaceStats(input: DistanceTime): RaceStats {
+ const d1 = convertDistance(input.distanceValue, input.distanceUnit, DistanceUnits.Meters);
+
+ return {
+ purdyPoints: raceUtils.getPurdyPoints(d1, input.time),
+ vo2Max: raceUtils.getVO2Max(d1, input.time),
+ vo2: raceUtils.getVO2(d1, input.time),
+ vo2MaxPercentage: raceUtils.getVO2Percentage(input.time) * 100,
+ }
+}
+
+/**
+ * Predict workout results from a target
+ * @param {DistanceTime} input The input race
+ * @param {WorkoutTarget} target The workout target
+ * @param {WorkoutOptions} options The workout options
+ * @param {Boolean} preciseDurations Whether to return precise, unrounded, durations
+ * @returns {TargetResult} The result
+ */
+export function calculateWorkoutResults(input: DistanceTime, target: WorkoutTarget,
+ options: WorkoutOptions,
+ preciseDurations: boolean = true): TargetResult {
+ // Initialize distance and time variables
+ const d1 = convertDistance(input.distanceValue, input.distanceUnit, DistanceUnits.Meters);
+ const t1 = input.time;
+ const d3 = convertDistance(target.splitValue, target.splitUnit, DistanceUnits.Meters);
+ let d2, t2;
+
+ // Calculate result
+ if (target.type === 'distance') {
+ // Convert target distance into meters
+ d2 = convertDistance(target.distanceValue, target.distanceUnit, DistanceUnits.Meters);
+
+ // Get workout split prediction
+ t2 = raceUtils.predictTime(d1, input.time, d2, options.model, options.riegelExponent);
+ } else {
+ t2 = target.time;
+
+ // Get workout split prediction
+ d2 = raceUtils.predictDistance(t1, d1, t2, options.model, options.riegelExponent);
+ }
+ const t3 = paceUtils.calculateTime(d2, t2, d3);
+
+ // Return result
+ return {
+ key: (options.customTargetNames && target.customName) || workoutTargetToString(target),
+ value: formatDuration(t3, 3, preciseDurations ? 2 : 0, true),
+ pace: '', // Pace not used in workout calculator
+ result: ResultType.Value,
+ sort: t3,
+ }
+}
diff --git a/src/utils/targets.ts b/src/utils/targets.ts
@@ -1,5 +1,5 @@
import { formatDuration, formatNumber } from '@/utils/format';
-import { DISTANCE_UNITS, DISTANCE_UNIT_KEYS, convertDistance } from '@/utils/units';
+import { DistanceUnits, DistanceUnitData, convertDistance } from '@/utils/units';
/*
* Enumeration for the two basic types of targets: those defined by distance vs time
@@ -15,7 +15,7 @@ export enum TargetType {
interface DistanceTarget {
type: TargetType.Distance,
distanceValue: number,
- distanceUnit: DISTANCE_UNIT_KEYS,
+ distanceUnit: DistanceUnits,
};
/**
@@ -59,7 +59,8 @@ export interface SplitTargetSet {
*/
export type WorkoutTarget = StandardTarget & {
splitValue: number,
- splitUnit: DISTANCE_UNIT_KEYS,
+ splitUnit: DistanceUnits,
+ customName?: string,
};
/*
@@ -83,8 +84,8 @@ export type Target = StandardTarget | SplitTarget | WorkoutTarget;
export function sort(targets: Array<Target>): Array<Target> {
return [
...targets.filter((item) => item.type === TargetType.Distance)
- .sort((a, b) => convertDistance(a.distanceValue, a.distanceUnit, DISTANCE_UNIT_KEYS.meters)
- - convertDistance(b.distanceValue, b.distanceUnit, DISTANCE_UNIT_KEYS.meters)),
+ .sort((a, b) => convertDistance(a.distanceValue, a.distanceUnit, DistanceUnits.Meters)
+ - convertDistance(b.distanceValue, b.distanceUnit, DistanceUnits.Meters)),
...targets.filter((item) => item.type === TargetType.Time)
.sort((a, b) => a.time - b.time),
@@ -98,12 +99,12 @@ export function sort(targets: Array<Target>): Array<Target> {
*/
export function workoutTargetToString(target: WorkoutTarget): string {
let result = formatNumber(target.splitValue, 0, 2, false) + ' ' +
- DISTANCE_UNITS[target.splitUnit].symbol;
+ DistanceUnitData[target.splitUnit].symbol;
if (target.type === TargetType.Time) {
result += ' @ ' + formatDuration(target.time, 3, 2, false);
} else if (target.distanceValue != target.splitValue || target.distanceUnit != target.splitUnit) {
result += ' @ ' + formatNumber(target.distanceValue, 0, 2, false) + ' ' +
- DISTANCE_UNITS[target.distanceUnit].symbol;
+ DistanceUnitData[target.distanceUnit].symbol;
}
return result;
}
@@ -114,36 +115,36 @@ export function workoutTargetToString(target: WorkoutTarget): string {
const common_pace_targets: StandardTargetSet = {
name: 'Common Pace Targets',
targets: sort([
- { type: TargetType.Distance, distanceValue: 100, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 200, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 300, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 400, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 600, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 800, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 1000, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 1200, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 1500, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 1600, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 3200, distanceUnit: DISTANCE_UNIT_KEYS.meters },
-
- { type: TargetType.Distance, distanceValue: 2, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
- { type: TargetType.Distance, distanceValue: 3, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
- { type: TargetType.Distance, distanceValue: 4, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
- { type: TargetType.Distance, distanceValue: 5, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
- { type: TargetType.Distance, distanceValue: 6, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
- { type: TargetType.Distance, distanceValue: 8, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
- { type: TargetType.Distance, distanceValue: 10, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
-
- { type: TargetType.Distance, distanceValue: 1, distanceUnit: DISTANCE_UNIT_KEYS.miles },
- { type: TargetType.Distance, distanceValue: 2, distanceUnit: DISTANCE_UNIT_KEYS.miles },
- { type: TargetType.Distance, distanceValue: 3, distanceUnit: DISTANCE_UNIT_KEYS.miles },
- { type: TargetType.Distance, distanceValue: 5, distanceUnit: DISTANCE_UNIT_KEYS.miles },
- { type: TargetType.Distance, distanceValue: 6, distanceUnit: DISTANCE_UNIT_KEYS.miles },
- { type: TargetType.Distance, distanceValue: 8, distanceUnit: DISTANCE_UNIT_KEYS.miles },
- { type: TargetType.Distance, distanceValue: 10, distanceUnit: DISTANCE_UNIT_KEYS.miles },
-
- { type: TargetType.Distance, distanceValue: 0.5, distanceUnit: DISTANCE_UNIT_KEYS.marathons },
- { type: TargetType.Distance, distanceValue: 1, distanceUnit: DISTANCE_UNIT_KEYS.marathons },
+ { type: TargetType.Distance, distanceValue: 100, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 200, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 300, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 400, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 600, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 800, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 1000, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 1200, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 1500, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 1600, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 3200, distanceUnit: DistanceUnits.Meters },
+
+ { type: TargetType.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Kilometers },
+ { type: TargetType.Distance, distanceValue: 3, distanceUnit: DistanceUnits.Kilometers },
+ { type: TargetType.Distance, distanceValue: 4, distanceUnit: DistanceUnits.Kilometers },
+ { type: TargetType.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers },
+ { type: TargetType.Distance, distanceValue: 6, distanceUnit: DistanceUnits.Kilometers },
+ { type: TargetType.Distance, distanceValue: 8, distanceUnit: DistanceUnits.Kilometers },
+ { type: TargetType.Distance, distanceValue: 10, distanceUnit: DistanceUnits.Kilometers },
+
+ { type: TargetType.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles },
+ { type: TargetType.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Miles },
+ { type: TargetType.Distance, distanceValue: 3, distanceUnit: DistanceUnits.Miles },
+ { type: TargetType.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Miles },
+ { type: TargetType.Distance, distanceValue: 6, distanceUnit: DistanceUnits.Miles },
+ { type: TargetType.Distance, distanceValue: 8, distanceUnit: DistanceUnits.Miles },
+ { type: TargetType.Distance, distanceValue: 10, distanceUnit: DistanceUnits.Miles },
+
+ { type: TargetType.Distance, distanceValue: 0.5, distanceUnit: DistanceUnits.Marathons },
+ { type: TargetType.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Marathons },
{ type: TargetType.Time, time: 600 },
{ type: TargetType.Time, time: 1800 },
@@ -157,24 +158,24 @@ const common_pace_targets: StandardTargetSet = {
const common_race_targets: StandardTargetSet = {
name: 'Common Race Targets',
targets: sort([
- { type: TargetType.Distance, distanceValue: 400, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 800, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 1500, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 1600, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 1, distanceUnit: DISTANCE_UNIT_KEYS.miles },
- { type: TargetType.Distance, distanceValue: 3000, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 3200, distanceUnit: DISTANCE_UNIT_KEYS.meters },
- { type: TargetType.Distance, distanceValue: 2, distanceUnit: DISTANCE_UNIT_KEYS.miles },
-
- { type: TargetType.Distance, distanceValue: 3, distanceUnit: DISTANCE_UNIT_KEYS.miles },
- { type: TargetType.Distance, distanceValue: 5, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
- { type: TargetType.Distance, distanceValue: 6, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
- { type: TargetType.Distance, distanceValue: 8, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
- { type: TargetType.Distance, distanceValue: 10, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
- { type: TargetType.Distance, distanceValue: 15, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
-
- { type: TargetType.Distance, distanceValue: 0.5, distanceUnit: DISTANCE_UNIT_KEYS.marathons },
- { type: TargetType.Distance, distanceValue: 1, distanceUnit: DISTANCE_UNIT_KEYS.marathons },
+ { type: TargetType.Distance, distanceValue: 400, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 800, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 1500, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 1600, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles },
+ { type: TargetType.Distance, distanceValue: 3000, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 3200, distanceUnit: DistanceUnits.Meters },
+ { type: TargetType.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Miles },
+
+ { type: TargetType.Distance, distanceValue: 3, distanceUnit: DistanceUnits.Miles },
+ { type: TargetType.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers },
+ { type: TargetType.Distance, distanceValue: 6, distanceUnit: DistanceUnits.Kilometers },
+ { type: TargetType.Distance, distanceValue: 8, distanceUnit: DistanceUnits.Kilometers },
+ { type: TargetType.Distance, distanceValue: 10, distanceUnit: DistanceUnits.Kilometers },
+ { type: TargetType.Distance, distanceValue: 15, distanceUnit: DistanceUnits.Kilometers },
+
+ { type: TargetType.Distance, distanceValue: 0.5, distanceUnit: DistanceUnits.Marathons },
+ { type: TargetType.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Marathons },
]),
};
@@ -185,9 +186,9 @@ const common_race_targets: StandardTargetSet = {
const five_k_mile_splits: SplitTargetSet = {
name: '5K Mile Splits',
targets: [
- { type: TargetType.Distance, distanceValue: 1, distanceUnit: DISTANCE_UNIT_KEYS.miles },
- { type: TargetType.Distance, distanceValue: 2, distanceUnit: DISTANCE_UNIT_KEYS.miles },
- { type: TargetType.Distance, distanceValue: 5, distanceUnit: DISTANCE_UNIT_KEYS.kilometers },
+ { type: TargetType.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles },
+ { type: TargetType.Distance, distanceValue: 2, distanceUnit: DistanceUnits.Miles },
+ { type: TargetType.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers },
],
};
@@ -198,20 +199,20 @@ const common_workout_targets: WorkoutTargetSet = {
name: 'Common Workout Targets',
targets: [
{
- splitValue: 400, splitUnit: DISTANCE_UNIT_KEYS.meters,
- type: TargetType.Distance, distanceValue: 1, distanceUnit: DISTANCE_UNIT_KEYS.miles,
+ splitValue: 400, splitUnit: DistanceUnits.Meters,
+ type: TargetType.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Miles,
},
{
- splitValue: 800, splitUnit: DISTANCE_UNIT_KEYS.meters,
- type: TargetType.Distance, distanceValue: 5, distanceUnit: DISTANCE_UNIT_KEYS.kilometers,
+ splitValue: 800, splitUnit: DistanceUnits.Meters,
+ type: TargetType.Distance, distanceValue: 5, distanceUnit: DistanceUnits.Kilometers,
},
{
- splitValue: 1600, splitUnit: DISTANCE_UNIT_KEYS.meters,
+ splitValue: 1600, splitUnit: DistanceUnits.Meters,
type: TargetType.Time, time: 3600,
},
{
- splitValue: 1, splitUnit: DISTANCE_UNIT_KEYS.miles,
- type: TargetType.Distance, distanceValue: 1, distanceUnit: DISTANCE_UNIT_KEYS.marathons,
+ splitValue: 1, splitUnit: DistanceUnits.Miles,
+ type: TargetType.Distance, distanceValue: 1, distanceUnit: DistanceUnits.Marathons,
},
],
};
diff --git a/src/utils/units.ts b/src/utils/units.ts
@@ -1,41 +1,23 @@
-export enum TIME_UNIT_KEYS {
- seconds = 'seconds',
- minutes = 'minutes',
- hours = 'hours',
-}
-export enum DISTANCE_UNIT_KEYS {
- meters = 'meters',
- yards = 'yards',
- kilometers = 'kilometers',
- miles = 'miles',
- marathons = 'marathons',
-}
-export enum SPEED_UNIT_KEYS {
- meters_per_second = 'meters_per_second',
- kilometers_per_hour = 'kilometers_per_hour',
- miles_per_hour = 'miles_per_hour',
-}
-export enum PACE_UNIT_KEYS {
- seconds_per_meter = 'seconds_per_meter',
- time_per_kilometer = 'seconds_per_kilometer',
- time_per_mile = 'seconds_per_mile',
-}
-
/**
- * The time units
+ * The supported time units
*/
-export const TIME_UNITS = {
- seconds: {
+export enum TimeUnits {
+ Seconds = 'seconds',
+ Minutes = 'minutes',
+ Hours = 'hours',
+}
+export const TimeUnitData = {
+ [TimeUnits.Seconds]: {
name: 'Seconds',
symbol: 's',
value: 1,
},
- minutes: {
+ [TimeUnits.Minutes]: {
name: 'Minutes',
symbol: 'min',
value: 60,
},
- hours: {
+ [TimeUnits.Hours]: {
name: 'Hours',
symbol: 'hr',
value: 3600,
@@ -43,30 +25,37 @@ export const TIME_UNITS = {
};
/**
- * The distance units
+ * The supported distance units
*/
-export const DISTANCE_UNITS = {
- meters: {
+export enum DistanceUnits {
+ Meters = 'meters',
+ Yards = 'yards',
+ Kilometers = 'kilometers',
+ Miles = 'miles',
+ Marathons = 'marathons',
+}
+export const DistanceUnitData = {
+ [DistanceUnits.Meters]: {
name: 'Meters',
symbol: 'm',
value: 1,
},
- yards: {
+ [DistanceUnits.Yards]: {
name: 'Yards',
symbol: 'yd',
value: 0.9144,
},
- kilometers: {
+ [DistanceUnits.Kilometers]: {
name: 'Kilometers',
symbol: 'km',
value: 1000,
},
- miles: {
+ [DistanceUnits.Miles]: {
name: 'Miles',
symbol: 'mi',
value: 1609.3499,
},
- marathons: {
+ [DistanceUnits.Marathons]: {
name: 'Marathons',
symbol: 'Mar',
value: 42195,
@@ -74,9 +63,14 @@ export const DISTANCE_UNITS = {
};
/**
- * The speed units
+ * The supported speed units
*/
-export const SPEED_UNITS = {
+export enum SpeedUnits {
+ MetersPerSecond = 'meters_per_second',
+ KilometersPerHour = 'kilometers_per_hour',
+ MilesPerHour = 'miles_per_hour',
+}
+export const SpeedUnitData = {
meters_per_second: {
name: 'Meters per Second',
symbol: 'm/s',
@@ -85,36 +79,55 @@ export const SPEED_UNITS = {
kilometers_per_hour: {
name: 'Kilometers per Hour',
symbol: 'kph',
- value: DISTANCE_UNITS.kilometers.value / TIME_UNITS.hours.value,
+ value: DistanceUnitData[DistanceUnits.Kilometers].value / TimeUnitData[TimeUnits.Hours].value,
},
miles_per_hour: {
name: 'Miles per Hour',
symbol: 'mph',
- value: DISTANCE_UNITS.miles.value / TIME_UNITS.hours.value,
+ value: DistanceUnitData[DistanceUnits.Miles].value / TimeUnitData[TimeUnits.Hours].value,
},
};
/**
- * The value of each pace unit in seconds per meter
+ * The supported pace units
*/
-export const PACE_UNITS = {
- seconds_per_meter: {
+export enum PaceUnits {
+ SecondsPerMeter = 'seconds_per_meter',
+ TimePerKilometer = 'seconds_per_kilometer',
+ TimePerMile = 'seconds_per_mile',
+}
+export const PaceUnitData = {
+ [PaceUnits.SecondsPerMeter]: {
name: 'Seconds per Meter',
symbol: 's/m',
value: 1,
},
- seconds_per_kilometer: {
+ [PaceUnits.TimePerKilometer]: {
name: 'Time per Kilometer',
symbol: '/ km',
- value: TIME_UNITS.seconds.value / DISTANCE_UNITS.kilometers.value,
+ value: TimeUnitData[TimeUnits.Seconds].value / DistanceUnitData[DistanceUnits.Kilometers].value,
},
- seconds_per_mile: {
+ [PaceUnits.TimePerMile]: {
name: 'Time per Mile',
symbol: '/ mi',
- value: TIME_UNITS.seconds.value / DISTANCE_UNITS.miles.value,
+ value: TimeUnitData[TimeUnits.Seconds].value / DistanceUnitData[DistanceUnits.Miles].value,
},
};
+export enum UnitSystems {
+ Metric = 'metric',
+ Imperial = 'imperial',
+};
+
+export interface Distance {
+ distanceValue: number,
+ distanceUnit: DistanceUnits,
+}
+
+export interface DistanceTime extends Distance {
+ time: number,
+}
+
/**
* Convert between time units
* @param {number} inputValue The input value
@@ -122,9 +135,9 @@ export const PACE_UNITS = {
* @param {string} outputUnit The unit of the output
* @returns {number} The output
*/
-export function convertTime(inputValue: number, inputUnit: TIME_UNIT_KEYS,
- outputUnit: TIME_UNIT_KEYS): number {
- return (inputValue * TIME_UNITS[inputUnit].value) / TIME_UNITS[outputUnit].value;
+export function convertTime(inputValue: number, inputUnit: TimeUnits,
+ outputUnit: TimeUnits): number {
+ return (inputValue * TimeUnitData[inputUnit].value) / TimeUnitData[outputUnit].value;
}
/**
@@ -134,9 +147,9 @@ export function convertTime(inputValue: number, inputUnit: TIME_UNIT_KEYS,
* @param {string} outputUnit The unit of the output
* @returns {number} The output
*/
-export function convertDistance(inputValue: number, inputUnit: DISTANCE_UNIT_KEYS,
- outputUnit: DISTANCE_UNIT_KEYS): number {
- return (inputValue * DISTANCE_UNITS[inputUnit].value) / DISTANCE_UNITS[outputUnit].value;
+export function convertDistance(inputValue: number, inputUnit: DistanceUnits,
+ outputUnit: DistanceUnits): number {
+ return (inputValue * DistanceUnitData[inputUnit].value) / DistanceUnitData[outputUnit].value;
}
/**
@@ -146,9 +159,9 @@ export function convertDistance(inputValue: number, inputUnit: DISTANCE_UNIT_KEY
* @param {string} outputUnit The unit of the output
* @returns {number} The output
*/
-export function convertSpeed(inputValue: number, inputUnit: SPEED_UNIT_KEYS,
- outputUnit: SPEED_UNIT_KEYS): number {
- return (inputValue * SPEED_UNITS[inputUnit].value) / SPEED_UNITS[outputUnit].value;
+export function convertSpeed(inputValue: number, inputUnit: SpeedUnits,
+ outputUnit: SpeedUnits): number {
+ return (inputValue * SpeedUnitData[inputUnit].value) / SpeedUnitData[outputUnit].value;
}
/**
@@ -158,9 +171,9 @@ export function convertSpeed(inputValue: number, inputUnit: SPEED_UNIT_KEYS,
* @param {string} outputUnit The unit of the output
* @returns {number} The output
*/
-export function convertPace(inputValue: number, inputUnit: PACE_UNIT_KEYS,
- outputUnit: PACE_UNIT_KEYS): number {
- return (inputValue * PACE_UNITS[inputUnit].value) / PACE_UNITS[outputUnit].value;
+export function convertPace(inputValue: number, inputUnit: PaceUnits,
+ outputUnit: PaceUnits): number {
+ return (inputValue * PaceUnitData[inputUnit].value) / PaceUnitData[outputUnit].value;
}
/**
@@ -170,59 +183,60 @@ export function convertPace(inputValue: number, inputUnit: PACE_UNIT_KEYS,
* @param {string} outputUnit The unit of the output
* @returns {number} The output
*/
-export function convertSpeedPace(inputValue: number, inputUnit: SPEED_UNIT_KEYS | PACE_UNIT_KEYS,
- outputUnit: SPEED_UNIT_KEYS | PACE_UNIT_KEYS): number {
+export function convertSpeedPace(inputValue: number, inputUnit: SpeedUnits | PaceUnits,
+ outputUnit: SpeedUnits | PaceUnits): number {
// Calculate input speed
let speed;
- if (inputUnit in PACE_UNITS) {
- speed = 1 / (inputValue * PACE_UNITS[inputUnit as PACE_UNIT_KEYS].value);
+ if (inputUnit in PaceUnitData) {
+ speed = 1 / (inputValue * PaceUnitData[inputUnit as PaceUnits].value);
} else {
- speed = inputValue * SPEED_UNITS[inputUnit as SPEED_UNIT_KEYS].value;
+ speed = inputValue * SpeedUnitData[inputUnit as SpeedUnits].value;
}
// Calculate output
- if (outputUnit in PACE_UNITS) {
- return (1 / speed) / PACE_UNITS[outputUnit as PACE_UNIT_KEYS].value;
+ if (outputUnit in PaceUnitData) {
+ return (1 / speed) / PaceUnitData[outputUnit as PaceUnits].value;
}
- return speed / SPEED_UNITS[outputUnit as SPEED_UNIT_KEYS].value;
+ return speed / SpeedUnitData[outputUnit as SpeedUnits].value;
}
/**
* Detect the user's default unit system
- * @returns {string} The default unit system
+ * @returns {UnitSystems} The default unit system
*/
-export function detectDefaultUnitSystem(): string {
+export function detectDefaultUnitSystem(): UnitSystems {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const language = (navigator.language || (navigator as any).userLanguage).toLowerCase();
if (language.endsWith('-us') || language.endsWith('-mm')) {
- return 'imperial';
+ return UnitSystems.Imperial;
}
- return 'metric';
+ return UnitSystems.Metric;
}
/**
* Get the default distance unit in a unit system
- * @param {string} unitSystem The unit system
- * @returns {string} The default distance unit
+ * @param {UnitSystems} unitSystem The unit system
+ * @returns {DistanceUnits} The default distance unit
*/
-export function getDefaultDistanceUnit(unitSystem: string): string {
- return unitSystem === 'metric' ? 'kilometers' : 'miles';
+export function getDefaultDistanceUnit(unitSystem: UnitSystems): DistanceUnits {
+ return unitSystem === UnitSystems.Metric ? DistanceUnits.Kilometers : DistanceUnits.Miles;
}
/**
* Get the default speed unit in a unit system
- * @param {string} unitSystem The unit system
- * @returns {string} The default speed unit
+ * @param {UnitSystems} unitSystem The unit system
+ * @returns {SpeedUnits} The default speed unit
*/
-export function getDefaultSpeedUnit(unitSystem: string): string {
- return unitSystem === 'metric' ? 'kilometers_per_hour' : 'miles_per_hour';
+export function getDefaultSpeedUnit(unitSystem: UnitSystems): SpeedUnits {
+ return unitSystem === UnitSystems.Metric ? SpeedUnits.KilometersPerHour
+ : SpeedUnits.MilesPerHour;
}
/**
* Get the default pace unit in a unit system
- * @param {string} unitSystem The unit system
- * @returns {string} The default pace unit
+ * @param {UnitSystems} unitSystem The unit system
+ * @returns {PaceUnits} The default pace unit
*/
-export function getDefaultPaceUnit(unitSystem: string): string {
- return unitSystem === 'metric' ? 'seconds_per_kilometer' : 'seconds_per_mile';
+export function getDefaultPaceUnit(unitSystem: UnitSystems): PaceUnits {
+ return unitSystem === UnitSystems.Metric ? PaceUnits.TimePerKilometer : PaceUnits.TimePerMile;
}
diff --git a/src/views/UnitCalculator.vue b/src/views/UnitCalculator.vue
@@ -38,7 +38,7 @@
import { computed, ref } from 'vue';
import { formatDuration, formatNumber } from '@/utils/format';
-import { DISTANCE_UNITS, TIME_UNITS, SPEED_UNITS, PACE_UNITS, convertDistance, convertTime,
+import { DistanceUnitData, TimeUnitData, SpeedUnitData, PaceUnitData, convertDistance, convertTime,
convertSpeedPace } from '@/utils/units';
import DecimalInput from '@/components/DecimalInput.vue';
@@ -90,11 +90,11 @@ const input = computed({
const units = computed(() => {
switch (category.value) {
case 'distance': {
- return DISTANCE_UNITS;
+ return DistanceUnitData;
}
case 'time': {
return {
- ...TIME_UNITS,
+ ...TimeUnitData,
'hh:mm:ss': {
name: 'hh:mm:ss',
symbol: '',
@@ -103,7 +103,7 @@ const units = computed(() => {
};
}
case 'speed_and_pace': {
- return { ...PACE_UNITS, ...SPEED_UNITS };
+ return { ...PaceUnitData, ...SpeedUnitData };
}
default: {
return {};
@@ -144,10 +144,10 @@ const outputValue = computed(() => {
* @returns {String} The type ('decimal' or 'time')
*/
function getUnitType(unit) {
- if (unit in DISTANCE_UNITS) {
+ if (unit in DistanceUnitData) {
return 'decimal';
}
- if (unit in TIME_UNITS) {
+ if (unit in TimeUnitData) {
return 'decimal';
}
if (unit === 'hh:mm:ss') {