diff --git a/.github/workflows/.tests-javascript.yml b/.github/workflows/.tests-javascript.yml index 4c4f94c6..8d80c77b 100644 --- a/.github/workflows/.tests-javascript.yml +++ b/.github/workflows/.tests-javascript.yml @@ -28,6 +28,9 @@ jobs: - name: Lint working-directory: ${{env.working-directory}} run: yarn lint + - name: Type check + working-directory: ${{env.working-directory}} + run: yarn type-check - name: Tests working-directory: ${{env.working-directory}} run: yarn test:unit diff --git a/fittrackee_client/src/App.vue b/fittrackee_client/src/App.vue index 4cc7167a..a6877f41 100644 --- a/fittrackee_client/src/App.vue +++ b/fittrackee_client/src/App.vue @@ -37,8 +37,9 @@ import NoConfig from '@/components/NoConfig.vue' import { ROOT_STORE } from '@/store/constants' import type { TAppConfig } from '@/types/application' + import type { TLanguage } from '@/types/locales' import { useStore } from '@/use/useStore' - import { localeFromLanguage } from '@/utils/locales' + import { isLanguageSupported } from '@/utils/locales' const store = useStore() @@ -82,10 +83,10 @@ }, 300) } function initLanguage() { - let language = 'en' + let language: TLanguage = 'en' try { const navigatorLanguage = navigator.language.split('-')[0] - if (navigatorLanguage in localeFromLanguage) { + if (isLanguageSupported(navigatorLanguage)) { language = navigatorLanguage } } catch (e) { diff --git a/fittrackee_client/src/components/Administration/AppStatsCards.vue b/fittrackee_client/src/components/Administration/AppStatsCards.vue index 536431b4..deabf8bb 100644 --- a/fittrackee_client/src/components/Administration/AppStatsCards.vue +++ b/fittrackee_client/src/components/Administration/AppStatsCards.vue @@ -37,7 +37,7 @@ const { appStatistics } = toRefs(props) const uploadDirSize = computed(() => - getReadableFileSize(appStatistics.value.uploads_dir_size, false) + getReadableFileSize(appStatistics.value.uploads_dir_size) ) 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 @@ >