From 91455251e189d17e99007b5fc2ebb8f87cdb82fb Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 11 Nov 2023 14:32:55 +0100 Subject: [PATCH 01/14] Client - update Node to 18.x --- .github/workflows/.tests-javascript.yml | 4 ++-- fittrackee_client/Dockerfile | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/.tests-javascript.yml b/.github/workflows/.tests-javascript.yml index 66d222a0..4c4f94c6 100644 --- a/.github/workflows/.tests-javascript.yml +++ b/.github/workflows/.tests-javascript.yml @@ -16,10 +16,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Use Node.js 17.x + - name: Use Node.js 18.x uses: actions/setup-node@v3 with: - node-version: "17.x" + node-version: "18.x" - name: Install yarn and dependencies working-directory: ${{env.working-directory}} run: | diff --git a/fittrackee_client/Dockerfile b/fittrackee_client/Dockerfile index df734177..a8bf3e9c 100644 --- a/fittrackee_client/Dockerfile +++ b/fittrackee_client/Dockerfile @@ -1,4 +1,4 @@ -FROM node:16 +FROM node:18 MAINTAINER SamR1@users.noreply.github.com From 1befae927d731f2f9dce4f2254ac8debbaf81303 Mon Sep 17 00:00:00 2001 From: Sam Date: Sat, 11 Nov 2023 15:23:04 +0100 Subject: [PATCH 02/14] Client - upgrade Vue to 3.3 and move to Vite --- Makefile | 7 +- fittrackee_client/.env | 2 +- fittrackee_client/.eslintrc.cjs | 18 + fittrackee_client/.gitignore | 28 + .../{.prettierrc => .prettierrc.json} | 3 +- fittrackee_client/README.md | 51 +- fittrackee_client/babel.config.js | 3 - fittrackee_client/env.d.ts | 1 + fittrackee_client/index.html | 15 + fittrackee_client/package.json | 134 +- fittrackee_client/public/index.html | 19 - fittrackee_client/src/App.vue | 5 +- fittrackee_client/src/api/pending.ts | 2 +- fittrackee_client/src/components/About.vue | 11 +- .../Administration/AdminApplication.vue | 60 +- .../components/Administration/AdminMenu.vue | 6 +- .../components/Administration/AdminSports.vue | 5 +- .../components/Administration/AdminUsers.vue | 10 +- .../Administration/AppStatsCards.vue | 2 +- .../src/components/Common/CustomTextArea.vue | 2 +- .../src/components/Common/Distance.vue | 5 +- .../src/components/Common/Dropdown.vue | 2 +- .../src/components/Common/Error.vue | 2 +- .../src/components/Common/FilterSelects.vue | 2 +- .../components/Common/Images/EmailSent.vue | 2 +- .../src/components/Common/Images/ErrorImg.vue | 2 +- .../src/components/Common/Images/Password.vue | 2 +- .../Common/Images/SportImage/CyclingSport.vue | 2 +- .../Images/SportImage/CyclingTransport.vue | 2 +- .../Images/SportImage/CyclingVirtual.vue | 67 +- .../Common/Images/SportImage/Hiking.vue | 2 +- .../Images/SportImage/MountainBiking.vue | 2 +- .../SportImage/MountainBikingElectric.vue | 2 +- .../Images/SportImage/Mountaineering.vue | 2 +- .../Images/SportImage/OpenWaterSwimming.vue | 2 +- .../Common/Images/SportImage/Paragliding.vue | 2 +- .../Common/Images/SportImage/Rowing.vue | 2 +- .../Common/Images/SportImage/Running.vue | 2 +- .../Common/Images/SportImage/SkiingAlpine.vue | 2 +- .../Images/SportImage/SkiingCrossCountry.vue | 2 +- .../Common/Images/SportImage/Snowshoes.vue | 2 +- .../Common/Images/SportImage/Trail.vue | 2 +- .../Common/Images/SportImage/Walking.vue | 2 +- .../src/components/Common/Modal.vue | 10 +- .../src/components/Common/NotFound.vue | 3 +- .../src/components/Common/Pagination.vue | 6 +- .../src/components/Common/PasswordInput.vue | 3 +- .../src/components/Common/PasswordStength.vue | 11 +- .../src/components/Common/StaticMap.vue | 4 +- .../components/Common/StatsChart/Chart.vue | 9 +- .../components/Common/StatsChart/index.vue | 18 +- .../src/components/Dashboard/Timeline.vue | 9 +- .../Dashboard/UserCalendar/CalendarCells.vue | 7 +- .../Dashboard/UserCalendar/CalendarDays.vue | 3 +- .../Dashboard/UserCalendar/CalendarHeader.vue | 3 +- .../UserCalendar/CalendarWorkout.vue | 2 +- .../UserCalendar/CalendarWorkouts.vue | 4 +- .../UserCalendar/CalendarWorkoutsChart.vue | 7 +- .../Dashboard/UserCalendar/index.vue | 12 +- .../components/Dashboard/UserMonthStats.vue | 4 +- .../Dashboard/UserRecords/RecordsCard.vue | 2 +- .../Dashboard/UserRecords/index.vue | 4 +- .../Dashboard/UserStatsCards/index.vue | 28 +- fittrackee_client/src/components/NavBar.vue | 7 +- .../src/components/PrivacyPolicy.vue | 7 +- .../src/components/PrivacyPolicyToAccept.vue | 7 +- .../components/Statistics/StatsSportsMenu.vue | 9 +- .../src/components/Statistics/index.vue | 9 +- .../User/PasswordReset/PasswordResetForm.vue | 2 +- .../User/ProfileDisplay/UserHeader.vue | 5 +- .../User/ProfileDisplay/UserInfos.vue | 16 +- .../User/ProfileDisplay/UserPreferences.vue | 5 +- .../components/User/ProfileDisplay/index.vue | 2 +- .../User/ProfileEdition/TimezoneDropdown.vue | 3 +- .../ProfileEdition/UserAccountEdition.vue | 7 +- .../User/ProfileEdition/UserInfosEdition.vue | 9 +- .../ProfileEdition/UserPictureEdition.vue | 7 +- .../ProfileEdition/UserPreferencesEdition.vue | 5 +- .../UserPrivacyPolicyValidation.vue | 21 +- .../components/User/ProfileEdition/index.vue | 11 +- .../components/User/UserApps/AddUserApp.vue | 4 +- .../User/UserApps/AuthorizeUserApp.vue | 5 +- .../src/components/User/UserApps/UserApp.vue | 4 +- .../components/User/UserApps/UserAppsList.vue | 12 +- .../src/components/User/UserApps/index.vue | 2 +- .../src/components/User/UserAuthForm.vue | 20 +- .../src/components/User/UserPicture.vue | 2 +- .../src/components/User/UserProfileTabs.vue | 2 +- .../components/User/UserSportPreferences.vue | 7 +- .../src/components/Workout/WorkoutCard.vue | 16 +- .../Workout/WorkoutDetail/WeatherWind.vue | 2 +- .../WorkoutDetail/WorkoutCardTitle.vue | 4 +- .../WorkoutDetail/WorkoutChart/index.vue | 11 +- .../WorkoutDetail/WorkoutChart/legend.ts | 3 +- .../Workout/WorkoutDetail/WorkoutData.vue | 2 +- .../WorkoutDetail/WorkoutMap/CustomMarker.vue | 2 +- .../WorkoutDetail/WorkoutMap/index.vue | 12 +- .../Workout/WorkoutDetail/WorkoutNotes.vue | 2 +- .../Workout/WorkoutDetail/WorkoutRecord.vue | 2 +- .../Workout/WorkoutDetail/WorkoutSegments.vue | 2 +- .../Workout/WorkoutDetail/WorkoutWeather.vue | 2 +- .../Workout/WorkoutDetail/index.vue | 19 +- .../src/components/Workout/WorkoutEdition.vue | 14 +- .../components/Workouts/WorkoutsFilters.vue | 10 +- .../src/components/Workouts/WorkoutsList.vue | 23 +- fittrackee_client/src/directives.ts | 2 +- fittrackee_client/src/i18n.ts | 42 +- fittrackee_client/src/locales/de/about.json | 12 +- .../src/locales/de/administration.json | 122 +- fittrackee_client/src/locales/de/api.json | 84 +- fittrackee_client/src/locales/de/buttons.json | 34 +- fittrackee_client/src/locales/de/common.json | 44 +- .../src/locales/de/dashboard.json | 4 +- fittrackee_client/src/locales/de/error.json | 14 +- fittrackee_client/src/locales/de/oauth2.json | 66 +- .../src/locales/de/privacy_policy.json | 70 +- fittrackee_client/src/locales/de/sports.json | 96 +- .../src/locales/de/statistics.json | 12 +- fittrackee_client/src/locales/de/user.json | 272 +- .../src/locales/de/workouts.json | 214 +- fittrackee_client/src/locales/en/about.json | 14 +- .../src/locales/en/administration.json | 122 +- fittrackee_client/src/locales/en/api.json | 86 +- fittrackee_client/src/locales/en/buttons.json | 36 +- fittrackee_client/src/locales/en/common.json | 46 +- .../src/locales/en/dashboard.json | 4 +- fittrackee_client/src/locales/en/error.json | 14 +- fittrackee_client/src/locales/en/oauth2.json | 66 +- .../src/locales/en/privacy_policy.json | 72 +- fittrackee_client/src/locales/en/sports.json | 96 +- .../src/locales/en/statistics.json | 12 +- fittrackee_client/src/locales/en/user.json | 274 +- .../src/locales/en/workouts.json | 214 +- fittrackee_client/src/locales/es/about.json | 12 +- .../src/locales/es/administration.json | 122 +- fittrackee_client/src/locales/es/api.json | 84 +- fittrackee_client/src/locales/es/buttons.json | 34 +- fittrackee_client/src/locales/es/common.json | 44 +- .../src/locales/es/dashboard.json | 4 +- fittrackee_client/src/locales/es/error.json | 14 +- fittrackee_client/src/locales/es/oauth2.json | 66 +- .../src/locales/es/privacy_policy.json | 70 +- fittrackee_client/src/locales/es/sports.json | 96 +- .../src/locales/es/statistics.json | 12 +- fittrackee_client/src/locales/es/user.json | 272 +- .../src/locales/es/workouts.json | 214 +- fittrackee_client/src/locales/fr/about.json | 12 +- .../src/locales/fr/administration.json | 122 +- fittrackee_client/src/locales/fr/api.json | 84 +- fittrackee_client/src/locales/fr/buttons.json | 34 +- fittrackee_client/src/locales/fr/common.json | 46 +- .../src/locales/fr/dashboard.json | 4 +- fittrackee_client/src/locales/fr/error.json | 14 +- fittrackee_client/src/locales/fr/oauth2.json | 66 +- .../src/locales/fr/privacy_policy.json | 72 +- fittrackee_client/src/locales/fr/sports.json | 96 +- .../src/locales/fr/statistics.json | 12 +- fittrackee_client/src/locales/fr/user.json | 274 +- .../src/locales/fr/workouts.json | 214 +- fittrackee_client/src/locales/gl/about.json | 12 +- .../src/locales/gl/administration.json | 122 +- fittrackee_client/src/locales/gl/api.json | 84 +- fittrackee_client/src/locales/gl/buttons.json | 34 +- fittrackee_client/src/locales/gl/common.json | 44 +- .../src/locales/gl/dashboard.json | 4 +- fittrackee_client/src/locales/gl/error.json | 14 +- fittrackee_client/src/locales/gl/oauth2.json | 66 +- .../src/locales/gl/privacy_policy.json | 70 +- fittrackee_client/src/locales/gl/sports.json | 96 +- .../src/locales/gl/statistics.json | 12 +- fittrackee_client/src/locales/gl/user.json | 272 +- .../src/locales/gl/workouts.json | 214 +- fittrackee_client/src/locales/it/about.json | 8 +- .../src/locales/it/administration.json | 110 +- fittrackee_client/src/locales/it/api.json | 72 +- fittrackee_client/src/locales/it/buttons.json | 32 +- fittrackee_client/src/locales/it/common.json | 44 +- .../src/locales/it/dashboard.json | 4 +- fittrackee_client/src/locales/it/error.json | 14 +- fittrackee_client/src/locales/it/oauth2.json | 66 +- .../src/locales/it/privacy_policy.json | 2 +- fittrackee_client/src/locales/it/sports.json | 84 +- .../src/locales/it/statistics.json | 12 +- fittrackee_client/src/locales/it/user.json | 222 +- .../src/locales/it/workouts.json | 204 +- fittrackee_client/src/locales/nb/about.json | 12 +- .../src/locales/nb/administration.json | 102 +- fittrackee_client/src/locales/nb/api.json | 66 +- fittrackee_client/src/locales/nb/buttons.json | 30 +- fittrackee_client/src/locales/nb/common.json | 34 +- .../src/locales/nb/dashboard.json | 4 +- fittrackee_client/src/locales/nb/error.json | 10 +- fittrackee_client/src/locales/nb/oauth2.json | 48 +- .../src/locales/nb/privacy_policy.json | 36 +- fittrackee_client/src/locales/nb/sports.json | 54 +- .../src/locales/nb/statistics.json | 12 +- fittrackee_client/src/locales/nb/user.json | 218 +- .../src/locales/nb/workouts.json | 168 +- fittrackee_client/src/locales/nl/about.json | 12 +- .../src/locales/nl/administration.json | 122 +- fittrackee_client/src/locales/nl/api.json | 84 +- fittrackee_client/src/locales/nl/buttons.json | 34 +- fittrackee_client/src/locales/nl/common.json | 44 +- .../src/locales/nl/dashboard.json | 4 +- fittrackee_client/src/locales/nl/error.json | 14 +- fittrackee_client/src/locales/nl/oauth2.json | 66 +- .../src/locales/nl/privacy_policy.json | 70 +- fittrackee_client/src/locales/nl/sports.json | 96 +- .../src/locales/nl/statistics.json | 12 +- fittrackee_client/src/locales/nl/user.json | 272 +- .../src/locales/nl/workouts.json | 214 +- fittrackee_client/src/locales/pl/about.json | 12 +- .../src/locales/pl/administration.json | 122 +- fittrackee_client/src/locales/pl/api.json | 84 +- fittrackee_client/src/locales/pl/buttons.json | 34 +- fittrackee_client/src/locales/pl/common.json | 44 +- .../src/locales/pl/dashboard.json | 4 +- fittrackee_client/src/locales/pl/error.json | 14 +- fittrackee_client/src/locales/pl/oauth2.json | 66 +- .../src/locales/pl/privacy_policy.json | 70 +- fittrackee_client/src/locales/pl/sports.json | 96 +- .../src/locales/pl/statistics.json | 12 +- fittrackee_client/src/locales/pl/user.json | 272 +- .../src/locales/pl/workouts.json | 214 +- fittrackee_client/src/main.ts | 1 - .../src/registerServiceWorker.ts | 34 - fittrackee_client/src/router/index.ts | 5 +- fittrackee_client/src/scss/base.scss | 38 +- fittrackee_client/src/scss/colors.scss | 31 +- fittrackee_client/src/scss/fonts.scss | 14 +- fittrackee_client/src/scss/vars.scss | 6 +- fittrackee_client/src/store/index.ts | 2 +- .../src/store/modules/authUser/actions.ts | 8 +- .../src/store/modules/authUser/getters.ts | 6 +- .../src/store/modules/authUser/index.ts | 6 +- .../src/store/modules/authUser/mutations.ts | 6 +- .../src/store/modules/authUser/state.ts | 4 +- .../src/store/modules/authUser/types.ts | 8 +- .../src/store/modules/oauth2/actions.ts | 8 +- .../src/store/modules/oauth2/getters.ts | 6 +- .../src/store/modules/oauth2/index.ts | 6 +- .../src/store/modules/oauth2/mutations.ts | 11 +- .../src/store/modules/oauth2/state.ts | 6 +- .../src/store/modules/oauth2/types.ts | 10 +- .../src/store/modules/root/actions.ts | 6 +- .../src/store/modules/root/getters.ts | 4 +- .../src/store/modules/root/index.ts | 4 +- .../src/store/modules/root/mutations.ts | 6 +- .../src/store/modules/root/state.ts | 4 +- .../src/store/modules/root/types.ts | 8 +- .../src/store/modules/sports/actions.ts | 8 +- .../src/store/modules/sports/getters.ts | 6 +- .../src/store/modules/sports/index.ts | 6 +- .../src/store/modules/sports/mutations.ts | 9 +- .../src/store/modules/sports/state.ts | 2 +- .../src/store/modules/sports/types.ts | 8 +- .../src/store/modules/statistics/actions.ts | 8 +- .../src/store/modules/statistics/getters.ts | 6 +- .../src/store/modules/statistics/index.ts | 6 +- .../src/store/modules/statistics/mutations.ts | 6 +- .../src/store/modules/statistics/state.ts | 4 +- .../src/store/modules/statistics/types.ts | 11 +- .../src/store/modules/users/actions.ts | 12 +- .../src/store/modules/users/getters.ts | 6 +- .../src/store/modules/users/index.ts | 6 +- .../src/store/modules/users/mutations.ts | 8 +- .../src/store/modules/users/state.ts | 6 +- .../src/store/modules/users/types.ts | 10 +- .../src/store/modules/workouts/actions.ts | 8 +- .../src/store/modules/workouts/getters.ts | 6 +- .../src/store/modules/workouts/index.ts | 6 +- .../src/store/modules/workouts/mutations.ts | 8 +- .../src/store/modules/workouts/state.ts | 6 +- .../src/store/modules/workouts/types.ts | 10 +- fittrackee_client/src/store/types.ts | 14 +- fittrackee_client/src/types/statistics.ts | 2 +- fittrackee_client/src/types/user.ts | 4 +- fittrackee_client/src/types/workouts.ts | 4 +- fittrackee_client/src/use/useStore.ts | 2 +- fittrackee_client/src/utils/api.ts | 6 +- fittrackee_client/src/utils/index.ts | 22 +- fittrackee_client/src/utils/locales.ts | 3 +- fittrackee_client/src/utils/records.ts | 6 +- fittrackee_client/src/utils/sports.ts | 4 +- fittrackee_client/src/utils/statistics.ts | 6 +- fittrackee_client/src/utils/tooltip.ts | 2 +- fittrackee_client/src/utils/units.ts | 2 +- fittrackee_client/src/utils/workouts.ts | 2 +- fittrackee_client/src/views/AdminView.vue | 5 +- fittrackee_client/src/views/Dashboard.vue | 10 +- .../src/views/PrivacyPolicyView.vue | 2 +- .../src/views/StatisticsView.vue | 7 +- .../user/AccountConfirmationResendView.vue | 1 + .../views/user/AccountConfirmationView.vue | 7 +- .../src/views/user/EmailUpdateView.vue | 9 +- .../src/views/user/ProfileView.vue | 5 +- fittrackee_client/src/views/user/UserView.vue | 11 +- .../src/views/workouts/AddWorkout.vue | 9 +- .../src/views/workouts/EditWorkout.vue | 9 +- .../src/views/workouts/Workout.vue | 22 +- .../src/views/workouts/WorkoutsView.vue | 7 +- fittrackee_client/src/vue-fullscreen.d.ts | 1 + fittrackee_client/src/vuex.d.ts | 6 + fittrackee_client/tsconfig.app.json | 12 + fittrackee_client/tsconfig.json | 48 +- fittrackee_client/tsconfig.node.json | 16 + fittrackee_client/vite.config.ts | 25 + fittrackee_client/vue.config.js | 38 - fittrackee_client/yarn.lock | 8260 ++--------------- 309 files changed, 6291 insertions(+), 12719 deletions(-) create mode 100644 fittrackee_client/.eslintrc.cjs create mode 100644 fittrackee_client/.gitignore rename fittrackee_client/{.prettierrc => .prettierrc.json} (81%) delete mode 100644 fittrackee_client/babel.config.js create mode 100644 fittrackee_client/env.d.ts create mode 100644 fittrackee_client/index.html delete mode 100644 fittrackee_client/public/index.html delete mode 100644 fittrackee_client/src/registerServiceWorker.ts create mode 100644 fittrackee_client/src/vue-fullscreen.d.ts create mode 100644 fittrackee_client/src/vuex.d.ts create mode 100644 fittrackee_client/tsconfig.app.json create mode 100644 fittrackee_client/tsconfig.node.json create mode 100644 fittrackee_client/vite.config.ts delete mode 100644 fittrackee_client/vue.config.js diff --git a/Makefile b/Makefile index c7859da7..79f65ac5 100644 --- a/Makefile +++ b/Makefile @@ -194,7 +194,7 @@ lint-client: cd fittrackee_client && $(NPM) lint lint-client-fix: - cd fittrackee_client && $(NPM) lint-fix + cd fittrackee_client && $(NPM) format lint-python: $(PYTEST) --isort --black -m "isort or black" fittrackee e2e --ignore=fittrackee/migrations @@ -233,7 +233,7 @@ serve-dev: serve-client: # for dev environments - cd fittrackee_client && PORT=3000 $(NPM) serve + cd fittrackee_client && PORT=3000 $(NPM) dev serve-python: # for dev environments @@ -269,6 +269,9 @@ type-check: echo 'Running mypy...' $(MYPY) fittrackee +type-check-client: + cd fittrackee_client && $(NPM) type-check + upgrade-db: $(FTCLI) db upgrade diff --git a/fittrackee_client/.env b/fittrackee_client/.env index 93c2b687..1309d972 100644 --- a/fittrackee_client/.env +++ b/fittrackee_client/.env @@ -1,2 +1,2 @@ -VUE_APP_API_URL=http://localhost:5000 +VITE_APP_API_URL=http://localhost:5000 PORT=3000 \ No newline at end of file diff --git a/fittrackee_client/.eslintrc.cjs b/fittrackee_client/.eslintrc.cjs new file mode 100644 index 00000000..b5aa77c3 --- /dev/null +++ b/fittrackee_client/.eslintrc.cjs @@ -0,0 +1,18 @@ +/* eslint-env node */ +require('@rushstack/eslint-patch/modern-module-resolution') + +module.exports = { + root: true, + 'extends': [ + 'plugin:vue/vue3-essential', + 'eslint:recommended', + '@vue/eslint-config-typescript', + '@vue/eslint-config-prettier/skip-formatting' + ], + parserOptions: { + ecmaVersion: 'latest' + }, + "rules": { + "vue/multi-word-component-names": "off" + } +} diff --git a/fittrackee_client/.gitignore b/fittrackee_client/.gitignore new file mode 100644 index 00000000..58bbedcd --- /dev/null +++ b/fittrackee_client/.gitignore @@ -0,0 +1,28 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +coverage +*.local + +/cypress/videos/ +/cypress/screenshots/ + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? \ No newline at end of file diff --git a/fittrackee_client/.prettierrc b/fittrackee_client/.prettierrc.json similarity index 81% rename from fittrackee_client/.prettierrc rename to fittrackee_client/.prettierrc.json index 55ae9dd1..35abc8f6 100644 --- a/fittrackee_client/.prettierrc +++ b/fittrackee_client/.prettierrc.json @@ -1,4 +1,5 @@ { + "$schema": "https://json.schemastore.org/prettierrc", "tabWidth": 2, "semi": false, "singleQuote": true, @@ -9,4 +10,4 @@ "printWidth": 80, "endOfLine": "auto", "vueIndentScriptAndStyle": true -} +} \ No newline at end of file diff --git a/fittrackee_client/README.md b/fittrackee_client/README.md index 3f553d90..11e13e74 100644 --- a/fittrackee_client/README.md +++ b/fittrackee_client/README.md @@ -1,29 +1,46 @@ # fittrackee_client -## Project setup -``` -yarn install +This template should help get you started developing with Vue 3 in Vite. + +## Recommended IDE Setup + +[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). + +## Type Support for `.vue` Imports in TS + +TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types. + +If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps: + +1. Disable the built-in TypeScript Extension + 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette + 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)` +2. Reload the VSCode window by running `Developer: Reload Window` from the command palette. + +## Customize configuration + +See [Vite Configuration Reference](https://vitejs.dev/config/). + +## Project Setup + +```sh +yarn ``` -### Compiles and hot-reloads for development -``` -yarn serve +### Compile and Hot-Reload for Development + +```sh +yarn dev ``` -### Compiles and minifies for production -``` +### Type-Check, Compile and Minify for Production + +```sh yarn build ``` -### Run your unit tests -``` -yarn test:unit -``` +### Lint with [ESLint](https://eslint.org/) -### Lints and fixes files -``` +```sh yarn lint ``` - -### Customize configuration -See [Configuration Reference](https://cli.vuejs.org/config/). diff --git a/fittrackee_client/babel.config.js b/fittrackee_client/babel.config.js deleted file mode 100644 index c1b783ea..00000000 --- a/fittrackee_client/babel.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - presets: ['@vue/cli-plugin-babel/preset'], -} diff --git a/fittrackee_client/env.d.ts b/fittrackee_client/env.d.ts new file mode 100644 index 00000000..11f02fe2 --- /dev/null +++ b/fittrackee_client/env.d.ts @@ -0,0 +1 @@ +/// diff --git a/fittrackee_client/index.html b/fittrackee_client/index.html new file mode 100644 index 00000000..1fa7e9e4 --- /dev/null +++ b/fittrackee_client/index.html @@ -0,0 +1,15 @@ + + + + + + + + + Vite App + + +
+ + + diff --git a/fittrackee_client/package.json b/fittrackee_client/package.json index a833992b..3c9f9ad8 100644 --- a/fittrackee_client/package.json +++ b/fittrackee_client/package.json @@ -3,127 +3,63 @@ "version": "0.7.25", "private": true, "scripts": { - "serve": "vue-cli-service serve", - "build": "vue-cli-service build", - "test:unit": "vue-cli-service test:unit", - "lint": "vue-cli-service lint", - "lint-fix": "vue-cli-service lint --fix", - "i18n:report": "vue-cli-service i18n:report --src \"./src/**/*.?(js|vue)\" --locales \"./src/locales/**/*.json\"" + "dev": "vite", + "build": "run-p type-check \"build-only {@}\" --", + "preview": "vite preview", + "build-only": "vite build", + "type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false", + "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore", + "format": "prettier --write src/" }, "dependencies": { "@tmcw/togeojson": "^5.8.1", - "@vue-leaflet/vue-leaflet": "0.9.0", + "@vue-leaflet/vue-leaflet": "^0.10.1", "@zxcvbn-ts/core": "^3.0.4", - "@zxcvbn-ts/language-common": "^3.0.3", + "@zxcvbn-ts/language-common": "^3.0.4", "@zxcvbn-ts/language-de": "^3.0.2", "@zxcvbn-ts/language-en": "^3.0.2", "@zxcvbn-ts/language-es-es": "^3.0.2", "@zxcvbn-ts/language-fr": "^3.0.2", "@zxcvbn-ts/language-it": "^3.0.2", "@zxcvbn-ts/language-pl": "^3.0.2", - "axios": "^1.5.1", + "axios": "^1.6.1", "chart.js": "^4.4.0", "chartjs-plugin-datalabels": "^2.2.0", - "core-js": "^3.33.0", - "date-fns": "2.29.3", + "core-js": "^3.33.2", + "date-fns": "2.30.0", "date-fns-tz": "^2.0.0", "leaflet": "^1.9.4", - "linkify-html": "^4.1.1", - "linkifyjs": "^4.1.1", - "register-service-worker": "^1.7.1", + "linkify-html": "^4.1.2", + "linkifyjs": "^4.1.2", "sanitize-html": "^2.11.0", "snarkdown": "^2.0.0", - "vue": "3.2.47", - "vue-chart-3": "3.1.1", + "vue": "^3.3.8", + "vue-chart-3": "^3.1.8", "vue-fullscreen": "^3.1.1", - "vue-i18n": "^9.5.0", + "vue-i18n": "^9.6.5", "vue-router": "^4.2.5", "vuex": "^4.1.0" }, "devDependencies": { "@intlify/vue-i18n-loader": "^4.2.0", - "@types/chai": "^4.3.6", - "@types/mocha": "^10.0.2", - "@types/sanitize-html": "^2.9.1", - "@typescript-eslint/eslint-plugin": "^5.60.0", - "@typescript-eslint/parser": "^5.60.0", - "@vue/cli-plugin-babel": "~5.0.8", - "@vue/cli-plugin-eslint": "~5.0.8", - "@vue/cli-plugin-pwa": "~5.0.8", - "@vue/cli-plugin-router": "~5.0.8", - "@vue/cli-plugin-typescript": "~5.0.8", - "@vue/cli-plugin-unit-mocha": "~5.0.8", - "@vue/cli-plugin-vuex": "~5.0.8", - "@vue/cli-service": "~5.0.8", - "@vue/eslint-config-typescript": "^11.0.3", - "@vue/test-utils": "^2.4.1", + "@rushstack/eslint-patch": "^1.3.3", + "@tsconfig/node18": "^18.2.2", + "@types/chai": "^4.3.10", + "@types/mocha": "^10.0.4", + "@types/node": "^20.9.0", + "@types/sanitize-html": "^2.9.4", + "@vitejs/plugin-vue": "^4.4.0", + "@vue/eslint-config-prettier": "^8.0.0", + "@vue/eslint-config-typescript": "^12.0.0", + "@vue/tsconfig": "^0.4.0", "chai": "^4.3.10", - "eslint": "8.42.0", - "eslint-config-prettier": "^8.10.0", - "eslint-import-resolver-typescript": "^3.6.1", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-prettier": "^4.2.1", + "eslint": "^8.49.0", "eslint-plugin-vue": "^9.17.0", - "prettier": "^2.8.8", - "sass": "^1.68.0", - "sass-loader": "^13.3.2", - "typescript": "5.0.4", - "vue-cli-plugin-i18n": "~2.3.2" - }, - "eslintConfig": { - "root": true, - "env": { - "node": true - }, - "extends": [ - "plugin:vue/vue3-essential", - "eslint:recommended", - "@vue/typescript/recommended", - "plugin:import/recommended", - "plugin:import/typescript" - ], - "globals": { - "defineProps": "readonly", - "defineEmits": "readonly", - "defineExpose": "readonly", - "withDefaults": "readonly" - }, - "settings": { - "import/resolver": "typescript" - }, - "parserOptions": { - "ecmaVersion": 2020, - "parser": "@typescript-eslint/parser" - }, - "rules": { - "import/order": [ - "error", - { - "newlines-between": "always", - "alphabetize": { - "order": "asc", - "caseInsensitive": true - } - } - ], - "vue/multi-word-component-names": "off" - }, - "overrides": [ - { - "files": [ - "**/__tests__/*.{j,t}s?(x)", - "**/tests/unit/**/*.spec.{j,t}s?(x)" - ], - "env": { - "mocha": true - } - } - ] - }, - "browserslist": [ - "> 1%", - "last 2 versions", - "not dead", - "not ie 11" - ] + "npm-run-all2": "^6.1.1", + "prettier": "^3.0.3", + "sass": "^1.69.5", + "typescript": "~5.2.0", + "vite": "^4.4.11", + "vue-tsc": "^1.8.19" + } } diff --git a/fittrackee_client/public/index.html b/fittrackee_client/public/index.html deleted file mode 100644 index 4835c894..00000000 --- a/fittrackee_client/public/index.html +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - <%= htmlWebpackPlugin.options.title %> - - - -
- - - diff --git a/fittrackee_client/src/App.vue b/fittrackee_client/src/App.vue index a5c90e46..4cc7167a 100644 --- a/fittrackee_client/src/App.vue +++ b/fittrackee_client/src/App.vue @@ -29,13 +29,14 @@ - diff --git a/fittrackee_client/src/components/Statistics/StatsSportsMenu.vue b/fittrackee_client/src/components/Statistics/StatsSportsMenu.vue index e2110e17..67a95cd0 100644 --- a/fittrackee_client/src/components/Statistics/StatsSportsMenu.vue +++ b/fittrackee_client/src/components/Statistics/StatsSportsMenu.vue @@ -8,7 +8,7 @@ > \ No newline at end of file + diff --git a/fittrackee_client/src/views/StatisticsView.vue b/fittrackee_client/src/views/StatisticsView.vue index 959167ce..8a7cb262 100644 --- a/fittrackee_client/src/views/StatisticsView.vue +++ b/fittrackee_client/src/views/StatisticsView.vue @@ -18,13 +18,14 @@ diff --git a/fittrackee_client/src/components/Common/CustomTextArea.vue b/fittrackee_client/src/components/Common/CustomTextArea.vue index 6b30d83f..629d9bcf 100644 --- a/fittrackee_client/src/components/Common/CustomTextArea.vue +++ b/fittrackee_client/src/components/Common/CustomTextArea.vue @@ -33,8 +33,8 @@ const text = ref('') - function updateText(event: Event & { target: HTMLInputElement }) { - emit('updateValue', event.target.value) + function updateText(event: Event) { + emit('updateValue', (event.target as HTMLInputElement).value) } watch( diff --git a/fittrackee_client/src/components/Common/FilterSelects.vue b/fittrackee_client/src/components/Common/FilterSelects.vue index 60efd561..38d6b62a 100644 --- a/fittrackee_client/src/components/Common/FilterSelects.vue +++ b/fittrackee_client/src/components/Common/FilterSelects.vue @@ -60,8 +60,12 @@ const { order_by, query, sort, message } = toRefs(props) const perPage = [10, 25, 50, 100] - function onSelectUpdate(event: Event & { target: HTMLInputElement }) { - emit('updateSelect', event.target.id, event.target.value) + function onSelectUpdate(event: Event) { + emit( + 'updateSelect', + (event.target as HTMLInputElement).id, + (event.target as HTMLInputElement).value + ) } diff --git a/fittrackee_client/src/components/Common/Images/SportImage/index.vue b/fittrackee_client/src/components/Common/Images/SportImage/index.vue index 1d910f08..8b42fc24 100644 --- a/fittrackee_client/src/components/Common/Images/SportImage/index.vue +++ b/fittrackee_client/src/components/Common/Images/SportImage/index.vue @@ -26,7 +26,7 @@ diff --git a/fittrackee_client/src/components/Common/Modal.vue b/fittrackee_client/src/components/Common/Modal.vue index a3c9851f..392366bd 100644 --- a/fittrackee_client/src/components/Common/Modal.vue +++ b/fittrackee_client/src/components/Common/Modal.vue @@ -50,7 +50,7 @@ strongMessage?: string | null } const props = withDefaults(defineProps(), { - strongMessage: () => null, + strongMessage: () => '', }) const emit = defineEmits(['cancelAction', 'confirmAction']) @@ -63,7 +63,7 @@ ) let confirmButton: HTMLElement | null = null let cancelButton: HTMLElement | null = null - let previousFocusedElement: Element | null = null + let previousFocusedElement: HTMLInputElement | null = null function focusTrap(e: KeyboardEvent) { if (e.key === 'Tab' || e.keyCode === 9) { @@ -77,7 +77,7 @@ } onMounted(() => { - previousFocusedElement = document.activeElement + previousFocusedElement = document.activeElement as HTMLInputElement | null cancelButton = document.getElementById('cancel-button') confirmButton = document.getElementById('confirm-button') if (cancelButton) { diff --git a/fittrackee_client/src/components/Common/Pagination.vue b/fittrackee_client/src/components/Common/Pagination.vue index d66ae395..2f1c36c7 100644 --- a/fittrackee_client/src/components/Common/Pagination.vue +++ b/fittrackee_client/src/components/Common/Pagination.vue @@ -50,6 +50,7 @@ diff --git a/fittrackee_client/src/components/Common/PasswordInput.vue b/fittrackee_client/src/components/Common/PasswordInput.vue index 72a51dae..2cae3eb3 100644 --- a/fittrackee_client/src/components/Common/PasswordInput.vue +++ b/fittrackee_client/src/components/Common/PasswordInput.vue @@ -62,8 +62,8 @@ function togglePassword() { showPassword.value = !showPassword.value } - function updatePassword(event: Event & { target: HTMLInputElement }) { - emit('updatePassword', event.target.value) + function updatePassword(event: Event) { + emit('updatePassword', (event.target as HTMLInputElement).value) } function invalidPassword() { emit('passwordError') diff --git a/fittrackee_client/src/components/Common/StatsChart/index.vue b/fittrackee_client/src/components/Common/StatsChart/index.vue index 863aad6f..92b56299 100644 --- a/fittrackee_client/src/components/Common/StatsChart/index.vue +++ b/fittrackee_client/src/components/Common/StatsChart/index.vue @@ -163,12 +163,9 @@ params: apiParams, }) } - function updateDisplayData( - event: Event & { - target: HTMLInputElement & { name: TStatisticsDatasetKeys } - } - ) { - displayedData.value = event.target.name + function updateDisplayData(event: Event) { + displayedData.value = (event.target as HTMLInputElement) + .name as TStatisticsDatasetKeys } function getApiParams( chartParams: IStatisticsDateParams, diff --git a/fittrackee_client/src/components/Dashboard/Timeline.vue b/fittrackee_client/src/components/Dashboard/Timeline.vue index 4769c231..ec1718c3 100644 --- a/fittrackee_client/src/components/Dashboard/Timeline.vue +++ b/fittrackee_client/src/components/Dashboard/Timeline.vue @@ -40,14 +40,14 @@ import NoWorkouts from '@/components/Workouts/NoWorkouts.vue' import { WORKOUTS_STORE } from '@/store/constants' import type { ISport } from '@/types/sports' - import type { IUserProfile } from '@/types/user' + import type { IAuthUserProfile } from '@/types/user' import type { IWorkout } from '@/types/workouts' import { useStore } from '@/use/useStore' import { defaultOrder } from '@/utils/workouts' interface Props { sports: ISport[] - user: IUserProfile + user: IAuthUserProfile } const props = defineProps() diff --git a/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarDays.vue b/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarDays.vue index 7ded724d..3512cbb0 100644 --- a/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarDays.vue +++ b/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarDays.vue @@ -16,7 +16,7 @@ } const props = defineProps() - const days = [] + const days: Date[] = [] for (let i = 0; i < 7; i++) { days.push(addDays(props.startDate, i)) } diff --git a/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkout.vue b/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkout.vue index 58b00925..df97054b 100644 --- a/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkout.vue +++ b/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkout.vue @@ -20,7 +20,9 @@ .filter((record) => displayHARecord ? true : record.record_type !== 'HA' ) - .map((record) => ` ${$t(`workouts.RECORD_${record.record_type}`)}`) + .map( + (record) => ` ${$t(`workouts.RECORD_${record.record_type}`)}` + )[0] " /> diff --git a/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkouts.vue b/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkouts.vue index 9ae5d796..708d898e 100644 --- a/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkouts.vue +++ b/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkouts.vue @@ -20,6 +20,7 @@ :sports="sports" :datasets="chartDatasets" :colors="colors" + :displayHARecord="displayHARecord" /> @@ -30,6 +31,7 @@ :sports="sports" :datasets="chartDatasets" :colors="colors" + :displayHARecord="displayHARecord" /> diff --git a/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkoutsChart.vue b/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkoutsChart.vue index 81bb4f06..b3e1947e 100644 --- a/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkoutsChart.vue +++ b/fittrackee_client/src/components/Dashboard/UserCalendar/CalendarWorkoutsChart.vue @@ -14,6 +14,7 @@ > sports: ISport[] workouts: IWorkout[] + displayHARecord: boolean } const props = defineProps() const { colors, datasets, sports, workouts } = toRefs(props) const isHidden = ref(true) - function togglePane(event: Event & { target: HTMLElement }) { + function togglePane(event: Event) { event.stopPropagation() isHidden.value = !isHidden.value } diff --git a/fittrackee_client/src/components/Dashboard/UserMonthStats.vue b/fittrackee_client/src/components/Dashboard/UserMonthStats.vue index f2582221..a2764843 100644 --- a/fittrackee_client/src/components/Dashboard/UserMonthStats.vue +++ b/fittrackee_client/src/components/Dashboard/UserMonthStats.vue @@ -21,11 +21,11 @@ import StatChart from '@/components/Common/StatsChart/index.vue' import type { ISport } from '@/types/sports' - import type { IUserProfile } from '@/types/user' + import type { IAuthUserProfile } from '@/types/user' interface Props { sports: ISport[] - user: IUserProfile + user: IAuthUserProfile } const props = defineProps() diff --git a/fittrackee_client/src/components/Dashboard/UserRecords/RecordsCard.vue b/fittrackee_client/src/components/Dashboard/UserRecords/RecordsCard.vue index a3a945ff..eb7c4d8a 100644 --- a/fittrackee_client/src/components/Dashboard/UserRecords/RecordsCard.vue +++ b/fittrackee_client/src/components/Dashboard/UserRecords/RecordsCard.vue @@ -35,11 +35,11 @@ import { toRefs } from 'vue' import { useI18n } from 'vue-i18n' - import type { ICardRecord, IRecord, IRecordsBySports } from '@/types/workouts' + import type { ICardRecord, IRecord, IRecordsBySport } from '@/types/workouts' import { sortRecords } from '@/utils/records' interface Props { - records: IRecordsBySports + records: IRecordsBySport sportTranslatedLabel: string } const props = defineProps() diff --git a/fittrackee_client/src/components/NavBar.vue b/fittrackee_client/src/components/NavBar.vue index f9d0a322..5fbced34 100644 --- a/fittrackee_client/src/components/NavBar.vue +++ b/fittrackee_client/src/components/NavBar.vue @@ -99,6 +99,7 @@ import UserPicture from '@/components/User/UserPicture.vue' import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants' import type { IDropdownOption } from '@/types/forms' + import type { TLanguage } from '@/types/locales' import type { IAuthUserProfile } from '@/types/user' import { useStore } from '@/use/useStore' import { availableLanguages } from '@/utils/locales' @@ -130,7 +131,7 @@ function updateLanguage(option: IDropdownOption) { store.dispatch( ROOT_STORE.ACTIONS.UPDATE_APPLICATION_LANGUAGE, - option.value.toString() + option.value as TLanguage ) } function logout() { diff --git a/fittrackee_client/src/components/Statistics/StatsSportsMenu.vue b/fittrackee_client/src/components/Statistics/StatsSportsMenu.vue index 67a95cd0..83c71954 100644 --- a/fittrackee_client/src/components/Statistics/StatsSportsMenu.vue +++ b/fittrackee_client/src/components/Statistics/StatsSportsMenu.vue @@ -39,7 +39,7 @@ const { t } = useI18n() - const sportColors: Record | undefined = inject('sportColors') + const sportColors = inject('sportColors') as Record const { selectedSportIds } = toRefs(props) const translatedSports: ComputedRef = computed(() => translateSports(props.userSports, t) diff --git a/fittrackee_client/src/components/User/ProfileDisplay/UserInfos.vue b/fittrackee_client/src/components/User/ProfileDisplay/UserInfos.vue index 1723b475..da2d956c 100644 --- a/fittrackee_client/src/components/User/ProfileDisplay/UserInfos.vue +++ b/fittrackee_client/src/components/User/ProfileDisplay/UserInfos.vue @@ -125,6 +125,7 @@ import { AUTH_USER_STORE, ROOT_STORE, USERS_STORE } from '@/store/constants' import type { TAppConfig } from '@/types/application' + import type { TLanguage } from '@/types/locales' import type { IAuthUserProfile, IUserProfile } from '@/types/user' import { useStore } from '@/use/useStore' import { formatDate, getDateFormat } from '@/utils/dates' @@ -141,7 +142,7 @@ const store = useStore() const { user, fromAdmin } = toRefs(props) - const language: ComputedRef = computed( + const language: ComputedRef = computed( () => store.getters[ROOT_STORE.GETTERS.LANGUAGE] ) const authUser: ComputedRef = computed( diff --git a/fittrackee_client/src/components/User/ProfileDisplay/UserPreferences.vue b/fittrackee_client/src/components/User/ProfileDisplay/UserPreferences.vue index 8289561e..90799c21 100644 --- a/fittrackee_client/src/components/User/ProfileDisplay/UserPreferences.vue +++ b/fittrackee_client/src/components/User/ProfileDisplay/UserPreferences.vue @@ -60,6 +60,7 @@ import type { ComputedRef } from 'vue' import { ROOT_STORE } from '@/store/constants' + import type { TLanguage } from '@/types/locales' import type { IAuthUserProfile } from '@/types/user' import { useStore } from '@/use/useStore' import { getDateFormat } from '@/utils/dates' @@ -72,7 +73,7 @@ const store = useStore() - const appLanguage: ComputedRef = computed( + const appLanguage: ComputedRef = computed( () => store.getters[ROOT_STORE.GETTERS.LANGUAGE] ) const userLanguage = computed(() => diff --git a/fittrackee_client/src/components/User/ProfileEdition/TimezoneDropdown.vue b/fittrackee_client/src/components/User/ProfileEdition/TimezoneDropdown.vue index 29b73948..4a5d5259 100644 --- a/fittrackee_client/src/components/User/ProfileEdition/TimezoneDropdown.vue +++ b/fittrackee_client/src/components/User/ProfileEdition/TimezoneDropdown.vue @@ -60,16 +60,16 @@ isOpen.value = false emit('updateTimezone', value) } - function onEnter(event: Event & { target: HTMLInputElement }) { + function onEnter(event: Event) { event.preventDefault() if (tzList.value?.firstElementChild?.innerHTML) { onUpdateTimezone(tzList.value?.firstElementChild?.innerHTML) } } - function openDropdown(event: Event & { target: HTMLInputElement }) { + function openDropdown(event: Event) { event.preventDefault() isOpen.value = true - timezone.value = event.target.value.trim() + timezone.value = (event.target as HTMLInputElement).value.trim() } watch( diff --git a/fittrackee_client/src/components/User/ProfileEdition/UserAccountEdition.vue b/fittrackee_client/src/components/User/ProfileEdition/UserAccountEdition.vue index b1d50232..c4448f14 100644 --- a/fittrackee_client/src/components/User/ProfileEdition/UserAccountEdition.vue +++ b/fittrackee_client/src/components/User/ProfileEdition/UserAccountEdition.vue @@ -87,7 +87,7 @@ >