running-tools

A collection of tools for runners and their coaches
git clone https://git.ashermorgan.net/running-tools/
Log | Files | Refs | README

commit 9a4659fafc0ee03d15d903b6afb4e52f34b4c427
parent a5252e2e8b65d8611e7b9f706a356ec532fe160c
Author: ashermorgan <59518073+ashermorgan@users.noreply.github.com>
Date:   Thu, 26 Aug 2021 12:14:18 -0700

Save time table targets in localStorage

Diffstat:
Asrc/assets/rotate-ccw.svg | 1+
Msrc/components/TimeTable.vue | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Asrc/utils/localStorage.js | 38++++++++++++++++++++++++++++++++++++++
Msrc/views/PaceCalculator.vue | 17++++++++++-------
Msrc/views/RaceCalculator.vue | 15++++++++-------
5 files changed, 122 insertions(+), 18 deletions(-)

diff --git a/src/assets/rotate-ccw.svg b/src/assets/rotate-ccw.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-rotate-ccw"><polyline points="1 4 1 10 7 10"></polyline><path d="M3.51 15a9 9 0 1 0 2.13-9.36L1 10"></path></svg> diff --git a/src/components/TimeTable.vue b/src/components/TimeTable.vue @@ -46,6 +46,9 @@ <th>Edit Targets</th> <th> + <button class="icon" title="Reset Targets" @click="resetTargets"> + <img alt="" src="@/assets/rotate-ccw.svg"> + </button> <button class="icon" title="Close" @click="inEditMode=false"> <img alt="" src="@/assets/x.svg"> </button> @@ -73,7 +76,7 @@ </tr> <tr v-if="targets.length === 0" class="empty-message"> - <td colspan="4"> + <td colspan="2"> There aren't any targets,<br> click <img alt="Add Target" src="@/assets/plus-circle.svg"> @@ -84,9 +87,9 @@ <tfoot> <tr> - <td colspan="4"> + <td colspan="2"> <button class="icon" title="Add Target" @click="targets.push({distanceValue: 1, - distanceUnit: 'miles'})"> + distanceUnit: 'miles'})"> <img alt="" src="@/assets/plus-circle.svg"> </button> </td> @@ -98,6 +101,7 @@ <script> import unitUtils from '@/utils/units'; +import storage from '@/utils/localStorage'; import DecimalInput from '@/components/DecimalInput.vue'; @@ -124,6 +128,14 @@ export default { type: Array, default: () => [], }, + + /** + * The localStorage key for the list of targets + */ + storageKey: { + type: String, + default: null, + }, }, data() { @@ -151,7 +163,7 @@ export default { /** * The time table targets */ - targets: this.defaultTargets, + targets: storage.get(this.storageKey, this.defaultTargets), }; }, @@ -174,6 +186,55 @@ export default { return result; }, }, + + watch: { + /** + * Sort targets + */ + inEditMode() { + this.sortTargets(); + }, + + /** + * Save targets + */ + targets: { + handler(newValue) { + if (this.storageKey !== null) { + storage.set(this.storageKey, newValue); + } + }, + deep: true, + }, + }, + + methods: { + /** + * Restore the default targets + */ + resetTargets() { + // Clone default targets array + this.targets = JSON.parse(JSON.stringify(this.defaultTargets)); + + // Sort targets + this.sortTargets(); + }, + + /** + * Sort the targets by distance + */ + sortTargets() { + this.targets.sort((a, b) => unitUtils.convertDistance(a.distanceValue, a.distanceUnit, + 'meters') - unitUtils.convertDistance(b.distanceValue, b.distanceUnit, 'meters')); + }, + }, + + /** + * Close edit targets table + */ + deactivated() { + this.inEditMode = false; + }, }; </script> diff --git a/src/utils/localStorage.js b/src/utils/localStorage.js @@ -0,0 +1,38 @@ +// The global localStorage prefix +const prefix = 'running-tools'; + +/** + * Get the value of a key from localStorage + * @param {String} key The key + * @param {Object} defaultValue The default value + * @returns {Object} The value + */ +function get(key, defaultValue) { + // Clone defaultValue + const clonedDefault = JSON.parse(JSON.stringify(defaultValue)); + + if (key === null) { + return clonedDefault; + } + let value; + try { + value = JSON.parse(localStorage.getItem(`${prefix}.${key}`)); + } catch { + return clonedDefault; + } + return value === null ? clonedDefault : value; +} + +/** + * Set the value of a key in localStorage + * @param {String} key The key + * @param {Object} value The value + * */ +function set(key, value) { + localStorage.setItem(`${prefix}.${key}`, JSON.stringify(value)); +} + +export default { + get, + set, +}; diff --git a/src/views/PaceCalculator.vue b/src/views/PaceCalculator.vue @@ -15,7 +15,8 @@ <p>is the same pace as running</p> - <time-table class="output" :calculate-result="calculatePace" :default-targets="defaultTargets"/> + <time-table class="output" :calculate-result="calculatePace" :default-targets="defaultTargets" + storage-key="pace-calculator-targets"/> </div> </template> @@ -74,12 +75,6 @@ export default { { distanceValue: 1600, distanceUnit: 'meters' }, { distanceValue: 3200, distanceUnit: 'meters' }, - { distanceValue: 1, distanceUnit: 'miles' }, - { distanceValue: 2, distanceUnit: 'miles' }, - { distanceValue: 3, distanceUnit: 'miles' }, - { distanceValue: 5, distanceUnit: 'miles' }, - { distanceValue: 10, distanceUnit: 'miles' }, - { distanceValue: 2, distanceUnit: 'kilometers' }, { distanceValue: 3, distanceUnit: 'kilometers' }, { distanceValue: 4, distanceUnit: 'kilometers' }, @@ -89,6 +84,14 @@ export default { { distanceValue: 10, distanceUnit: 'kilometers' }, { distanceValue: 15, distanceUnit: 'kilometers' }, + { distanceValue: 1, distanceUnit: 'miles' }, + { distanceValue: 2, distanceUnit: 'miles' }, + { distanceValue: 3, distanceUnit: 'miles' }, + { distanceValue: 5, distanceUnit: 'miles' }, + { distanceValue: 6, distanceUnit: 'miles' }, + { distanceValue: 8, distanceUnit: 'miles' }, + { distanceValue: 10, distanceUnit: 'miles' }, + { distanceValue: 0.5, distanceUnit: 'marathons' }, { distanceValue: 1, distanceUnit: 'marathons' }, ], diff --git a/src/views/RaceCalculator.vue b/src/views/RaceCalculator.vue @@ -14,7 +14,8 @@ <p>is approximately equivalent to running</p> - <time-table class="output" :calculate-result="predictTime" :default-targets="defaultTargets"/> + <time-table class="output" :calculate-result="predictTime" :default-targets="defaultTargets" + storage-key="race-calculator-targets"/> </div> </template> @@ -69,18 +70,18 @@ export default { { distanceValue: 1600, distanceUnit: 'meters' }, { distanceValue: 3200, distanceUnit: 'meters' }, - { distanceValue: 1, distanceUnit: 'miles' }, - { distanceValue: 2, distanceUnit: 'miles' }, - { distanceValue: 3, distanceUnit: 'miles' }, - { distanceValue: 5, distanceUnit: 'miles' }, - { distanceValue: 10, distanceUnit: 'miles' }, - { distanceValue: 3, distanceUnit: 'kilometers' }, { distanceValue: 5, distanceUnit: 'kilometers' }, { distanceValue: 8, distanceUnit: 'kilometers' }, { distanceValue: 10, distanceUnit: 'kilometers' }, { distanceValue: 15, distanceUnit: 'kilometers' }, + { distanceValue: 1, distanceUnit: 'miles' }, + { distanceValue: 2, distanceUnit: 'miles' }, + { distanceValue: 3, distanceUnit: 'miles' }, + { distanceValue: 5, distanceUnit: 'miles' }, + { distanceValue: 10, distanceUnit: 'miles' }, + { distanceValue: 0.5, distanceUnit: 'marathons' }, { distanceValue: 1, distanceUnit: 'marathons' }, ],