commit 8bcd4be3ac28f2a7df8f3413b52a087a101755aa
parent cb11a47eeb45faac340f7007a1b18bae348fbd79
Author: Asher Morgan <59518073+ashermorgan@users.noreply.github.com>
Date: Sun, 24 Aug 2025 15:56:50 -0700
Create changelog page generated from CHANGELOG.md
Diffstat:
7 files changed, 148 insertions(+), 32 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
@@ -21,7 +21,7 @@
- Open the edit target set dialog automatically after a new target set is
created
-## Removed
+### Removed
- Remove support for using target sets across multiple calculators (excluding
the Batch Calculator, where applicable)
diff --git a/package-lock.json b/package-lock.json
@@ -9,6 +9,7 @@
"version": "1.4.1",
"dependencies": {
"feather-icons": "^4.29.2",
+ "markdown-it": "^14.1.0",
"vue": "^3.5.17",
"vue-feather": "^2.0.0",
"vue-router": "^4.3.2"
@@ -17,6 +18,7 @@
"@eslint/js": "^9.22.0",
"@playwright/test": "^1.53.1",
"@tsconfig/node22": "^22.0.2",
+ "@types/markdown-it": "^14.1.2",
"@types/node": "^24.0.7",
"@vitejs/plugin-vue": "^5.2.4",
"@vue/eslint-config-typescript": "^14.5.1",
@@ -2344,13 +2346,13 @@
}
},
"node_modules/@eslint/plugin-kit": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.2.tgz",
- "integrity": "sha512-4SaFZCNfJqvk/kenHpI8xvN42DMaoycy4PzKc5otHxRswww1kAt82OlBuwRVLofCACCTZEcla2Ydxv8scMXaTg==",
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz",
+ "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
- "@eslint/core": "^0.15.0",
+ "@eslint/core": "^0.15.2",
"levn": "^0.4.1"
},
"engines": {
@@ -2358,9 +2360,9 @@
}
},
"node_modules/@eslint/plugin-kit/node_modules/@eslint/core": {
- "version": "0.15.0",
- "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.0.tgz",
- "integrity": "sha512-b7ePw78tEWWkpgZCDYkbqDOP8dmM6qe+AOC6iuJqlq1R/0ahMAeH3qynpnqKFGkMltrp44ohV4ubGyvLX28tzw==",
+ "version": "0.15.2",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz",
+ "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==",
"dev": true,
"license": "Apache-2.0",
"dependencies": {
@@ -3050,6 +3052,31 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/@types/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/markdown-it": {
+ "version": "14.1.2",
+ "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
+ "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/linkify-it": "^5",
+ "@types/mdurl": "^2"
+ }
+ },
+ "node_modules/@types/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/@types/node": {
"version": "24.0.7",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.7.tgz",
@@ -3809,7 +3836,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
- "dev": true,
"license": "Python-2.0"
},
"node_modules/array-buffer-byte-length": {
@@ -7273,6 +7299,15 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/linkify-it": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
+ "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
+ "license": "MIT",
+ "dependencies": {
+ "uc.micro": "^2.0.0"
+ }
+ },
"node_modules/locate-path": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
@@ -7361,6 +7396,35 @@
"@jridgewell/sourcemap-codec": "^1.5.0"
}
},
+ "node_modules/markdown-it": {
+ "version": "14.1.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
+ "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1",
+ "entities": "^4.4.0",
+ "linkify-it": "^5.0.0",
+ "mdurl": "^2.0.0",
+ "punycode.js": "^2.3.1",
+ "uc.micro": "^2.1.0"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.mjs"
+ }
+ },
+ "node_modules/markdown-it/node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
"node_modules/marky": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/marky/-/marky-1.3.0.tgz",
@@ -7378,6 +7442,12 @@
"node": ">= 0.4"
}
},
+ "node_modules/mdurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
+ "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
+ "license": "MIT"
+ },
"node_modules/memorystream": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
@@ -8191,6 +8261,15 @@
"node": ">=6"
}
},
+ "node_modules/punycode.js": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
+ "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/puppeteer-core": {
"version": "24.10.2",
"resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.10.2.tgz",
@@ -9717,6 +9796,12 @@
"typescript": ">=4.8.4 <5.9.0"
}
},
+ "node_modules/uc.micro": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
+ "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
+ "license": "MIT"
+ },
"node_modules/unbox-primitive": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
diff --git a/package.json b/package.json
@@ -20,6 +20,7 @@
},
"dependencies": {
"feather-icons": "^4.29.2",
+ "markdown-it": "^14.1.0",
"vue": "^3.5.17",
"vue-feather": "^2.0.0",
"vue-router": "^4.3.2"
@@ -28,6 +29,7 @@
"@eslint/js": "^9.22.0",
"@playwright/test": "^1.53.1",
"@tsconfig/node22": "^22.0.2",
+ "@types/markdown-it": "^14.1.2",
"@types/node": "^24.0.7",
"@vitejs/plugin-vue": "^5.2.4",
"@vue/eslint-config-typescript": "^14.5.1",
diff --git a/src/assets/global.css b/src/assets/global.css
@@ -144,6 +144,29 @@ header h1 {
}
}
+/* long-form text styles */
+.text {
+ max-width: 800px;
+ margin: auto;
+ font-size: 1.1em;
+}
+.text h2 {
+ text-align: center;
+}
+.text * + h2, .text :not(h2) + h3 {
+ margin-top: 1em;
+}
+.text p, .text ul {
+ margin-bottom: 0.5em;
+}
+.text p {
+ line-height: 1.3;
+}
+.text li {
+ margin-bottom: 0.2em;
+ margin-left: 1.5em;
+}
+
/* light/default theme */
:root {
/* The theme color of the app */
diff --git a/src/router/index.ts b/src/router/index.ts
@@ -2,6 +2,7 @@ import { createRouter, createWebHashHistory } from 'vue-router';
import HomePage from '@/views/HomePage.vue';
import AboutPage from '@/views/AboutPage.vue';
import BatchCalculator from '@/views/BatchCalculator.vue';
+import ChangeLog from '@/views/ChangeLog.vue';
import PaceCalculator from '@/views/PaceCalculator.vue';
import RaceCalculator from '@/views/RaceCalculator.vue';
import SplitCalculator from '@/views/SplitCalculator.vue';
@@ -35,6 +36,15 @@ const router = createRouter({
},
},
{
+ path: '/changelog',
+ name: 'changelog',
+ component: ChangeLog,
+ meta: {
+ title: 'Change Log',
+ back: 'home',
+ },
+ },
+ {
path: '/calculate',
redirect: '/home',
},
diff --git a/src/views/AboutPage.vue b/src/views/AboutPage.vue
@@ -1,10 +1,11 @@
<template>
- <div class="about-page">
+ <div class="text">
<p>
Running Tools is an <a :href="git_url">open source</a> collection of tools for runners
and their coaches.
All calculations are performed locally on your device.
- This is Running Tools version {{ version }}{{ development ? ' (dev)' : '' }}.
+ This is Running Tools version <router-link :to="{ name: 'changelog' }">
+ {{ version }}</router-link>{{ development ? ' (dev)' : '' }}.
</p>
<h2>Installation</h2>
@@ -178,27 +179,6 @@ const git_url: string = repository.url.slice(4);
</script>
<style scoped>
-.about-page {
- max-width: 800px;
- margin: auto;
- font-size: 1.1em;
-}
-h2 {
- text-align: center;
-}
-h2, h3 {
- margin-top: 1em;
-}
-p, blockquote, ul {
- margin-bottom: 0.5em;
-}
-li {
- margin-bottom: 0.2em;
- margin-left: 1.5em;
-}
-p {
- line-height: 1.3;
-}
.questions {
font-style: italic;
}
diff --git a/src/views/ChangeLog.vue b/src/views/ChangeLog.vue
@@ -0,0 +1,16 @@
+<template>
+ <div class="text" v-html="changelog_html"/>
+</template>
+
+<script setup lang="ts">
+import markdownit from 'markdown-it'
+
+import changelog_md from '/CHANGELOG.md?raw'
+
+const changelog_html: string = markdownit({
+ typographer: true, // needed to convert '--' to en-dash
+}).render(changelog_md.slice(changelog_md.indexOf('\n') + 1)); // render without h1 on first line
+</script>
+
+<style scoped>
+</style>