style: fix linting issues met Prettier
This commit is contained in:
		
							parent
							
								
									ed8b5c919d
								
							
						
					
					
						commit
						ea5cf7abf9
					
				
					 26 changed files with 467 additions and 422 deletions
				
			
		|  | @ -1,10 +1,10 @@ | |||
| <script setup lang="ts"> | ||||
|     import ThemeCard from "@/components/ThemeCard.vue"; | ||||
|     import {ref, watchEffect, computed, type Ref} from "vue"; | ||||
|     import { ref, watchEffect, computed, type Ref } from "vue"; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
|     import { AGE_TO_THEMES, THEMESITEMS } from "@/utils/constants.ts"; | ||||
|     import { useThemeQuery } from "@/queries/themes.ts"; | ||||
|     import type {Theme} from "@/data-objects/theme.ts"; | ||||
|     import type { Theme } from "@/data-objects/theme.ts"; | ||||
| 
 | ||||
|     const props = defineProps({ | ||||
|         selectedTheme: { type: String, required: true }, | ||||
|  | @ -17,7 +17,7 @@ | |||
|     const { data: allThemes, isLoading, error } = useThemeQuery(language); | ||||
| 
 | ||||
|     const allCards: Ref<Theme[]> = ref([]); | ||||
|     const cards: Ref<Theme[]>  = ref([]); | ||||
|     const cards: Ref<Theme[]> = ref([]); | ||||
| 
 | ||||
|     watchEffect(() => { | ||||
|         const themes: Theme[] = allThemes.value ?? []; | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
|     import {useI18n} from "vue-i18n"; | ||||
|     import {useRoute, useRouter} from "vue-router"; | ||||
|     import {computed, ref} from "vue"; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
|     import { useRoute, useRouter } from "vue-router"; | ||||
|     import { computed, ref } from "vue"; | ||||
|     const route = useRoute(); | ||||
|     const router = useRouter(); | ||||
|     const { t } = useI18n(); | ||||
|  | @ -10,7 +10,7 @@ | |||
| 
 | ||||
|     const query = computed({ | ||||
|         get: () => route.query.query as string | null, | ||||
|         set: async (newValue) => router.push({path: SEARCH_PATH, query: {query: newValue}}) | ||||
|         set: async (newValue) => router.push({ path: SEARCH_PATH, query: { query: newValue } }), | ||||
|     }); | ||||
| 
 | ||||
|     const queryInput = ref(query.value); | ||||
|  | @ -31,6 +31,4 @@ | |||
|     ></v-text-field> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| 
 | ||||
| </style> | ||||
| <style scoped></style> | ||||
|  |  | |||
|  | @ -1,16 +1,17 @@ | |||
| <script setup lang="ts"> | ||||
|     import { convertBase64ToImageSrc } from "@/utils/base64ToImage.ts"; | ||||
|     import type { LearningPath } from "@/data-objects/learning-paths/learning-path.ts"; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
| 
 | ||||
| import {convertBase64ToImageSrc} from "@/utils/base64ToImage.ts"; | ||||
| import type {LearningPath} from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| import {useI18n} from "vue-i18n"; | ||||
| 
 | ||||
| const { t } = useI18n(); | ||||
| const props = defineProps<{learningPaths: LearningPath[]}>(); | ||||
| 
 | ||||
|     const { t } = useI18n(); | ||||
|     const props = defineProps<{ learningPaths: LearningPath[] }>(); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <div class="results-grid" v-if="props.learningPaths.length > 0"> | ||||
|     <div | ||||
|         class="results-grid" | ||||
|         v-if="props.learningPaths.length > 0" | ||||
|     > | ||||
|         <v-card | ||||
|             class="learning-path-card" | ||||
|             link | ||||
|  | @ -27,12 +28,15 @@ const props = defineProps<{learningPaths: LearningPath[]}>(); | |||
|             <v-card-title>{{ learningPath.title }}</v-card-title> | ||||
|             <v-card-subtitle> | ||||
|                 <v-icon icon="mdi-human-male-boy"></v-icon> | ||||
|                 <span>{{ learningPath.targetAges.min }} - {{ learningPath.targetAges.max }} {{ t('yearsAge') }}</span> | ||||
|                 <span>{{ learningPath.targetAges.min }} - {{ learningPath.targetAges.max }} {{ t("yearsAge") }}</span> | ||||
|             </v-card-subtitle> | ||||
|             <v-card-text>{{ learningPath.description }}</v-card-text> | ||||
|         </v-card> | ||||
|     </div> | ||||
|     <div content="empty-state-container" v-else> | ||||
|     <div | ||||
|         content="empty-state-container" | ||||
|         v-else | ||||
|     > | ||||
|         <v-empty-state | ||||
|             icon="mdi-emoticon-sad-outline" | ||||
|             :title="t('noLearningPathsFound')" | ||||
|  |  | |||
|  | @ -1,24 +1,27 @@ | |||
| <script setup lang="ts" generic="T"> | ||||
|     import {computed} from "vue"; | ||||
|     import {useI18n} from "vue-i18n"; | ||||
|     import type {UseQueryReturnType} from "@tanstack/vue-query"; | ||||
|     import { computed } from "vue"; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
|     import type { UseQueryReturnType } from "@tanstack/vue-query"; | ||||
| 
 | ||||
|     const props = defineProps<{ | ||||
|         queryResult: UseQueryReturnType<T, Error> | ||||
|     }>() | ||||
|         queryResult: UseQueryReturnType<T, Error>; | ||||
|     }>(); | ||||
| 
 | ||||
|     const { isLoading, isError, isSuccess, data, error } = props.queryResult; | ||||
| 
 | ||||
|     const { t } = useI18n(); | ||||
| 
 | ||||
|     const errorMessage = computed(() => { | ||||
|         const errorWithMessage = (error.value as {message: string}) || null; | ||||
|         return errorWithMessage?.message || JSON.stringify(errorWithMessage) | ||||
|         const errorWithMessage = (error.value as { message: string }) || null; | ||||
|         return errorWithMessage?.message || JSON.stringify(errorWithMessage); | ||||
|     }); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <div class="loading-div" v-if="isLoading"> | ||||
|     <div | ||||
|         class="loading-div" | ||||
|         v-if="isLoading" | ||||
|     > | ||||
|         <v-progress-circular indeterminate></v-progress-circular> | ||||
|     </div> | ||||
|     <div v-if="isError"> | ||||
|  | @ -28,12 +31,15 @@ | |||
|             :title="t('error_title')" | ||||
|         ></v-empty-state> | ||||
|     </div> | ||||
|     <slot v-if="isSuccess && data" :data="data"></slot> | ||||
|     <slot | ||||
|         v-if="isSuccess && data" | ||||
|         :data="data" | ||||
|     ></slot> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
|   .loading-div { | ||||
|       padding: 20px; | ||||
|       text-align: center; | ||||
|   } | ||||
|     .loading-div { | ||||
|         padding: 20px; | ||||
|         text-align: center; | ||||
|     } | ||||
| </style> | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import apiClient from "@/services/api-client/api-client.ts"; | ||||
| import type {AxiosResponse, ResponseType} from "axios"; | ||||
| import {HttpErrorResponseException} from "@/exception/http-error-response-exception.ts"; | ||||
| import type { AxiosResponse, ResponseType } from "axios"; | ||||
| import { HttpErrorResponseException } from "@/exception/http-error-response-exception.ts"; | ||||
| 
 | ||||
| export abstract class BaseController { | ||||
|     protected basePath: string; | ||||
|  | @ -16,10 +16,7 @@ export abstract class BaseController { | |||
|     } | ||||
| 
 | ||||
|     protected async get<T>(path: string, queryParams?: QueryParams, responseType?: ResponseType): Promise<T> { | ||||
|         const response = await apiClient.get<T>( | ||||
|             this.absolutePathFor(path), | ||||
|             {params: queryParams, responseType} | ||||
|         ); | ||||
|         const response = await apiClient.get<T>(this.absolutePathFor(path), { params: queryParams, responseType }); | ||||
|         BaseController.assertSuccessResponse(response); | ||||
|         return response.data; | ||||
|     } | ||||
|  | @ -31,7 +28,7 @@ export abstract class BaseController { | |||
|     } | ||||
| 
 | ||||
|     protected async delete<T>(path: string): Promise<T> { | ||||
|         const response = await apiClient.delete<T>(this.absolutePathFor(path)) | ||||
|         const response = await apiClient.delete<T>(this.absolutePathFor(path)); | ||||
|         BaseController.assertSuccessResponse(response); | ||||
|         return response.data; | ||||
|     } | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import { ThemeController } from "@/controllers/themes.ts"; | ||||
| import {LearningObjectController} from "@/controllers/learning-objects.ts"; | ||||
| import {LearningPathController} from "@/controllers/learning-paths.ts"; | ||||
| import { LearningObjectController } from "@/controllers/learning-objects.ts"; | ||||
| import { LearningPathController } from "@/controllers/learning-paths.ts"; | ||||
| 
 | ||||
| export function controllerGetter<T>(factory: new () => T): () => T { | ||||
|     let instance: T | undefined; | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import {BaseController} from "@/controllers/base-controller.ts"; | ||||
| import type {Language} from "@/data-objects/language.ts"; | ||||
| import type {LearningObject} from "@/data-objects/learning-objects/learning-object.ts"; | ||||
| import { BaseController } from "@/controllers/base-controller.ts"; | ||||
| import type { Language } from "@/data-objects/language.ts"; | ||||
| import type { LearningObject } from "@/data-objects/learning-objects/learning-object.ts"; | ||||
| 
 | ||||
| export class LearningObjectController extends BaseController { | ||||
|     constructor() { | ||||
|  | @ -8,10 +8,10 @@ export class LearningObjectController extends BaseController { | |||
|     } | ||||
| 
 | ||||
|     async getMetadata(hruid: string, language: Language, version: number): Promise<LearningObject> { | ||||
|         return this.get<LearningObject>(`/${hruid}`, {language, version}); | ||||
|         return this.get<LearningObject>(`/${hruid}`, { language, version }); | ||||
|     } | ||||
| 
 | ||||
|     async getHTML(hruid: string, language: Language, version: number): Promise<Document> { | ||||
|         return this.get<Document>(`/${hruid}/html`, {language, version}, "document"); | ||||
|         return this.get<Document>(`/${hruid}/html`, { language, version }, "document"); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,28 +1,32 @@ | |||
| import {BaseController} from "@/controllers/base-controller.ts"; | ||||
| import {LearningPath} from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| import type {Language} from "@/data-objects/language.ts"; | ||||
| import {single} from "@/utils/response-assertions.ts"; | ||||
| import type {LearningPathDTO} from "@/data-objects/learning-paths/learning-path-dto.ts"; | ||||
| import { BaseController } from "@/controllers/base-controller.ts"; | ||||
| import { LearningPath } from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| import type { Language } from "@/data-objects/language.ts"; | ||||
| import { single } from "@/utils/response-assertions.ts"; | ||||
| import type { LearningPathDTO } from "@/data-objects/learning-paths/learning-path-dto.ts"; | ||||
| 
 | ||||
| export class LearningPathController extends BaseController { | ||||
|     constructor() { | ||||
|         super("learningPath"); | ||||
|     } | ||||
|     async search(query: string): Promise<LearningPath[]> { | ||||
|         const dtos = await this.get<LearningPathDTO[]>("/", {search: query}); | ||||
|         return dtos.map(dto => LearningPath.fromDTO(dto)); | ||||
|         const dtos = await this.get<LearningPathDTO[]>("/", { search: query }); | ||||
|         return dtos.map((dto) => LearningPath.fromDTO(dto)); | ||||
|     } | ||||
|     async getBy(hruid: string, language: Language, options?: {forGroup?: string, forStudent?: string}): Promise<LearningPath> { | ||||
|     async getBy( | ||||
|         hruid: string, | ||||
|         language: Language, | ||||
|         options?: { forGroup?: string; forStudent?: string }, | ||||
|     ): Promise<LearningPath> { | ||||
|         const dtos = await this.get<LearningPathDTO[]>("/", { | ||||
|             hruid, | ||||
|             language, | ||||
|             forGroup: options?.forGroup, | ||||
|             forStudent: options?.forStudent | ||||
|             forStudent: options?.forStudent, | ||||
|         }); | ||||
|         return LearningPath.fromDTO(single(dtos)); | ||||
|     } | ||||
|     async getAllByTheme(theme: string): Promise<LearningPath[]> { | ||||
|         const dtos = await this.get<LearningPathDTO[]>("/", {theme}); | ||||
|         return dtos.map(dto => LearningPath.fromDTO(dto)); | ||||
|         const dtos = await this.get<LearningPathDTO[]>("/", { theme }); | ||||
|         return dtos.map((dto) => LearningPath.fromDTO(dto)); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,186 +1,186 @@ | |||
| export enum Language { | ||||
|     Afar = 'aa', | ||||
|     Abkhazian = 'ab', | ||||
|     Afrikaans = 'af', | ||||
|     Akan = 'ak', | ||||
|     Albanian = 'sq', | ||||
|     Amharic = 'am', | ||||
|     Arabic = 'ar', | ||||
|     Aragonese = 'an', | ||||
|     Armenian = 'hy', | ||||
|     Assamese = 'as', | ||||
|     Avaric = 'av', | ||||
|     Avestan = 'ae', | ||||
|     Aymara = 'ay', | ||||
|     Azerbaijani = 'az', | ||||
|     Bashkir = 'ba', | ||||
|     Bambara = 'bm', | ||||
|     Basque = 'eu', | ||||
|     Belarusian = 'be', | ||||
|     Bengali = 'bn', | ||||
|     Bihari = 'bh', | ||||
|     Bislama = 'bi', | ||||
|     Bosnian = 'bs', | ||||
|     Breton = 'br', | ||||
|     Bulgarian = 'bg', | ||||
|     Burmese = 'my', | ||||
|     Catalan = 'ca', | ||||
|     Chamorro = 'ch', | ||||
|     Chechen = 'ce', | ||||
|     Chinese = 'zh', | ||||
|     ChurchSlavic = 'cu', | ||||
|     Chuvash = 'cv', | ||||
|     Cornish = 'kw', | ||||
|     Corsican = 'co', | ||||
|     Cree = 'cr', | ||||
|     Czech = 'cs', | ||||
|     Danish = 'da', | ||||
|     Divehi = 'dv', | ||||
|     Dutch = 'nl', | ||||
|     Dzongkha = 'dz', | ||||
|     English = 'en', | ||||
|     Esperanto = 'eo', | ||||
|     Estonian = 'et', | ||||
|     Ewe = 'ee', | ||||
|     Faroese = 'fo', | ||||
|     Fijian = 'fj', | ||||
|     Finnish = 'fi', | ||||
|     French = 'fr', | ||||
|     Frisian = 'fy', | ||||
|     Fulah = 'ff', | ||||
|     Georgian = 'ka', | ||||
|     German = 'de', | ||||
|     Gaelic = 'gd', | ||||
|     Irish = 'ga', | ||||
|     Galician = 'gl', | ||||
|     Manx = 'gv', | ||||
|     Greek = 'el', | ||||
|     Guarani = 'gn', | ||||
|     Gujarati = 'gu', | ||||
|     Haitian = 'ht', | ||||
|     Hausa = 'ha', | ||||
|     Hebrew = 'he', | ||||
|     Herero = 'hz', | ||||
|     Hindi = 'hi', | ||||
|     HiriMotu = 'ho', | ||||
|     Croatian = 'hr', | ||||
|     Hungarian = 'hu', | ||||
|     Igbo = 'ig', | ||||
|     Icelandic = 'is', | ||||
|     Ido = 'io', | ||||
|     SichuanYi = 'ii', | ||||
|     Inuktitut = 'iu', | ||||
|     Interlingue = 'ie', | ||||
|     Interlingua = 'ia', | ||||
|     Indonesian = 'id', | ||||
|     Inupiaq = 'ik', | ||||
|     Italian = 'it', | ||||
|     Javanese = 'jv', | ||||
|     Japanese = 'ja', | ||||
|     Kalaallisut = 'kl', | ||||
|     Kannada = 'kn', | ||||
|     Kashmiri = 'ks', | ||||
|     Kanuri = 'kr', | ||||
|     Kazakh = 'kk', | ||||
|     Khmer = 'km', | ||||
|     Kikuyu = 'ki', | ||||
|     Kinyarwanda = 'rw', | ||||
|     Kirghiz = 'ky', | ||||
|     Komi = 'kv', | ||||
|     Kongo = 'kg', | ||||
|     Korean = 'ko', | ||||
|     Kuanyama = 'kj', | ||||
|     Kurdish = 'ku', | ||||
|     Lao = 'lo', | ||||
|     Latin = 'la', | ||||
|     Latvian = 'lv', | ||||
|     Limburgan = 'li', | ||||
|     Lingala = 'ln', | ||||
|     Lithuanian = 'lt', | ||||
|     Luxembourgish = 'lb', | ||||
|     LubaKatanga = 'lu', | ||||
|     Ganda = 'lg', | ||||
|     Macedonian = 'mk', | ||||
|     Marshallese = 'mh', | ||||
|     Malayalam = 'ml', | ||||
|     Maori = 'mi', | ||||
|     Marathi = 'mr', | ||||
|     Malay = 'ms', | ||||
|     Malagasy = 'mg', | ||||
|     Maltese = 'mt', | ||||
|     Mongolian = 'mn', | ||||
|     Nauru = 'na', | ||||
|     Navajo = 'nv', | ||||
|     SouthNdebele = 'nr', | ||||
|     NorthNdebele = 'nd', | ||||
|     Ndonga = 'ng', | ||||
|     Nepali = 'ne', | ||||
|     NorwegianNynorsk = 'nn', | ||||
|     NorwegianBokmal = 'nb', | ||||
|     Norwegian = 'no', | ||||
|     Chichewa = 'ny', | ||||
|     Occitan = 'oc', | ||||
|     Ojibwa = 'oj', | ||||
|     Oriya = 'or', | ||||
|     Oromo = 'om', | ||||
|     Ossetian = 'os', | ||||
|     Punjabi = 'pa', | ||||
|     Persian = 'fa', | ||||
|     Pali = 'pi', | ||||
|     Polish = 'pl', | ||||
|     Portuguese = 'pt', | ||||
|     Pashto = 'ps', | ||||
|     Quechua = 'qu', | ||||
|     Romansh = 'rm', | ||||
|     Romanian = 'ro', | ||||
|     Rundi = 'rn', | ||||
|     Russian = 'ru', | ||||
|     Sango = 'sg', | ||||
|     Sanskrit = 'sa', | ||||
|     Sinhala = 'si', | ||||
|     Slovak = 'sk', | ||||
|     Slovenian = 'sl', | ||||
|     NorthernSami = 'se', | ||||
|     Samoan = 'sm', | ||||
|     Shona = 'sn', | ||||
|     Sindhi = 'sd', | ||||
|     Somali = 'so', | ||||
|     Sotho = 'st', | ||||
|     Spanish = 'es', | ||||
|     Sardinian = 'sc', | ||||
|     Serbian = 'sr', | ||||
|     Swati = 'ss', | ||||
|     Sundanese = 'su', | ||||
|     Swahili = 'sw', | ||||
|     Swedish = 'sv', | ||||
|     Tahitian = 'ty', | ||||
|     Tamil = 'ta', | ||||
|     Tatar = 'tt', | ||||
|     Telugu = 'te', | ||||
|     Tajik = 'tg', | ||||
|     Tagalog = 'tl', | ||||
|     Thai = 'th', | ||||
|     Tibetan = 'bo', | ||||
|     Tigrinya = 'ti', | ||||
|     Tonga = 'to', | ||||
|     Tswana = 'tn', | ||||
|     Tsonga = 'ts', | ||||
|     Turkmen = 'tk', | ||||
|     Turkish = 'tr', | ||||
|     Twi = 'tw', | ||||
|     Uighur = 'ug', | ||||
|     Ukrainian = 'uk', | ||||
|     Urdu = 'ur', | ||||
|     Uzbek = 'uz', | ||||
|     Venda = 've', | ||||
|     Vietnamese = 'vi', | ||||
|     Volapuk = 'vo', | ||||
|     Welsh = 'cy', | ||||
|     Walloon = 'wa', | ||||
|     Wolof = 'wo', | ||||
|     Xhosa = 'xh', | ||||
|     Yiddish = 'yi', | ||||
|     Yoruba = 'yo', | ||||
|     Zhuang = 'za', | ||||
|     Zulu = 'zu', | ||||
|     Afar = "aa", | ||||
|     Abkhazian = "ab", | ||||
|     Afrikaans = "af", | ||||
|     Akan = "ak", | ||||
|     Albanian = "sq", | ||||
|     Amharic = "am", | ||||
|     Arabic = "ar", | ||||
|     Aragonese = "an", | ||||
|     Armenian = "hy", | ||||
|     Assamese = "as", | ||||
|     Avaric = "av", | ||||
|     Avestan = "ae", | ||||
|     Aymara = "ay", | ||||
|     Azerbaijani = "az", | ||||
|     Bashkir = "ba", | ||||
|     Bambara = "bm", | ||||
|     Basque = "eu", | ||||
|     Belarusian = "be", | ||||
|     Bengali = "bn", | ||||
|     Bihari = "bh", | ||||
|     Bislama = "bi", | ||||
|     Bosnian = "bs", | ||||
|     Breton = "br", | ||||
|     Bulgarian = "bg", | ||||
|     Burmese = "my", | ||||
|     Catalan = "ca", | ||||
|     Chamorro = "ch", | ||||
|     Chechen = "ce", | ||||
|     Chinese = "zh", | ||||
|     ChurchSlavic = "cu", | ||||
|     Chuvash = "cv", | ||||
|     Cornish = "kw", | ||||
|     Corsican = "co", | ||||
|     Cree = "cr", | ||||
|     Czech = "cs", | ||||
|     Danish = "da", | ||||
|     Divehi = "dv", | ||||
|     Dutch = "nl", | ||||
|     Dzongkha = "dz", | ||||
|     English = "en", | ||||
|     Esperanto = "eo", | ||||
|     Estonian = "et", | ||||
|     Ewe = "ee", | ||||
|     Faroese = "fo", | ||||
|     Fijian = "fj", | ||||
|     Finnish = "fi", | ||||
|     French = "fr", | ||||
|     Frisian = "fy", | ||||
|     Fulah = "ff", | ||||
|     Georgian = "ka", | ||||
|     German = "de", | ||||
|     Gaelic = "gd", | ||||
|     Irish = "ga", | ||||
|     Galician = "gl", | ||||
|     Manx = "gv", | ||||
|     Greek = "el", | ||||
|     Guarani = "gn", | ||||
|     Gujarati = "gu", | ||||
|     Haitian = "ht", | ||||
|     Hausa = "ha", | ||||
|     Hebrew = "he", | ||||
|     Herero = "hz", | ||||
|     Hindi = "hi", | ||||
|     HiriMotu = "ho", | ||||
|     Croatian = "hr", | ||||
|     Hungarian = "hu", | ||||
|     Igbo = "ig", | ||||
|     Icelandic = "is", | ||||
|     Ido = "io", | ||||
|     SichuanYi = "ii", | ||||
|     Inuktitut = "iu", | ||||
|     Interlingue = "ie", | ||||
|     Interlingua = "ia", | ||||
|     Indonesian = "id", | ||||
|     Inupiaq = "ik", | ||||
|     Italian = "it", | ||||
|     Javanese = "jv", | ||||
|     Japanese = "ja", | ||||
|     Kalaallisut = "kl", | ||||
|     Kannada = "kn", | ||||
|     Kashmiri = "ks", | ||||
|     Kanuri = "kr", | ||||
|     Kazakh = "kk", | ||||
|     Khmer = "km", | ||||
|     Kikuyu = "ki", | ||||
|     Kinyarwanda = "rw", | ||||
|     Kirghiz = "ky", | ||||
|     Komi = "kv", | ||||
|     Kongo = "kg", | ||||
|     Korean = "ko", | ||||
|     Kuanyama = "kj", | ||||
|     Kurdish = "ku", | ||||
|     Lao = "lo", | ||||
|     Latin = "la", | ||||
|     Latvian = "lv", | ||||
|     Limburgan = "li", | ||||
|     Lingala = "ln", | ||||
|     Lithuanian = "lt", | ||||
|     Luxembourgish = "lb", | ||||
|     LubaKatanga = "lu", | ||||
|     Ganda = "lg", | ||||
|     Macedonian = "mk", | ||||
|     Marshallese = "mh", | ||||
|     Malayalam = "ml", | ||||
|     Maori = "mi", | ||||
|     Marathi = "mr", | ||||
|     Malay = "ms", | ||||
|     Malagasy = "mg", | ||||
|     Maltese = "mt", | ||||
|     Mongolian = "mn", | ||||
|     Nauru = "na", | ||||
|     Navajo = "nv", | ||||
|     SouthNdebele = "nr", | ||||
|     NorthNdebele = "nd", | ||||
|     Ndonga = "ng", | ||||
|     Nepali = "ne", | ||||
|     NorwegianNynorsk = "nn", | ||||
|     NorwegianBokmal = "nb", | ||||
|     Norwegian = "no", | ||||
|     Chichewa = "ny", | ||||
|     Occitan = "oc", | ||||
|     Ojibwa = "oj", | ||||
|     Oriya = "or", | ||||
|     Oromo = "om", | ||||
|     Ossetian = "os", | ||||
|     Punjabi = "pa", | ||||
|     Persian = "fa", | ||||
|     Pali = "pi", | ||||
|     Polish = "pl", | ||||
|     Portuguese = "pt", | ||||
|     Pashto = "ps", | ||||
|     Quechua = "qu", | ||||
|     Romansh = "rm", | ||||
|     Romanian = "ro", | ||||
|     Rundi = "rn", | ||||
|     Russian = "ru", | ||||
|     Sango = "sg", | ||||
|     Sanskrit = "sa", | ||||
|     Sinhala = "si", | ||||
|     Slovak = "sk", | ||||
|     Slovenian = "sl", | ||||
|     NorthernSami = "se", | ||||
|     Samoan = "sm", | ||||
|     Shona = "sn", | ||||
|     Sindhi = "sd", | ||||
|     Somali = "so", | ||||
|     Sotho = "st", | ||||
|     Spanish = "es", | ||||
|     Sardinian = "sc", | ||||
|     Serbian = "sr", | ||||
|     Swati = "ss", | ||||
|     Sundanese = "su", | ||||
|     Swahili = "sw", | ||||
|     Swedish = "sv", | ||||
|     Tahitian = "ty", | ||||
|     Tamil = "ta", | ||||
|     Tatar = "tt", | ||||
|     Telugu = "te", | ||||
|     Tajik = "tg", | ||||
|     Tagalog = "tl", | ||||
|     Thai = "th", | ||||
|     Tibetan = "bo", | ||||
|     Tigrinya = "ti", | ||||
|     Tonga = "to", | ||||
|     Tswana = "tn", | ||||
|     Tsonga = "ts", | ||||
|     Turkmen = "tk", | ||||
|     Turkish = "tr", | ||||
|     Twi = "tw", | ||||
|     Uighur = "ug", | ||||
|     Ukrainian = "uk", | ||||
|     Urdu = "ur", | ||||
|     Uzbek = "uz", | ||||
|     Venda = "ve", | ||||
|     Vietnamese = "vi", | ||||
|     Volapuk = "vo", | ||||
|     Welsh = "cy", | ||||
|     Walloon = "wa", | ||||
|     Wolof = "wo", | ||||
|     Xhosa = "xh", | ||||
|     Yiddish = "yi", | ||||
|     Yoruba = "yo", | ||||
|     Zhuang = "za", | ||||
|     Zulu = "zu", | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import type {Language} from "@/data-objects/language.ts"; | ||||
| import type {ReturnValue} from "@/data-objects/learning-objects/return-value.ts"; | ||||
| import type {EducationalGoal} from "@/data-objects/learning-objects/educational-goal.ts"; | ||||
| import type { Language } from "@/data-objects/language.ts"; | ||||
| import type { ReturnValue } from "@/data-objects/learning-objects/return-value.ts"; | ||||
| import type { EducationalGoal } from "@/data-objects/learning-objects/educational-goal.ts"; | ||||
| 
 | ||||
| export interface LearningObject { | ||||
|     key: string; | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| import type {LearningPathNodeDTO} from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| import type { LearningPathNodeDTO } from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| 
 | ||||
| export interface LearningPathDTO { | ||||
|     language: string; | ||||
|  |  | |||
|  | @ -1,23 +1,23 @@ | |||
| import type {Language} from "@/data-objects/language.ts"; | ||||
| import type {LearningPathNodeDTO} from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| import type { Language } from "@/data-objects/language.ts"; | ||||
| import type { LearningPathNodeDTO } from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| 
 | ||||
| export class LearningPathNode { | ||||
|     public readonly learningobjectHruid: string; | ||||
|     public readonly version: number; | ||||
|     public readonly language: Language; | ||||
|     public readonly transitions: { next: LearningPathNode, default: boolean }[]; | ||||
|     public readonly transitions: { next: LearningPathNode; default: boolean }[]; | ||||
|     public readonly createdAt: Date; | ||||
|     public readonly updatedAt: Date; | ||||
|     public readonly done: boolean; | ||||
| 
 | ||||
|     constructor(options: { | ||||
|         learningobjectHruid: string, | ||||
|         version: number, | ||||
|         language: Language, | ||||
|         transitions: { next: LearningPathNode, default: boolean }[], | ||||
|         createdAt: Date, | ||||
|         updatedAt: Date, | ||||
|         done?: boolean | ||||
|         learningobjectHruid: string; | ||||
|         version: number; | ||||
|         language: Language; | ||||
|         transitions: { next: LearningPathNode; default: boolean }[]; | ||||
|         createdAt: Date; | ||||
|         updatedAt: Date; | ||||
|         done?: boolean; | ||||
|     }) { | ||||
|         this.learningobjectHruid = options.learningobjectHruid; | ||||
|         this.version = options.version; | ||||
|  | @ -33,25 +33,28 @@ export class LearningPathNode { | |||
|             learningobjectHruid: dto.learningobject_hruid, | ||||
|             version: dto.version, | ||||
|             language: dto.language, | ||||
|             transitions: dto.transitions.map(transDto => { | ||||
|                 const nextNodeDto = otherNodes.filter(it => | ||||
|                     it.learningobject_hruid === transDto.next.hruid | ||||
|                     && it.language === transDto.next.language | ||||
|                     && it.version === transDto.next.version | ||||
|             transitions: dto.transitions.map((transDto) => { | ||||
|                 const nextNodeDto = otherNodes.filter( | ||||
|                     (it) => | ||||
|                         it.learningobject_hruid === transDto.next.hruid && | ||||
|                         it.language === transDto.next.language && | ||||
|                         it.version === transDto.next.version, | ||||
|                 ); | ||||
|                 if (nextNodeDto.length !== 1) { | ||||
|                     throw new Error(`Invalid learning path! There is a transition to node` | ||||
|                         + `${transDto.next.hruid}/${transDto.next.language}/${transDto.next.version}, but there are` | ||||
|                         + `${nextNodeDto.length} such nodes.`); | ||||
|                     throw new Error( | ||||
|                         `Invalid learning path! There is a transition to node` + | ||||
|                             `${transDto.next.hruid}/${transDto.next.language}/${transDto.next.version}, but there are` + | ||||
|                             `${nextNodeDto.length} such nodes.`, | ||||
|                     ); | ||||
|                 } | ||||
|                 return { | ||||
|                     next: LearningPathNode.fromDTOAndOtherNodes(nextNodeDto[0], otherNodes), | ||||
|                     default: transDto.default | ||||
|                 } | ||||
|                     default: transDto.default, | ||||
|                 }; | ||||
|             }), | ||||
|             createdAt: new Date(dto.created_at), | ||||
|             updatedAt: new Date(dto.updatedAt), | ||||
|             done: dto.done | ||||
|         }) | ||||
|             done: dto.done, | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| import type {Language} from "@/data-objects/language.ts"; | ||||
| import {LearningPathNode} from "@/data-objects/learning-paths/learning-path-node.ts"; | ||||
| import type {LearningPathDTO} from "@/data-objects/learning-paths/learning-path-dto.ts"; | ||||
| import type { Language } from "@/data-objects/language.ts"; | ||||
| import { LearningPathNode } from "@/data-objects/learning-paths/learning-path-node.ts"; | ||||
| import type { LearningPathDTO } from "@/data-objects/learning-paths/learning-path-dto.ts"; | ||||
| 
 | ||||
| export interface LearningPathNodeDTO { | ||||
|     _id: string; | ||||
|  | @ -33,21 +33,21 @@ export class LearningPath { | |||
|     public readonly amountOfNodes: number; | ||||
|     public readonly amountOfNodesLeft: number; | ||||
|     public readonly keywords: string[]; | ||||
|     public readonly targetAges: {min: number; max: number}; | ||||
|     public readonly targetAges: { min: number; max: number }; | ||||
|     public readonly startNode: LearningPathNode; | ||||
|     public readonly image?: string; // Image might be missing, so it's optional
 | ||||
| 
 | ||||
|     constructor(options: { | ||||
|         language: string, | ||||
|         hruid: string, | ||||
|         title: string, | ||||
|         description: string, | ||||
|         amountOfNodes: number, | ||||
|         amountOfNodesLeft: number, | ||||
|         keywords: string[], | ||||
|         targetAges: {min: number; max: number}, | ||||
|         startNode: LearningPathNode, | ||||
|         image?: string // Image might be missing, so it's optional
 | ||||
|         language: string; | ||||
|         hruid: string; | ||||
|         title: string; | ||||
|         description: string; | ||||
|         amountOfNodes: number; | ||||
|         amountOfNodesLeft: number; | ||||
|         keywords: string[]; | ||||
|         targetAges: { min: number; max: number }; | ||||
|         startNode: LearningPathNode; | ||||
|         image?: string; // Image might be missing, so it's optional
 | ||||
|     }) { | ||||
|         this.language = options.language; | ||||
|         this.hruid = options.hruid; | ||||
|  | @ -66,14 +66,13 @@ export class LearningPath { | |||
|         let currentNode = this.startNode; | ||||
|         while (currentNode) { | ||||
|             list.push(currentNode); | ||||
|             currentNode = currentNode.transitions.find(it => it.default)?.next | ||||
|                             || currentNode.transitions[0]?.next; | ||||
|             currentNode = currentNode.transitions.find((it) => it.default)?.next || currentNode.transitions[0]?.next; | ||||
|         } | ||||
|         return list; | ||||
|     } | ||||
| 
 | ||||
|     static fromDTO(dto: LearningPathDTO): LearningPath { | ||||
|         const startNodeDto = dto.nodes.filter(it => it.start_node === true); | ||||
|         const startNodeDto = dto.nodes.filter((it) => it.start_node === true); | ||||
|         if (startNodeDto.length !== 1) { | ||||
|             throw new Error(`Invalid learning path: ${dto.hruid}/${dto.language}!
 | ||||
|                                 Expected precisely one start node, but there were ${startNodeDto.length}.`);
 | ||||
|  | @ -85,10 +84,10 @@ export class LearningPath { | |||
|             description: dto.description, | ||||
|             amountOfNodes: dto.num_nodes, | ||||
|             amountOfNodesLeft: dto.num_nodes_left, | ||||
|             keywords: dto.keywords.split(' '), | ||||
|             targetAges: {min: dto.min_age, max: dto.max_age}, | ||||
|             keywords: dto.keywords.split(" "), | ||||
|             targetAges: { min: dto.min_age, max: dto.max_age }, | ||||
|             startNode: LearningPathNode.fromDTOAndOtherNodes(startNodeDto[0], dto.nodes), | ||||
|             image: dto.image | ||||
|             image: dto.image, | ||||
|         }); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| import type {AxiosResponse} from "axios"; | ||||
| import type { AxiosResponse } from "axios"; | ||||
| 
 | ||||
| export class HttpErrorResponseException extends Error { | ||||
|     public statusCode: number; | ||||
|     constructor(public response: AxiosResponse<unknown, unknown>) { | ||||
|         super((response.data as {message: string})?.message || JSON.stringify(response.data)); | ||||
|         super((response.data as { message: string })?.message || JSON.stringify(response.data)); | ||||
|         this.statusCode = response.status; | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -10,8 +10,8 @@ import i18n from "./i18n/i18n.ts"; | |||
| // Components
 | ||||
| import App from "./App.vue"; | ||||
| import router from "./router"; | ||||
| import {aliases, mdi} from "vuetify/iconsets/mdi"; | ||||
| import { VueQueryPlugin, QueryClient } from '@tanstack/vue-query'; | ||||
| import { aliases, mdi } from "vuetify/iconsets/mdi"; | ||||
| import { VueQueryPlugin, QueryClient } from "@tanstack/vue-query"; | ||||
| 
 | ||||
| const app = createApp(App); | ||||
| 
 | ||||
|  | @ -29,9 +29,9 @@ const vuetify = createVuetify({ | |||
|         defaultSet: "mdi", | ||||
|         aliases, | ||||
|         sets: { | ||||
|             mdi | ||||
|         } | ||||
|     } | ||||
|             mdi, | ||||
|         }, | ||||
|     }, | ||||
| }); | ||||
| 
 | ||||
| const queryClient = new QueryClient({ | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| import {type MaybeRefOrGetter, toValue} from "vue"; | ||||
| import type {Language} from "@/data-objects/language.ts"; | ||||
| import {useQuery, type UseQueryReturnType} from "@tanstack/vue-query"; | ||||
| import {getLearningObjectController} from "@/controllers/controllers.ts"; | ||||
| import type {LearningObject} from "@/data-objects/learning-objects/learning-object.ts"; | ||||
| import type {LearningPath} from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| import { type MaybeRefOrGetter, toValue } from "vue"; | ||||
| import type { Language } from "@/data-objects/language.ts"; | ||||
| import { useQuery, type UseQueryReturnType } from "@tanstack/vue-query"; | ||||
| import { getLearningObjectController } from "@/controllers/controllers.ts"; | ||||
| import type { LearningObject } from "@/data-objects/learning-objects/learning-object.ts"; | ||||
| import type { LearningPath } from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| 
 | ||||
| const LEARNING_OBJECT_KEY = "learningObject"; | ||||
| const learningObjectController = getLearningObjectController(); | ||||
|  | @ -11,13 +11,13 @@ const learningObjectController = getLearningObjectController(); | |||
| export function useLearningObjectMetadataQuery( | ||||
|     hruid: MaybeRefOrGetter<string>, | ||||
|     language: MaybeRefOrGetter<Language>, | ||||
|     version: MaybeRefOrGetter<number> | ||||
|     version: MaybeRefOrGetter<number>, | ||||
| ): UseQueryReturnType<LearningObject, Error> { | ||||
|     return useQuery({ | ||||
|         queryKey: [LEARNING_OBJECT_KEY, "metadata", hruid, language, version], | ||||
|         queryFn: async () => { | ||||
|             const [hruidVal, languageVal, versionVal] = [toValue(hruid), toValue(language), toValue(version)]; | ||||
|             return learningObjectController.getMetadata(hruidVal, languageVal, versionVal) | ||||
|             return learningObjectController.getMetadata(hruidVal, languageVal, versionVal); | ||||
|         }, | ||||
|         enabled: () => Boolean(toValue(hruid)) && Boolean(toValue(language)) && Boolean(toValue(version)), | ||||
|     }); | ||||
|  | @ -26,20 +26,20 @@ export function useLearningObjectMetadataQuery( | |||
| export function useLearningObjectHTMLQuery( | ||||
|     hruid: MaybeRefOrGetter<string>, | ||||
|     language: MaybeRefOrGetter<Language>, | ||||
|     version: MaybeRefOrGetter<number> | ||||
|     version: MaybeRefOrGetter<number>, | ||||
| ): UseQueryReturnType<Document, Error> { | ||||
|     return useQuery({ | ||||
|         queryKey: [LEARNING_OBJECT_KEY, "html", hruid, language, version], | ||||
|         queryFn: async () => { | ||||
|             const [hruidVal, languageVal, versionVal] = [toValue(hruid), toValue(language), toValue(version)]; | ||||
|             return learningObjectController.getHTML(hruidVal, languageVal, versionVal) | ||||
|             return learningObjectController.getHTML(hruidVal, languageVal, versionVal); | ||||
|         }, | ||||
|         enabled: () => Boolean(toValue(hruid)) && Boolean(toValue(language)) && Boolean(toValue(version)), | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| export function useLearningObjectListForPathQuery( | ||||
|     learningPath: MaybeRefOrGetter<LearningPath | undefined> | ||||
|     learningPath: MaybeRefOrGetter<LearningPath | undefined>, | ||||
| ): UseQueryReturnType<LearningObject[], Error> { | ||||
|     return useQuery({ | ||||
|         queryKey: [LEARNING_OBJECT_KEY, "onPath", learningPath], | ||||
|  | @ -47,7 +47,7 @@ export function useLearningObjectListForPathQuery( | |||
|             const learningObjects: Promise<LearningObject>[] = []; | ||||
|             for (const node of toValue(learningPath)!.nodesAsList) { | ||||
|                 learningObjects.push( | ||||
|                     learningObjectController.getMetadata(node.learningobjectHruid, node.language, node.version) | ||||
|                     learningObjectController.getMetadata(node.learningobjectHruid, node.language, node.version), | ||||
|                 ); | ||||
|             } | ||||
|             return Promise.all(learningObjects); | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| import {type MaybeRefOrGetter, toValue} from "vue"; | ||||
| import type {Language} from "@/data-objects/language.ts"; | ||||
| import {useQuery, type UseQueryReturnType} from "@tanstack/vue-query"; | ||||
| import { type MaybeRefOrGetter, toValue } from "vue"; | ||||
| import type { Language } from "@/data-objects/language.ts"; | ||||
| import { useQuery, type UseQueryReturnType } from "@tanstack/vue-query"; | ||||
| import { getLearningPathController } from "@/controllers/controllers"; | ||||
| import type {LearningPath} from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| import type { LearningPath } from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| 
 | ||||
| const LEARNING_PATH_KEY = "learningPath"; | ||||
| const learningPathController = getLearningPathController(); | ||||
|  | @ -10,31 +10,31 @@ const learningPathController = getLearningPathController(); | |||
| export function useGetLearningPathQuery( | ||||
|     hruid: MaybeRefOrGetter<string>, | ||||
|     language: MaybeRefOrGetter<Language>, | ||||
|     options?: MaybeRefOrGetter<{forGroup?: string, forStudent?: string}> | ||||
|     options?: MaybeRefOrGetter<{ forGroup?: string; forStudent?: string }>, | ||||
| ): UseQueryReturnType<LearningPath, Error> { | ||||
|     return useQuery({ | ||||
|         queryKey: [LEARNING_PATH_KEY, "get", hruid, language, options], | ||||
|         queryFn: async () => { | ||||
|             const [hruidVal, languageVal, optionsVal] = [toValue(hruid), toValue(language), toValue(options)]; | ||||
|             return learningPathController.getBy(hruidVal, languageVal, optionsVal) | ||||
|             return learningPathController.getBy(hruidVal, languageVal, optionsVal); | ||||
|         }, | ||||
|         enabled: () => Boolean(toValue(hruid)) && Boolean(toValue(language)), | ||||
|     }) | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| export function useGetAllLearningPathsByThemeQuery( | ||||
|     theme: MaybeRefOrGetter<string> | ||||
|     theme: MaybeRefOrGetter<string>, | ||||
| ): UseQueryReturnType<LearningPath[], Error> { | ||||
|     return useQuery({ | ||||
|         queryKey: [LEARNING_PATH_KEY, "getAllByTheme", theme], | ||||
|         queryFn: async () => learningPathController.getAllByTheme(toValue(theme)), | ||||
|         enabled: () => Boolean(toValue(theme)), | ||||
|     }) | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| export function useSearchLearningPathQuery( | ||||
|     query: MaybeRefOrGetter<string | undefined> | ||||
| ): UseQueryReturnType<LearningPath[], Error>  { | ||||
|     query: MaybeRefOrGetter<string | undefined>, | ||||
| ): UseQueryReturnType<LearningPath[], Error> { | ||||
|     return useQuery({ | ||||
|         queryKey: [LEARNING_PATH_KEY, "search", query], | ||||
|         queryFn: async () => { | ||||
|  | @ -42,5 +42,5 @@ export function useSearchLearningPathQuery( | |||
|             return learningPathController.search(queryVal); | ||||
|         }, | ||||
|         enabled: () => Boolean(toValue(query)), | ||||
|     }) | ||||
|     }); | ||||
| } | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import { useQuery, type UseQueryReturnType } from "@tanstack/vue-query"; | ||||
| import { getThemeController } from "@/controllers/controllers"; | ||||
| import { type MaybeRefOrGetter, toValue } from "vue"; | ||||
| import type {Theme} from "@/data-objects/theme.ts"; | ||||
| import type { Theme } from "@/data-objects/theme.ts"; | ||||
| 
 | ||||
| const themeController = getThemeController(); | ||||
| 
 | ||||
|  |  | |||
|  | @ -115,7 +115,7 @@ const router = createRouter({ | |||
|                     path: "search", | ||||
|                     name: "LearningPathSearchPage", | ||||
|                     component: LearningPathSearchPage, | ||||
|                     meta: { requiresAuth: true } | ||||
|                     meta: { requiresAuth: true }, | ||||
|                 }, | ||||
|                 { | ||||
|                     path: ":hruid/:language/:learningObjectHruid", | ||||
|  | @ -124,14 +124,14 @@ const router = createRouter({ | |||
|                     props: true, | ||||
|                     meta: { requiresAuth: true }, | ||||
|                 }, | ||||
|             ] | ||||
|             ], | ||||
|         }, | ||||
|         { | ||||
|             path: "/learningObject/:hruid/:language/:version/raw", | ||||
|             name: "LearningObjectView", | ||||
|             component: LearningObjectView, | ||||
|             props: true, | ||||
|             meta: { requiresAuth: true } | ||||
|             meta: { requiresAuth: true }, | ||||
|         }, | ||||
|         { | ||||
|             path: "/:catchAll(.*)", | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| import {NotFoundException} from "@/exception/not-found-exception.ts"; | ||||
| import {InvalidResponseException} from "@/exception/invalid-response-exception.ts"; | ||||
| import { NotFoundException } from "@/exception/not-found-exception.ts"; | ||||
| import { InvalidResponseException } from "@/exception/invalid-response-exception.ts"; | ||||
| 
 | ||||
| export function single<T>(list: T[]): T { | ||||
|     if (list.length === 1) { | ||||
|  | @ -7,6 +7,8 @@ export function single<T>(list: T[]): T { | |||
|     } else if (list.length === 0) { | ||||
|         throw new NotFoundException("Expected list with exactly one element, but got an empty list."); | ||||
|     } else { | ||||
|         throw new InvalidResponseException(`Expected list with exactly one element, but got one with ${list.length} elements.`); | ||||
|         throw new InvalidResponseException( | ||||
|             `Expected list with exactly one element, but got one with ${list.length} elements.`, | ||||
|         ); | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <script setup lang="ts"> | ||||
|     import { useRouter } from "vue-router"; | ||||
|     import {onMounted, ref, type Ref} from "vue"; | ||||
|     import { onMounted, ref, type Ref } from "vue"; | ||||
|     import auth from "../services/auth/auth-service.ts"; | ||||
| 
 | ||||
|     const router = useRouter(); | ||||
|  |  | |||
|  | @ -1,33 +1,33 @@ | |||
| <script setup lang="ts"> | ||||
| import type {LearningPath} from "@/data-objects/learning-paths/learning-path.ts"; | ||||
| import LearningPathsGrid from "@/components/LearningPathsGrid.vue"; | ||||
| import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||
| import {useGetAllLearningPathsByThemeQuery} from "@/queries/learning-paths.ts"; | ||||
| import {computed, ref} from "vue"; | ||||
| import {useI18n} from "vue-i18n"; | ||||
| import {useThemeQuery} from "@/queries/themes.ts"; | ||||
|     import type { LearningPath } from "@/data-objects/learning-paths/learning-path.ts"; | ||||
|     import LearningPathsGrid from "@/components/LearningPathsGrid.vue"; | ||||
|     import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||
|     import { useGetAllLearningPathsByThemeQuery } from "@/queries/learning-paths.ts"; | ||||
|     import { computed, ref } from "vue"; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
|     import { useThemeQuery } from "@/queries/themes.ts"; | ||||
| 
 | ||||
| const props = defineProps<{theme: string}>(); | ||||
|     const props = defineProps<{ theme: string }>(); | ||||
| 
 | ||||
| const { locale } = useI18n(); | ||||
| const language = computed(() => locale.value); | ||||
|     const { locale } = useI18n(); | ||||
|     const language = computed(() => locale.value); | ||||
| 
 | ||||
| const themeQueryResult = useThemeQuery(language); | ||||
|     const themeQueryResult = useThemeQuery(language); | ||||
| 
 | ||||
| const currentThemeInfo = computed(() => themeQueryResult.data.value?.find(it => it.key === props.theme)); | ||||
|     const currentThemeInfo = computed(() => themeQueryResult.data.value?.find((it) => it.key === props.theme)); | ||||
| 
 | ||||
| const learningPathsForThemeQueryResult = useGetAllLearningPathsByThemeQuery(() => props.theme); | ||||
|     const learningPathsForThemeQueryResult = useGetAllLearningPathsByThemeQuery(() => props.theme); | ||||
| 
 | ||||
| const { t } = useI18n(); | ||||
| const searchFilter = ref(""); | ||||
| 
 | ||||
| function filterLearningPaths(learningPaths: LearningPath[]): LearningPath[] { | ||||
|     return learningPaths.filter(it => | ||||
|         it.title.toLowerCase().includes(searchFilter.value.toLowerCase()) | ||||
|         || it.description.toLowerCase().includes(searchFilter.value.toLowerCase()) | ||||
|     ); | ||||
| } | ||||
|     const { t } = useI18n(); | ||||
|     const searchFilter = ref(""); | ||||
| 
 | ||||
|     function filterLearningPaths(learningPaths: LearningPath[]): LearningPath[] { | ||||
|         return learningPaths.filter( | ||||
|             (it) => | ||||
|                 it.title.toLowerCase().includes(searchFilter.value.toLowerCase()) || | ||||
|                 it.description.toLowerCase().includes(searchFilter.value.toLowerCase()), | ||||
|         ); | ||||
|     } | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|  | @ -44,7 +44,10 @@ function filterLearningPaths(learningPaths: LearningPath[]): LearningPath[] { | |||
|                 ></v-text-field> | ||||
|             </div> | ||||
| 
 | ||||
|             <using-query-result :query-result="learningPathsForThemeQueryResult" v-slot="{ data }: {data: LearningPath[]}"> | ||||
|             <using-query-result | ||||
|                 :query-result="learningPathsForThemeQueryResult" | ||||
|                 v-slot="{ data }: { data: LearningPath[] }" | ||||
|             > | ||||
|                 <learning-paths-grid :learning-paths="filterLearningPaths(data)"></learning-paths-grid> | ||||
|             </using-query-result> | ||||
|         </using-query-result> | ||||
|  |  | |||
|  | @ -1,18 +1,27 @@ | |||
| <script setup lang="ts"> | ||||
| import {Language} from "@/data-objects/language.ts"; | ||||
| import type {UseQueryReturnType} from "@tanstack/vue-query"; | ||||
| import {useLearningObjectHTMLQuery} from "@/queries/learning-objects.ts"; | ||||
| import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||
|     import { Language } from "@/data-objects/language.ts"; | ||||
|     import type { UseQueryReturnType } from "@tanstack/vue-query"; | ||||
|     import { useLearningObjectHTMLQuery } from "@/queries/learning-objects.ts"; | ||||
|     import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||
| 
 | ||||
| const props = defineProps<{hruid: string, language: Language, version: number}>() | ||||
| 
 | ||||
| const learningObjectHtmlQueryResult: UseQueryReturnType<Document, Error> = useLearningObjectHTMLQuery(() => props.hruid, () => props.language, () => props.version); | ||||
|     const props = defineProps<{ hruid: string; language: Language; version: number }>(); | ||||
| 
 | ||||
|     const learningObjectHtmlQueryResult: UseQueryReturnType<Document, Error> = useLearningObjectHTMLQuery( | ||||
|         () => props.hruid, | ||||
|         () => props.language, | ||||
|         () => props.version, | ||||
|     ); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <using-query-result :query-result="learningObjectHtmlQueryResult as UseQueryReturnType<Document, Error>" v-slot="learningPathHtml : {data: Document}"> | ||||
|         <div class="learning-object-container" v-html="learningPathHtml.data.body.innerHTML"></div> | ||||
|     <using-query-result | ||||
|         :query-result="learningObjectHtmlQueryResult as UseQueryReturnType<Document, Error>" | ||||
|         v-slot="learningPathHtml: { data: Document }" | ||||
|     > | ||||
|         <div | ||||
|             class="learning-object-container" | ||||
|             v-html="learningPathHtml.data.body.innerHTML" | ||||
|         ></div> | ||||
|     </using-query-result> | ||||
| </template> | ||||
| 
 | ||||
|  | @ -32,7 +41,11 @@ const learningObjectHtmlQueryResult: UseQueryReturnType<Document, Error> = useLe | |||
|     :deep(img) { | ||||
|         max-width: 80%; | ||||
|     } | ||||
|     :deep(h2), :deep(h3), :deep(h4), :deep(h5), :deep(h6) { | ||||
|     :deep(h2), | ||||
|     :deep(h3), | ||||
|     :deep(h4), | ||||
|     :deep(h5), | ||||
|     :deep(h6) { | ||||
|         margin-top: 10px; | ||||
|     } | ||||
| </style> | ||||
|  |  | |||
|  | @ -1,68 +1,61 @@ | |||
| <script setup lang="ts"> | ||||
|     import {Language} from "@/data-objects/language.ts"; | ||||
|     import type {LearningPath} from "@/data-objects/learning-paths/learning-path.ts"; | ||||
|     import {computed, type ComputedRef, ref} from "vue"; | ||||
|     import type {LearningObject} from "@/data-objects/learning-objects/learning-object.ts"; | ||||
|     import {useRoute} from "vue-router"; | ||||
|     import { Language } from "@/data-objects/language.ts"; | ||||
|     import type { LearningPath } from "@/data-objects/learning-paths/learning-path.ts"; | ||||
|     import { computed, type ComputedRef, ref } from "vue"; | ||||
|     import type { LearningObject } from "@/data-objects/learning-objects/learning-object.ts"; | ||||
|     import { useRoute } from "vue-router"; | ||||
|     import LearningObjectView from "@/views/learning-paths/LearningObjectView.vue"; | ||||
|     import {useI18n} from "vue-i18n"; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
|     import LearningPathSearchField from "@/components/LearningPathSearchField.vue"; | ||||
|     import {useGetLearningPathQuery} from "@/queries/learning-paths.ts"; | ||||
|     import {useLearningObjectListForPathQuery} from "@/queries/learning-objects.ts"; | ||||
|     import { useGetLearningPathQuery } from "@/queries/learning-paths.ts"; | ||||
|     import { useLearningObjectListForPathQuery } from "@/queries/learning-objects.ts"; | ||||
|     import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||
|     import authService from "@/services/auth/auth-service.ts"; | ||||
|     import {LearningPathNode} from "@/data-objects/learning-paths/learning-path-node.ts"; | ||||
|     import { LearningPathNode } from "@/data-objects/learning-paths/learning-path-node.ts"; | ||||
| 
 | ||||
|     const route = useRoute(); | ||||
|     const { t } = useI18n(); | ||||
| 
 | ||||
|     const props = defineProps<{hruid: string, language: Language, learningObjectHruid?: string}>() | ||||
|     const props = defineProps<{ hruid: string; language: Language; learningObjectHruid?: string }>(); | ||||
| 
 | ||||
|     interface Personalization { | ||||
|         forStudent?: string, | ||||
|         forGroup?: string | ||||
|         forStudent?: string; | ||||
|         forGroup?: string; | ||||
|     } | ||||
| 
 | ||||
|     const personalization = computed(() => { | ||||
|         if (route.query.forStudent || route.query.forGroup) { | ||||
|             return { | ||||
|                 forStudent: route.query.forStudent, | ||||
|                 forGroup: route.query.forGroup | ||||
|             } as Personalization | ||||
|                 forGroup: route.query.forGroup, | ||||
|             } as Personalization; | ||||
|         } | ||||
|             return { | ||||
|                 forStudent: authService.authState.user?.profile?.preferred_username | ||||
|             } as Personalization | ||||
| 
 | ||||
|         return { | ||||
|             forStudent: authService.authState.user?.profile?.preferred_username, | ||||
|         } as Personalization; | ||||
|     }); | ||||
| 
 | ||||
|     const learningPathQueryResult = useGetLearningPathQuery( | ||||
|         props.hruid, | ||||
|         props.language, | ||||
|         personalization | ||||
|     ); | ||||
|     const learningPathQueryResult = useGetLearningPathQuery(props.hruid, props.language, personalization); | ||||
| 
 | ||||
|     const learningObjectListQueryResult = useLearningObjectListForPathQuery(learningPathQueryResult.data); | ||||
| 
 | ||||
|     const nodesList: ComputedRef<LearningPathNode[] | null> = computed(() => | ||||
|         learningPathQueryResult.data.value?.nodesAsList ?? null | ||||
|     const nodesList: ComputedRef<LearningPathNode[] | null> = computed( | ||||
|         () => learningPathQueryResult.data.value?.nodesAsList ?? null, | ||||
|     ); | ||||
| 
 | ||||
|     const currentNode = computed(() => { | ||||
|         const currentHruid = props.learningObjectHruid; | ||||
|         return nodesList.value?.find(it => it.learningobjectHruid === currentHruid); | ||||
|         return nodesList.value?.find((it) => it.learningobjectHruid === currentHruid); | ||||
|     }); | ||||
| 
 | ||||
|     const nextNode = computed(() => { | ||||
|         if (!currentNode.value || !nodesList.value) | ||||
|             return undefined; | ||||
|         if (!currentNode.value || !nodesList.value) return undefined; | ||||
|         const currentIndex = nodesList.value?.indexOf(currentNode.value); | ||||
|         return currentIndex < nodesList.value?.length ? nodesList.value?.[currentIndex + 1] : undefined; | ||||
|     }); | ||||
| 
 | ||||
|     const previousNode = computed(() => { | ||||
|         if (!currentNode.value || !nodesList.value) | ||||
|             return undefined; | ||||
|         if (!currentNode.value || !nodesList.value) return undefined; | ||||
|         const currentIndex = nodesList.value?.indexOf(currentNode.value); | ||||
|         return currentIndex < nodesList.value?.length ? nodesList.value?.[currentIndex - 1] : undefined; | ||||
|     }); | ||||
|  | @ -71,11 +64,14 @@ | |||
| 
 | ||||
|     function isLearningObjectCompleted(learningObject: LearningObject): boolean { | ||||
|         if (learningObjectListQueryResult.isSuccess) { | ||||
|             return learningPathQueryResult.data.value?.nodesAsList?.find(it => | ||||
|                 it.learningobjectHruid === learningObject.key | ||||
|                 && it.version === learningObject.version | ||||
|                 && it.language === learningObject.language | ||||
|             )?.done ?? false; | ||||
|             return ( | ||||
|                 learningPathQueryResult.data.value?.nodesAsList?.find( | ||||
|                     (it) => | ||||
|                         it.learningobjectHruid === learningObject.key && | ||||
|                         it.version === learningObject.version && | ||||
|                         it.language === learningObject.language, | ||||
|                 )?.done ?? false | ||||
|             ); | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | @ -85,14 +81,14 @@ | |||
|     const ICONS: Record<NavItemState, string> = { | ||||
|         teacherExclusive: "mdi-information", | ||||
|         completed: "mdi-checkbox-marked-circle-outline", | ||||
|         notCompleted: "mdi-checkbox-blank-circle-outline" | ||||
|     } | ||||
|         notCompleted: "mdi-checkbox-blank-circle-outline", | ||||
|     }; | ||||
| 
 | ||||
|     const COLORS: Record<NavItemState, string | undefined>  = { | ||||
|     const COLORS: Record<NavItemState, string | undefined> = { | ||||
|         teacherExclusive: "info", | ||||
|         completed: "success", | ||||
|         notCompleted: undefined | ||||
|     } | ||||
|         notCompleted: undefined, | ||||
|     }; | ||||
| 
 | ||||
|     function getNavItemState(learningObject: LearningObject): NavItemState { | ||||
|         if (learningObject.teacherExclusive) { | ||||
|  | @ -100,15 +96,14 @@ | |||
|         } else if (isLearningObjectCompleted(learningObject)) { | ||||
|             return "completed"; | ||||
|         } | ||||
|             return "notCompleted"; | ||||
| 
 | ||||
|         return "notCompleted"; | ||||
|     } | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <using-query-result | ||||
|         :query-result="learningPathQueryResult" | ||||
|         v-slot="learningPath: {data: LearningPath}" | ||||
|         v-slot="learningPath: { data: LearningPath }" | ||||
|     > | ||||
|         <v-navigation-drawer v-model="navigationDrawerShown"> | ||||
|             <v-list-item | ||||
|  | @ -117,21 +112,39 @@ | |||
|             ></v-list-item> | ||||
|             <v-list-item> | ||||
|                 <template v-slot:subtitle> | ||||
|                     <p><v-icon :color="COLORS.notCompleted" :icon="ICONS.notCompleted"></v-icon> {{ t("legendNotCompletedYet") }}</p> | ||||
|                     <p><v-icon :color="COLORS.completed" :icon="ICONS.completed"></v-icon> {{ t("legendCompleted") }}</p> | ||||
|                     <p><v-icon :color="COLORS.teacherExclusive" :icon="ICONS.teacherExclusive"></v-icon> {{ t("legendTeacherExclusive") }}</p> | ||||
|                     <p> | ||||
|                         <v-icon | ||||
|                             :color="COLORS.notCompleted" | ||||
|                             :icon="ICONS.notCompleted" | ||||
|                         ></v-icon> | ||||
|                         {{ t("legendNotCompletedYet") }} | ||||
|                     </p> | ||||
|                     <p> | ||||
|                         <v-icon | ||||
|                             :color="COLORS.completed" | ||||
|                             :icon="ICONS.completed" | ||||
|                         ></v-icon> | ||||
|                         {{ t("legendCompleted") }} | ||||
|                     </p> | ||||
|                     <p> | ||||
|                         <v-icon | ||||
|                             :color="COLORS.teacherExclusive" | ||||
|                             :icon="ICONS.teacherExclusive" | ||||
|                         ></v-icon> | ||||
|                         {{ t("legendTeacherExclusive") }} | ||||
|                     </p> | ||||
|                 </template> | ||||
|             </v-list-item> | ||||
|             <v-divider></v-divider> | ||||
|             <div v-if="props.learningObjectHruid"> | ||||
|                 <using-query-result | ||||
|                     :query-result="learningObjectListQueryResult" | ||||
|                     v-slot="learningObjects: {data: LearningObject[]}" | ||||
|                     v-slot="learningObjects: { data: LearningObject[] }" | ||||
|                 > | ||||
|                     <template v-for="node in learningObjects.data"> | ||||
|                         <v-list-item | ||||
|                             link | ||||
|                             :to="{path: node.key, query: route.query}" | ||||
|                             :to="{ path: node.key, query: route.query }" | ||||
|                             :title="node.title" | ||||
|                             :active="node.key === props.learningObjectHruid" | ||||
|                             :key="node.key" | ||||
|  | @ -140,11 +153,10 @@ | |||
|                             <template v-slot:prepend> | ||||
|                                 <v-icon | ||||
|                                     :color="COLORS[getNavItemState(node)]" | ||||
|                                     :icon="ICONS[getNavItemState(node)]"></v-icon> | ||||
|                             </template> | ||||
|                             <template v-slot:append> | ||||
|                                 {{ node.estimatedTime }}' | ||||
|                                     :icon="ICONS[getNavItemState(node)]" | ||||
|                                 ></v-icon> | ||||
|                             </template> | ||||
|                             <template v-slot:append> {{ node.estimatedTime }}' </template> | ||||
|                         </v-list-item> | ||||
|                     </template> | ||||
|                 </using-query-result> | ||||
|  | @ -155,7 +167,8 @@ | |||
|                 :icon="navigationDrawerShown ? 'mdi-menu-open' : 'mdi-menu'" | ||||
|                 class="navigation-drawer-toggle-button" | ||||
|                 variant="plain" | ||||
|                 @click="navigationDrawerShown = !navigationDrawerShown"></v-btn> | ||||
|                 @click="navigationDrawerShown = !navigationDrawerShown" | ||||
|             ></v-btn> | ||||
|             <div class="search-field-container"> | ||||
|                 <learning-path-search-field></learning-path-search-field> | ||||
|             </div> | ||||
|  | @ -171,7 +184,7 @@ | |||
|                 prepend-icon="mdi-chevron-left" | ||||
|                 variant="text" | ||||
|                 :disabled="!previousNode" | ||||
|                 :to="previousNode ? {path: previousNode.learningobjectHruid, query: route.query} : undefined" | ||||
|                 :to="previousNode ? { path: previousNode.learningobjectHruid, query: route.query } : undefined" | ||||
|             > | ||||
|                 {{ t("previous") }} | ||||
|             </v-btn> | ||||
|  | @ -179,7 +192,7 @@ | |||
|                 append-icon="mdi-chevron-right" | ||||
|                 variant="text" | ||||
|                 :disabled="!nextNode" | ||||
|                 :to="nextNode ? {path: nextNode.learningobjectHruid, query: route.query} : undefined" | ||||
|                 :to="nextNode ? { path: nextNode.learningobjectHruid, query: route.query } : undefined" | ||||
|             > | ||||
|                 {{ t("next") }} | ||||
|             </v-btn> | ||||
|  |  | |||
|  | @ -1,10 +1,10 @@ | |||
| <script setup lang="ts"> | ||||
|     import type {LearningPath} from "@/data-objects/learning-paths/learning-path.ts"; | ||||
|     import {useRoute} from "vue-router"; | ||||
|     import {computed} from "vue"; | ||||
|     import {useI18n} from "vue-i18n"; | ||||
|     import type { LearningPath } from "@/data-objects/learning-paths/learning-path.ts"; | ||||
|     import { useRoute } from "vue-router"; | ||||
|     import { computed } from "vue"; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
|     import LearningPathSearchField from "@/components/LearningPathSearchField.vue"; | ||||
|     import {useSearchLearningPathQuery} from "@/queries/learning-paths.ts"; | ||||
|     import { useSearchLearningPathQuery } from "@/queries/learning-paths.ts"; | ||||
|     import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||
|     import LearningPathsGrid from "@/components/LearningPathsGrid.vue"; | ||||
| 
 | ||||
|  | @ -21,7 +21,10 @@ | |||
|         <learning-path-search-field class="search-field"></learning-path-search-field> | ||||
|     </div> | ||||
| 
 | ||||
|     <using-query-result :query-result="searchQueryResults" v-slot="{ data }: {data: LearningPath[]}"> | ||||
|     <using-query-result | ||||
|         :query-result="searchQueryResults" | ||||
|         v-slot="{ data }: { data: LearningPath[] }" | ||||
|     > | ||||
|         <learning-paths-grid :learning-paths="data"></learning-paths-grid> | ||||
|     </using-query-result> | ||||
|     <div content="empty-state-container"> | ||||
|  |  | |||
		Reference in a new issue
	
	 Lint Action
						Lint Action