style: fix linting issues met Prettier
This commit is contained in:
		
							parent
							
								
									2f5bb333db
								
							
						
					
					
						commit
						fc92570282
					
				
					 16 changed files with 498 additions and 505 deletions
				
			
		|  | @ -66,7 +66,7 @@ export async function getLearningPaths(req: AuthenticatedRequest, res: Response) | |||
| 
 | ||||
|             if (req.auth) { | ||||
|                 const adminUsername = req.auth.username; | ||||
|                 const userLearningPaths = await learningPathService.getLearningPathsAdministratedBy(adminUsername) || []; | ||||
|                 const userLearningPaths = (await learningPathService.getLearningPathsAdministratedBy(adminUsername)) || []; | ||||
|                 allLearningPaths = apiLearningPaths.concat(userLearningPaths); | ||||
|             } | ||||
| 
 | ||||
|  | @ -78,7 +78,7 @@ export async function getLearningPaths(req: AuthenticatedRequest, res: Response) | |||
|             hruidList, | ||||
|             language as Language, | ||||
|             `HRUIDs: ${hruidList.join(', ')}`, | ||||
|             forGroup, | ||||
|             forGroup | ||||
|         ); | ||||
|         res.json(learningPaths.data); | ||||
|     } | ||||
|  |  | |||
|  | @ -7,10 +7,13 @@ import { LearningPathTransition } from '../../entities/content/learning-path-tra | |||
| 
 | ||||
| export class LearningPathRepository extends DwengoEntityRepository<LearningPath> { | ||||
|     public async findByHruidAndLanguage(hruid: string, language: Language): Promise<LearningPath | null> { | ||||
|         return this.findOne({ | ||||
|         return this.findOne( | ||||
|             { | ||||
|                 hruid: hruid, | ||||
|                 language: language, | ||||
|         }, { populate: ['nodes', 'nodes.transitions', 'admins'] }); | ||||
|             }, | ||||
|             { populate: ['nodes', 'nodes.transitions', 'admins'] } | ||||
|         ); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  |  | |||
|  | @ -4,11 +4,7 @@ import { getLearningPathRepository } from '../../data/repositories.js'; | |||
| import learningObjectService from '../learning-objects/learning-object-service.js'; | ||||
| import { LearningPathNode } from '../../entities/content/learning-path-node.entity.js'; | ||||
| import { LearningPathTransition } from '../../entities/content/learning-path-transition.entity.js'; | ||||
| import { | ||||
|     getLastSubmissionForGroup, | ||||
|     idFromLearningPathNode, | ||||
|     isTransitionPossible, | ||||
| } from './learning-path-personalization-util.js'; | ||||
| import { getLastSubmissionForGroup, idFromLearningPathNode, isTransitionPossible } from './learning-path-personalization-util.js'; | ||||
| import { | ||||
|     FilteredLearningObject, | ||||
|     LearningObjectNode, | ||||
|  | @ -41,9 +37,9 @@ async function getLearningObjectsForNodes(nodes: Collection<LearningPathNode>): | |||
|                         version: node.version, | ||||
|                         language: node.language, | ||||
|                     }) | ||||
|                     .then((learningObject) => [node, learningObject] as [LearningPathNode, FilteredLearningObject | null]), | ||||
|             ), | ||||
|         ), | ||||
|                     .then((learningObject) => [node, learningObject] as [LearningPathNode, FilteredLearningObject | null]) | ||||
|             ) | ||||
|         ) | ||||
|     ); | ||||
| 
 | ||||
|     // Ignore all learning objects that cannot be found such that the rest of the learning path keeps working.
 | ||||
|  | @ -105,14 +101,14 @@ async function convertNode( | |||
|     node: LearningPathNode, | ||||
|     learningObject: FilteredLearningObject, | ||||
|     personalizedFor: Group | undefined, | ||||
|     nodesToLearningObjects: Map<LearningPathNode, FilteredLearningObject>, | ||||
|     nodesToLearningObjects: Map<LearningPathNode, FilteredLearningObject> | ||||
| ): Promise<LearningObjectNode> { | ||||
|     const lastSubmission = personalizedFor ? await getLastSubmissionForGroup(idFromLearningPathNode(node), personalizedFor) : null; | ||||
|     const transitions = node.transitions | ||||
|         .filter( | ||||
|             (trans) => | ||||
|                 !personalizedFor || // If we do not want a personalized learning path, keep all transitions
 | ||||
|                 isTransitionPossible(trans, optionalJsonStringToObject(lastSubmission?.content)), // Otherwise remove all transitions that aren't possible.
 | ||||
|                 isTransitionPossible(trans, optionalJsonStringToObject(lastSubmission?.content)) // Otherwise remove all transitions that aren't possible.
 | ||||
|         ) | ||||
|         .map((trans, i) => { | ||||
|             try { | ||||
|  | @ -145,10 +141,10 @@ async function convertNode( | |||
|  */ | ||||
| async function convertNodes( | ||||
|     nodesToLearningObjects: Map<LearningPathNode, FilteredLearningObject>, | ||||
|     personalizedFor?: Group, | ||||
|     personalizedFor?: Group | ||||
| ): Promise<LearningObjectNode[]> { | ||||
|     const nodesPromise = Array.from(nodesToLearningObjects.entries()).map(async (entry) => | ||||
|         convertNode(entry[0], entry[1], personalizedFor, nodesToLearningObjects), | ||||
|         convertNode(entry[0], entry[1], personalizedFor, nodesToLearningObjects) | ||||
|     ); | ||||
|     return await Promise.all(nodesPromise); | ||||
| } | ||||
|  | @ -175,7 +171,7 @@ function optionalJsonStringToObject(jsonString?: string): object | null { | |||
| function convertTransition( | ||||
|     transition: LearningPathTransition, | ||||
|     index: number, | ||||
|     nodesToLearningObjects: Map<LearningPathNode, FilteredLearningObject>, | ||||
|     nodesToLearningObjects: Map<LearningPathNode, FilteredLearningObject> | ||||
| ): Transition { | ||||
|     const nextNode = nodesToLearningObjects.get(transition.next); | ||||
|     if (!nextNode) { | ||||
|  | @ -206,10 +202,10 @@ const databaseLearningPathProvider: LearningPathProvider = { | |||
|         const learningPathRepo = getLearningPathRepository(); | ||||
| 
 | ||||
|         const learningPaths = (await Promise.all(hruids.map(async (hruid) => learningPathRepo.findByHruidAndLanguage(hruid, language)))).filter( | ||||
|             (learningPath) => learningPath !== null, | ||||
|             (learningPath) => learningPath !== null | ||||
|         ); | ||||
|         const filteredLearningPaths = await Promise.all( | ||||
|             learningPaths.map(async (learningPath, index) => convertLearningPath(learningPath, index, personalizedFor)), | ||||
|             learningPaths.map(async (learningPath, index) => convertLearningPath(learningPath, index, personalizedFor)) | ||||
|         ); | ||||
| 
 | ||||
|         return { | ||||
|  |  | |||
|  | @ -19,7 +19,7 @@ async function addProgressToLearningPath(learningPath: LearningPath, personalize | |||
|         learningPath.nodes.map(async (node) => { | ||||
|             const lastSubmission = personalizedFor ? await getLastSubmissionForGroup(idFromLearningObjectNode(node), personalizedFor) : null; | ||||
|             node.done = Boolean(lastSubmission); | ||||
|         }), | ||||
|         }) | ||||
|     ); | ||||
| 
 | ||||
|     learningPath.num_nodes = learningPath.nodes.length; | ||||
|  |  | |||
|  | @ -1,12 +1,7 @@ | |||
| import dwengoApiLearningPathProvider from './dwengo-api-learning-path-provider.js'; | ||||
| import databaseLearningPathProvider from './database-learning-path-provider.js'; | ||||
| import { envVars, getEnvVar } from '../../util/envVars.js'; | ||||
| import { | ||||
|     LearningObjectNode, | ||||
|     LearningPath, | ||||
|     LearningPathIdentifier, | ||||
|     LearningPathResponse, | ||||
| } from '@dwengo-1/common/interfaces/learning-content'; | ||||
| import { LearningObjectNode, LearningPath, LearningPathIdentifier, LearningPathResponse } from '@dwengo-1/common/interfaces/learning-content'; | ||||
| import { Language } from '@dwengo-1/common/util/language'; | ||||
| import { Group } from '../../entities/assignments/group.entity.js'; | ||||
| import { LearningPath as LearningPathEntity } from '../../entities/content/learning-path.entity.js'; | ||||
|  | @ -46,16 +41,16 @@ export function mapToLearningPath(dto: LearningPath, adminsDto: TeacherDTO[]): L | |||
|             startNode: nodeDto.start_node ?? false, | ||||
|             createdAt: new Date(), | ||||
|             updatedAt: new Date(), | ||||
|         }), | ||||
|         }) | ||||
|     ); | ||||
|     dto.nodes.forEach((nodeDto) => { | ||||
|         const fromNode = nodes.find( | ||||
|             (it) => it.learningObjectHruid === nodeDto.learningobject_hruid && it.language === nodeDto.language && it.version === nodeDto.version, | ||||
|             (it) => it.learningObjectHruid === nodeDto.learningobject_hruid && it.language === nodeDto.language && it.version === nodeDto.version | ||||
|         )!; | ||||
|         const transitions = nodeDto.transitions.map((transDto, i) => { | ||||
|             const toNode = nodes.find( | ||||
|                 (it) => | ||||
|                     it.learningObjectHruid === transDto.next.hruid && it.language === transDto.next.language && it.version === transDto.next.version, | ||||
|                     it.learningObjectHruid === transDto.next.hruid && it.language === transDto.next.language && it.version === transDto.next.version | ||||
|             ); | ||||
| 
 | ||||
|             if (toNode) { | ||||
|  | @ -99,7 +94,7 @@ const learningPathService = { | |||
|             nonUserContentHruids, | ||||
|             language, | ||||
|             source, | ||||
|             personalizedFor, | ||||
|             personalizedFor | ||||
|         ); | ||||
| 
 | ||||
|         const result = (userContentLearningPaths.data || []).concat(nonUserContentLearningPaths.data || []); | ||||
|  | @ -124,7 +119,7 @@ const learningPathService = { | |||
|      */ | ||||
|     async searchLearningPaths(query: string, language: Language, personalizedFor?: Group): Promise<LearningPath[]> { | ||||
|         const providerResponses = await Promise.all( | ||||
|             allProviders.map(async (provider) => provider.searchLearningPaths(query, language, personalizedFor)), | ||||
|             allProviders.map(async (provider) => provider.searchLearningPaths(query, language, personalizedFor)) | ||||
|         ); | ||||
|         return providerResponses.flat(); | ||||
|     }, | ||||
|  |  | |||
|  | @ -151,19 +151,13 @@ describe('DatabaseLearningPathProvider', () => { | |||
|     describe('searchLearningPathsByAdmin', () => { | ||||
|         it('returns the learning path owned by the admin', async () => { | ||||
|             const expectedLearningPath = mapToLearningPath(testLearningPath02, [mapToTeacherDTO(teacherB)]); | ||||
|             const result = await databaseLearningPathProvider.searchLearningPathsByAdmin( | ||||
|                 [teacherB], | ||||
|                 expectedLearningPath.language | ||||
|             ); | ||||
|             const result = await databaseLearningPathProvider.searchLearningPathsByAdmin([teacherB], expectedLearningPath.language); | ||||
|             expect(result.length).toBe(1); | ||||
|             expect(result[0].title).toBe(expectedLearningPath.title); | ||||
|             expect(result[0].description).toBe(expectedLearningPath.description); | ||||
|         }); | ||||
|         it('returns an empty result when querying admins that do not have custom learning paths', async() => { | ||||
|             const result = await databaseLearningPathProvider.searchLearningPathsByAdmin( | ||||
|                 [teacherA], | ||||
|                 testLearningPath.language | ||||
|             ); | ||||
|         it('returns an empty result when querying admins that do not have custom learning paths', async () => { | ||||
|             const result = await databaseLearningPathProvider.searchLearningPathsByAdmin([teacherA], testLearningPath.language); | ||||
|             expect(result.length).toBe(0); | ||||
|         }); | ||||
|     }); | ||||
|  |  | |||
|  | @ -1,19 +1,19 @@ | |||
| <script setup lang="ts"> | ||||
| import type { LearningObject } from '@/data-objects/learning-objects/learning-object'; | ||||
| import type { LearningPath } from '@/data-objects/learning-paths/learning-path'; | ||||
| import { useLearningObjectListForPathQuery } from '@/queries/learning-objects'; | ||||
| import { useRoute } from 'vue-router'; | ||||
| import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||
| import { ref, watchEffect } from 'vue'; | ||||
|     import type { LearningObject } from "@/data-objects/learning-objects/learning-object"; | ||||
|     import type { LearningPath } from "@/data-objects/learning-paths/learning-path"; | ||||
|     import { useLearningObjectListForPathQuery } from "@/queries/learning-objects"; | ||||
|     import { useRoute } from "vue-router"; | ||||
|     import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||
|     import { ref, watchEffect } from "vue"; | ||||
| 
 | ||||
|     const route = useRoute(); | ||||
| 
 | ||||
|     const props = defineProps<{ | ||||
|         path: LearningPath; | ||||
|         activeObjectId: string  | ||||
|         activeObjectId: string; | ||||
|     }>(); | ||||
| 
 | ||||
|     const currentPath = ref(props.path) | ||||
|     const currentPath = ref(props.path); | ||||
| 
 | ||||
|     const learningObjectListQueryResult = useLearningObjectListForPathQuery(currentPath); | ||||
| 
 | ||||
|  | @ -33,21 +33,34 @@ import { ref, watchEffect } from 'vue'; | |||
|     function toggleDropdown(): void { | ||||
|         dropdownEnabled.value = !dropdownEnabled.value; | ||||
|     } | ||||
| 
 | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <main> | ||||
|         <div class="dropdown-toggle" @click="toggleDropdown()">▼{{path.title}}</div> | ||||
|         <div class="dropdown" v-if="dropdownEnabled"> | ||||
|         <div | ||||
|             class="dropdown-toggle" | ||||
|             @click="toggleDropdown()" | ||||
|         > | ||||
|             ▼{{ path.title }} | ||||
|         </div> | ||||
|         <div | ||||
|             class="dropdown" | ||||
|             v-if="dropdownEnabled" | ||||
|         > | ||||
|             <using-query-result | ||||
|                 :query-result="learningObjectListQueryResult" | ||||
|                 v-slot="learningObjects: { data: LearningObject[] }" | ||||
|             > | ||||
|                 <template v-for="node in learningObjects.data" :key="node.key"> | ||||
|                 <template | ||||
|                     v-for="node in learningObjects.data" | ||||
|                     :key="node.key" | ||||
|                 > | ||||
|                     <v-list-item | ||||
|                         link | ||||
|                         :to="{ path: `/discussion-reload/${currentPath.hruid}/${node.language}/${node.key}`, query: route.query }" | ||||
|                         :to="{ | ||||
|                             path: `/discussion-reload/${currentPath.hruid}/${node.language}/${node.key}`, | ||||
|                             query: route.query, | ||||
|                         }" | ||||
|                         :title="node.title" | ||||
|                         :active="node.key === props.activeObjectId" | ||||
|                     > | ||||
|  | @ -59,7 +72,7 @@ import { ref, watchEffect } from 'vue'; | |||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| .dropdown { | ||||
|     .dropdown { | ||||
|         margin-left: 0.5rem; | ||||
|         padding-left: 1rem; | ||||
|         border-left: 2px solid #e0e0e0; | ||||
|  | @ -67,8 +80,8 @@ import { ref, watchEffect } from 'vue'; | |||
|         border-radius: 4px; | ||||
|         padding-top: 0.5rem; | ||||
|         padding-bottom: 0.5rem; | ||||
| } | ||||
| .dropdown-toggle { | ||||
|     } | ||||
|     .dropdown-toggle { | ||||
|         cursor: pointer; | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|  | @ -76,14 +89,14 @@ import { ref, watchEffect } from 'vue'; | |||
|         user-select: none; | ||||
|         padding: 0.5rem; | ||||
|         transition: color 0.2s; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .dropdown-toggle:hover { | ||||
|     .dropdown-toggle:hover { | ||||
|         color: #27c53f; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .dropdown-icon { | ||||
|     .dropdown-icon { | ||||
|         margin-right: 0.5rem; | ||||
|         font-size: 0.9rem; | ||||
| } | ||||
|     } | ||||
| </style> | ||||
|  |  | |||
|  | @ -1,18 +1,16 @@ | |||
| <script setup lang="ts"> | ||||
|     import type { LearningPath } from "@/data-objects/learning-paths/learning-path.ts"; | ||||
|     import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||
|     import DiscussionSideBarElement from "@/components/DiscussionSideBarElement.vue"; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
|     import { useGetAllLearningPaths } from "@/queries/learning-paths.ts"; | ||||
|     import { ref } from "vue"; | ||||
| 
 | ||||
| import type { LearningPath } from '@/data-objects/learning-paths/learning-path.ts'; | ||||
| import UsingQueryResult from '@/components/UsingQueryResult.vue'; | ||||
| import DiscussionSideBarElement from '@/components/DiscussionSideBarElement.vue'; | ||||
| import { useI18n } from 'vue-i18n'; | ||||
| import { useGetAllLearningPaths } from '@/queries/learning-paths.ts'; | ||||
| import { ref } from 'vue'; | ||||
|     const { t, locale } = useI18n(); | ||||
| 
 | ||||
| const { t, locale } = useI18n(); | ||||
| 
 | ||||
| const navigationDrawerShown = ref(true); | ||||
| 
 | ||||
| const allLearningPathsResult = useGetAllLearningPaths(locale.value); | ||||
|     const navigationDrawerShown = ref(true); | ||||
| 
 | ||||
|     const allLearningPathsResult = useGetAllLearningPaths(locale.value); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|  | @ -24,14 +22,15 @@ const allLearningPathsResult = useGetAllLearningPaths(locale.value); | |||
|         <div class="d-flex flex-column h-100"> | ||||
|             <v-list-item> | ||||
|                 <template v-slot:title> | ||||
|                     <div class="title">{{ t('discussions') }}</div> | ||||
|                     <div class="title">{{ t("discussions") }}</div> | ||||
|                 </template> | ||||
|             </v-list-item> | ||||
|             <v-divider></v-divider> | ||||
|             <div> | ||||
|                 <using-query-result | ||||
|                     :query-result="allLearningPathsResult" | ||||
|                     v-slot="learningPaths: {data: LearningPath[]}"> | ||||
|                     v-slot="learningPaths: { data: LearningPath[] }" | ||||
|                 > | ||||
|                     <DiscussionSideBarElement | ||||
|                         v-for="learningPath in learningPaths.data" | ||||
|                         :path="learningPath" | ||||
|  | @ -54,13 +53,11 @@ const allLearningPathsResult = useGetAllLearningPaths(locale.value); | |||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| .title { | ||||
|     .title { | ||||
|         color: #0e6942; | ||||
|         text-transform: uppercase; | ||||
|         font-weight: bolder; | ||||
|         padding-top: 2%; | ||||
|         font-size: 36px; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|     } | ||||
| </style> | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| <script setup lang="ts"> | ||||
|     import type { QuestionDTO } from "@dwengo-1/common/interfaces/question"; | ||||
|     import SingleQuestion from "./SingleQuestion.vue"; | ||||
|     import { useI18n } from 'vue-i18n'; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
| 
 | ||||
|     const { t } = useI18n(); | ||||
| 
 | ||||
|  | @ -21,12 +21,12 @@ | |||
|             </div> | ||||
|         </div> | ||||
|         <div v-else> | ||||
|             <p class="no-questions">{{t("no-questions")}}</p> | ||||
|             <p class="no-questions">{{ t("no-questions") }}</p> | ||||
|         </div> | ||||
|     </div> | ||||
| </template> | ||||
| <style scoped> | ||||
| .no-questions { | ||||
|     .no-questions { | ||||
|         display: flex; | ||||
|         justify-content: center; | ||||
|         align-items: center; | ||||
|  | @ -35,5 +35,5 @@ | |||
|         font-size: 18px; | ||||
|         color: #666; | ||||
|         padding: 0 20px; | ||||
| } | ||||
|     } | ||||
| </style> | ||||
|  |  | |||
|  | @ -1,53 +1,51 @@ | |||
| <script setup lang="ts"> | ||||
|     import authService from "@/services/auth/auth-service.ts"; | ||||
|     import { Language } from "@/data-objects/language.ts"; | ||||
|     import { computed, type ComputedRef, ref } from "vue"; | ||||
|     import type { AssignmentDTO } from "@dwengo-1/common/interfaces/assignment"; | ||||
|     import { useStudentAssignmentsQuery, useStudentGroupsQuery } from "@/queries/students.ts"; | ||||
|     import type { GroupDTO, GroupDTOId } from "@dwengo-1/common/interfaces/group"; | ||||
|     import type { QuestionData } from "@dwengo-1/common/interfaces/question"; | ||||
|     import type { LearningObjectIdentifierDTO } from "@dwengo-1/interfaces/learning-content"; | ||||
|     import { useCreateQuestionMutation, useQuestionsQuery } from "@/queries/questions.ts"; | ||||
|     import { LearningPathNode } from "@/data-objects/learning-paths/learning-path-node.ts"; | ||||
|     import { useGetLearningPathQuery } from "@/queries/learning-paths.ts"; | ||||
|     import { useLearningObjectListForPathQuery } from "@/queries/learning-objects.ts"; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
|     import { AccountType } from "@dwengo-1/common/src/util/account-types.ts"; | ||||
| 
 | ||||
| import authService from '@/services/auth/auth-service.ts'; | ||||
| import { Language } from '@/data-objects/language.ts'; | ||||
| import { computed, type ComputedRef, ref } from 'vue'; | ||||
| import type { AssignmentDTO } from '@dwengo-1/common/interfaces/assignment'; | ||||
| import { useStudentAssignmentsQuery, useStudentGroupsQuery } from '@/queries/students.ts'; | ||||
| import type { GroupDTO, GroupDTOId } from '@dwengo-1/common/interfaces/group'; | ||||
| import type { QuestionData } from '@dwengo-1/common/interfaces/question'; | ||||
| import type { LearningObjectIdentifierDTO } from '@dwengo-1/interfaces/learning-content'; | ||||
| import { useCreateQuestionMutation, useQuestionsQuery } from '@/queries/questions.ts'; | ||||
| import { LearningPathNode } from '@/data-objects/learning-paths/learning-path-node.ts'; | ||||
| import { useGetLearningPathQuery } from '@/queries/learning-paths.ts'; | ||||
| import { useLearningObjectListForPathQuery } from '@/queries/learning-objects.ts'; | ||||
| import { useI18n } from 'vue-i18n'; | ||||
| import { AccountType } from '@dwengo-1/common/src/util/account-types.ts'; | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
|     const props = defineProps<{ | ||||
|         hruid: string; | ||||
|         language: Language; | ||||
|         learningObjectHruid?: string; | ||||
|     forGroup?: GroupDTOId | undefined | ||||
| }>(); | ||||
|         forGroup?: GroupDTOId | undefined; | ||||
|     }>(); | ||||
| 
 | ||||
| const { t } = useI18n(); | ||||
|     const { t } = useI18n(); | ||||
| 
 | ||||
| const studentAssignmentsQueryResult = useStudentAssignmentsQuery( | ||||
|     const studentAssignmentsQueryResult = useStudentAssignmentsQuery( | ||||
|         authService.authState.user?.profile.preferred_username, | ||||
| ); | ||||
| const learningPathQueryResult = useGetLearningPathQuery(props.hruid, props.language, props.forGroup); | ||||
| const learningObjectListQueryResult = useLearningObjectListForPathQuery(learningPathQueryResult.data); | ||||
|     ); | ||||
|     const learningPathQueryResult = useGetLearningPathQuery(props.hruid, props.language, props.forGroup); | ||||
|     const learningObjectListQueryResult = useLearningObjectListForPathQuery(learningPathQueryResult.data); | ||||
| 
 | ||||
| const pathIsAssignment = computed(() => { | ||||
|     const pathIsAssignment = computed(() => { | ||||
|         const assignments = (studentAssignmentsQueryResult.data.value?.assignments as AssignmentDTO[]) || []; | ||||
|         return assignments.some( | ||||
|             (assignment) => assignment.learningPath === props.hruid && assignment.language === props.language, | ||||
|         ); | ||||
| }); | ||||
|     }); | ||||
| 
 | ||||
| const nodesList: ComputedRef<LearningPathNode[] | null> = computed( | ||||
|     const nodesList: ComputedRef<LearningPathNode[] | null> = computed( | ||||
|         () => learningPathQueryResult.data.value?.nodesAsList ?? null, | ||||
| ); | ||||
|     ); | ||||
| 
 | ||||
| 
 | ||||
| const currentNode = computed(() => { | ||||
|     const currentNode = computed(() => { | ||||
|         const currentHruid = props.learningObjectHruid; | ||||
|         return nodesList.value?.find((it) => it.learningobjectHruid === currentHruid); | ||||
| }); | ||||
|     }); | ||||
| 
 | ||||
| const getQuestionsQuery = useQuestionsQuery( | ||||
|     const getQuestionsQuery = useQuestionsQuery( | ||||
|         computed( | ||||
|             () => | ||||
|                 ({ | ||||
|  | @ -56,18 +54,18 @@ const getQuestionsQuery = useQuestionsQuery( | |||
|                     version: currentNode.value?.version, | ||||
|                 }) as LearningObjectIdentifierDTO, | ||||
|         ), | ||||
| ); | ||||
|     ); | ||||
| 
 | ||||
| const questionInput = ref(''); | ||||
|     const questionInput = ref(""); | ||||
| 
 | ||||
| const loID: LearningObjectIdentifierDTO = { | ||||
|     const loID: LearningObjectIdentifierDTO = { | ||||
|         hruid: props.learningObjectHruid as string, | ||||
|         language: props.language, | ||||
| }; | ||||
| const createQuestionMutation = useCreateQuestionMutation(loID); | ||||
| const groupsQueryResult = useStudentGroupsQuery(authService.authState.user?.profile.preferred_username); | ||||
|     }; | ||||
|     const createQuestionMutation = useCreateQuestionMutation(loID); | ||||
|     const groupsQueryResult = useStudentGroupsQuery(authService.authState.user?.profile.preferred_username); | ||||
| 
 | ||||
| function submitQuestion(): void { | ||||
|     function submitQuestion(): void { | ||||
|         const assignments = studentAssignmentsQueryResult.data.value?.assignments as AssignmentDTO[]; | ||||
|         const assignment = assignments.find( | ||||
|             (assignment) => assignment.learningPath === props.hruid && assignment.language === props.language, | ||||
|  | @ -79,10 +77,10 @@ function submitQuestion(): void { | |||
|             content: questionInput.value, | ||||
|             inGroup: group, | ||||
|         }; | ||||
|     if (questionInput.value !== '') { | ||||
|         if (questionInput.value !== "") { | ||||
|             createQuestionMutation.mutate(questionData, { | ||||
|                 onSuccess: async () => { | ||||
|                 questionInput.value = ''; // Clear the input field after submission | ||||
|                     questionInput.value = ""; // Clear the input field after submission | ||||
|                     await getQuestionsQuery.refetch(); // Reload the questions | ||||
|                 }, | ||||
|                 onError: (_) => { | ||||
|  | @ -91,7 +89,7 @@ function submitQuestion(): void { | |||
|                 }, | ||||
|             }); | ||||
|         } | ||||
| } | ||||
|     } | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|  | @ -114,48 +112,47 @@ function submitQuestion(): void { | |||
|             </button> | ||||
|         </div> | ||||
|     </div> | ||||
| 
 | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| .question-box { | ||||
|     .question-box { | ||||
|         width: 100%; | ||||
|         max-width: 400px; | ||||
|         margin: 20px auto; | ||||
|         font-family: sans-serif; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .input-wrapper { | ||||
|     .input-wrapper { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         border: 1px solid #ccc; | ||||
|         border-radius: 999px; | ||||
|         padding: 8px 12px; | ||||
|         box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .question-input { | ||||
|     .question-input { | ||||
|         flex: 1; | ||||
|         border: none; | ||||
|         outline: none; | ||||
|         font-size: 14px; | ||||
|         background-color: transparent; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .question-input::placeholder { | ||||
|     .question-input::placeholder { | ||||
|         color: #999; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .send-button { | ||||
|     .send-button { | ||||
|         background: none; | ||||
|         border: none; | ||||
|         cursor: pointer; | ||||
|         font-size: 16px; | ||||
|         color: #555; | ||||
|         transition: color 0.2s ease; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .send-button:hover { | ||||
|     .send-button:hover { | ||||
|         color: #000; | ||||
| } | ||||
|     } | ||||
| </style> | ||||
|  |  | |||
|  | @ -8,7 +8,6 @@ | |||
|     import authService from "@/services/auth/auth-service"; | ||||
|     import { useI18n } from "vue-i18n"; | ||||
| 
 | ||||
| 
 | ||||
|     const { t } = useI18n(); | ||||
| 
 | ||||
|     const props = defineProps<{ | ||||
|  | @ -135,7 +134,7 @@ | |||
|                     :key="answerIndex" | ||||
|                     class="text-gray-600" | ||||
|                 > | ||||
|                     <v-divider :thickness=2 /> | ||||
|                     <v-divider :thickness="2" /> | ||||
|                     <div | ||||
|                         class="flex justify-between items-center mb-2" | ||||
|                         style=" | ||||
|  |  | |||
|  | @ -1,23 +1,23 @@ | |||
| import { createRouter, createWebHistory } from 'vue-router'; | ||||
| import SingleAssignment from '@/views/assignments/SingleAssignment.vue'; | ||||
| import SingleClass from '@/views/classes/SingleClass.vue'; | ||||
| import SingleDiscussion from '@/views/discussions/SingleDiscussion.vue'; | ||||
| import NotFound from '@/components/errors/NotFound.vue'; | ||||
| import CreateAssignment from '@/views/assignments/CreateAssignment.vue'; | ||||
| import CreateDiscussion from '@/views/discussions/CreateDiscussion.vue'; | ||||
| import CallbackPage from '@/views/CallbackPage.vue'; | ||||
| import UserClasses from '@/views/classes/UserClasses.vue'; | ||||
| import UserAssignments from '@/views/assignments/UserAssignments.vue'; | ||||
| import LearningPathPage from '@/views/learning-paths/LearningPathPage.vue'; | ||||
| import LearningPathSearchPage from '@/views/learning-paths/LearningPathSearchPage.vue'; | ||||
| import UserHomePage from '@/views/homepage/UserHomePage.vue'; | ||||
| import SingleTheme from '@/views/SingleTheme.vue'; | ||||
| import LearningObjectView from '@/views/learning-paths/learning-object/LearningObjectView.vue'; | ||||
| import authService from '@/services/auth/auth-service'; | ||||
| import DiscussionForward from '@/views/discussions/DiscussionForward.vue'; | ||||
| import NoDiscussion from '@/views/discussions/NoDiscussion.vue'; | ||||
| import OwnLearningContentPage from '@/views/own-learning-content/OwnLearningContentPage.vue'; | ||||
| import { allowRedirect, Redirect } from '@/utils/redirect.ts'; | ||||
| import { createRouter, createWebHistory } from "vue-router"; | ||||
| import SingleAssignment from "@/views/assignments/SingleAssignment.vue"; | ||||
| import SingleClass from "@/views/classes/SingleClass.vue"; | ||||
| import SingleDiscussion from "@/views/discussions/SingleDiscussion.vue"; | ||||
| import NotFound from "@/components/errors/NotFound.vue"; | ||||
| import CreateAssignment from "@/views/assignments/CreateAssignment.vue"; | ||||
| import CreateDiscussion from "@/views/discussions/CreateDiscussion.vue"; | ||||
| import CallbackPage from "@/views/CallbackPage.vue"; | ||||
| import UserClasses from "@/views/classes/UserClasses.vue"; | ||||
| import UserAssignments from "@/views/assignments/UserAssignments.vue"; | ||||
| import LearningPathPage from "@/views/learning-paths/LearningPathPage.vue"; | ||||
| import LearningPathSearchPage from "@/views/learning-paths/LearningPathSearchPage.vue"; | ||||
| import UserHomePage from "@/views/homepage/UserHomePage.vue"; | ||||
| import SingleTheme from "@/views/SingleTheme.vue"; | ||||
| import LearningObjectView from "@/views/learning-paths/learning-object/LearningObjectView.vue"; | ||||
| import authService from "@/services/auth/auth-service"; | ||||
| import DiscussionForward from "@/views/discussions/DiscussionForward.vue"; | ||||
| import NoDiscussion from "@/views/discussions/NoDiscussion.vue"; | ||||
| import OwnLearningContentPage from "@/views/own-learning-content/OwnLearningContentPage.vue"; | ||||
| import { allowRedirect, Redirect } from "@/utils/redirect.ts"; | ||||
| 
 | ||||
| const router = createRouter({ | ||||
|     history: createWebHistory(import.meta.env.BASE_URL), | ||||
|  |  | |||
|  | @ -1,26 +1,21 @@ | |||
| <script setup lang="ts"> | ||||
| import type { Language } from '@/data-objects/language'; | ||||
| import { onMounted } from 'vue'; | ||||
| import { useRouter } from 'vue-router'; | ||||
|     import type { Language } from "@/data-objects/language"; | ||||
|     import { onMounted } from "vue"; | ||||
|     import { useRouter } from "vue-router"; | ||||
| 
 | ||||
| const router = useRouter(); | ||||
|     const router = useRouter(); | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
|     const props = defineProps<{ | ||||
|         hruid: string; | ||||
|         language: Language; | ||||
|         learningObjectHruid?: string; | ||||
| }>(); | ||||
|     }>(); | ||||
| 
 | ||||
| const discussionURL = "/discussion"  | ||||
|     + "/" + props.hruid | ||||
|     + "/" + props.language | ||||
|     + "/" + props.learningObjectHruid | ||||
|     const discussionURL = "/discussion" + "/" + props.hruid + "/" + props.language + "/" + props.learningObjectHruid; | ||||
| 
 | ||||
| 
 | ||||
| onMounted(async () => { | ||||
|     onMounted(async () => { | ||||
|         await router.replace(discussionURL); | ||||
| }) | ||||
| 
 | ||||
|     }); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|  |  | |||
|  | @ -1,15 +1,14 @@ | |||
| <script setup lang="ts"> | ||||
| import { useI18n } from 'vue-i18n'; | ||||
| import DiscussionsSideBar from '@/components/DiscussionsSideBar.vue'; | ||||
| 
 | ||||
| const { t } = useI18n(); | ||||
|     import { useI18n } from "vue-i18n"; | ||||
|     import DiscussionsSideBar from "@/components/DiscussionsSideBar.vue"; | ||||
| 
 | ||||
|     const { t } = useI18n(); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <DiscussionsSideBar></DiscussionsSideBar> | ||||
|     <div> | ||||
|         <p class="no-discussion-tip">{{t("no-discussion-tip")}}</p> | ||||
|         <p class="no-discussion-tip">{{ t("no-discussion-tip") }}</p> | ||||
|     </div> | ||||
| </template> | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,38 +1,38 @@ | |||
| <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, watch } from 'vue'; | ||||
| import type { LearningObject } from '@/data-objects/learning-objects/learning-object.ts'; | ||||
| import { useRoute } from 'vue-router'; | ||||
| import { useGetAllLearningPaths, useGetLearningPathQuery } from '@/queries/learning-paths.ts'; | ||||
| import { useLearningObjectListForPathQuery } from '@/queries/learning-objects.ts'; | ||||
| import UsingQueryResult from '@/components/UsingQueryResult.vue'; | ||||
| import { LearningPathNode } from '@/data-objects/learning-paths/learning-path-node.ts'; | ||||
| import { useQuestionsQuery } from '@/queries/questions'; | ||||
| import type { QuestionsResponse } from '@/controllers/questions'; | ||||
| import type { LearningObjectIdentifierDTO } from '@dwengo-1/common/interfaces/learning-content'; | ||||
| import QandA from '@/components/QandA.vue'; | ||||
| import type { QuestionDTO } from '@dwengo-1/common/interfaces/question'; | ||||
| import DiscussionsSideBar from '@/components/DiscussionsSideBar.vue'; | ||||
| import QuestionBox from '@/components/QuestionBox.vue'; | ||||
|     import { Language } from "@/data-objects/language.ts"; | ||||
|     import type { LearningPath } from "@/data-objects/learning-paths/learning-path.ts"; | ||||
|     import { computed, type ComputedRef, ref, watch } from "vue"; | ||||
|     import type { LearningObject } from "@/data-objects/learning-objects/learning-object.ts"; | ||||
|     import { useRoute } from "vue-router"; | ||||
|     import { useGetAllLearningPaths, useGetLearningPathQuery } from "@/queries/learning-paths.ts"; | ||||
|     import { useLearningObjectListForPathQuery } from "@/queries/learning-objects.ts"; | ||||
|     import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||
|     import { LearningPathNode } from "@/data-objects/learning-paths/learning-path-node.ts"; | ||||
|     import { useQuestionsQuery } from "@/queries/questions"; | ||||
|     import type { QuestionsResponse } from "@/controllers/questions"; | ||||
|     import type { LearningObjectIdentifierDTO } from "@dwengo-1/common/interfaces/learning-content"; | ||||
|     import QandA from "@/components/QandA.vue"; | ||||
|     import type { QuestionDTO } from "@dwengo-1/common/interfaces/question"; | ||||
|     import DiscussionsSideBar from "@/components/DiscussionsSideBar.vue"; | ||||
|     import QuestionBox from "@/components/QuestionBox.vue"; | ||||
| 
 | ||||
| const route = useRoute(); | ||||
|     const route = useRoute(); | ||||
| 
 | ||||
| const props = defineProps<{ | ||||
|     const props = defineProps<{ | ||||
|         hruid: string; | ||||
|         language: Language; | ||||
|         learningObjectHruid?: string; | ||||
| }>(); | ||||
|     }>(); | ||||
| 
 | ||||
| interface LearningPathPageQuery { | ||||
|     interface LearningPathPageQuery { | ||||
|         forGroup?: string; | ||||
|         assignmentNo?: string; | ||||
|         classId?: string; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| const query = computed(() => route.query as LearningPathPageQuery); | ||||
|     const query = computed(() => route.query as LearningPathPageQuery); | ||||
| 
 | ||||
| const forGroup = computed(() => { | ||||
|     const forGroup = computed(() => { | ||||
|         if (query.value.forGroup && query.value.assignmentNo && query.value.classId) { | ||||
|             return { | ||||
|                 forGroup: parseInt(query.value.forGroup), | ||||
|  | @ -41,11 +41,11 @@ const forGroup = computed(() => { | |||
|             }; | ||||
|         } | ||||
|         return undefined; | ||||
| }); | ||||
|     }); | ||||
| 
 | ||||
| const allLearningPathsResult = useGetAllLearningPaths(props.language); | ||||
|     const allLearningPathsResult = useGetAllLearningPaths(props.language); | ||||
| 
 | ||||
| async function learningObjectHasQuestions(learningObject: LearningObject): Promise<boolean> { | ||||
|     async function learningObjectHasQuestions(learningObject: LearningObject): Promise<boolean> { | ||||
|         const loid = { | ||||
|             hruid: learningObject.key, | ||||
|             version: learningObject.version, | ||||
|  | @ -53,21 +53,25 @@ async function learningObjectHasQuestions(learningObject: LearningObject): Promi | |||
|         } as LearningObjectIdentifierDTO; | ||||
|         const { data } = useQuestionsQuery(loid); | ||||
|         return (data.value?.questions.length ?? 0) > 0; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| async function learningPathHasQuestions(learningPath: LearningPath): Promise<boolean> { | ||||
|     const learningPathQueryResult = useGetLearningPathQuery(learningPath.hruid, learningPath.language as Language, forGroup); | ||||
|     async function learningPathHasQuestions(learningPath: LearningPath): Promise<boolean> { | ||||
|         const learningPathQueryResult = useGetLearningPathQuery( | ||||
|             learningPath.hruid, | ||||
|             learningPath.language as Language, | ||||
|             forGroup, | ||||
|         ); | ||||
|         const learningObjectListQueryResult = useLearningObjectListForPathQuery(learningPathQueryResult.data); | ||||
|         const learningObjects = learningObjectListQueryResult.data.value || []; | ||||
|         const hasQuestions = await Promise.all( | ||||
|             learningObjects.map(async (learningObject) => learningObjectHasQuestions(learningObject)), | ||||
|         ); | ||||
|         return hasQuestions.some((hasQuestion) => hasQuestion); | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| const questionedLearningPaths = ref<LearningPath[] | null>(null); | ||||
|     const questionedLearningPaths = ref<LearningPath[] | null>(null); | ||||
| 
 | ||||
| watch( | ||||
|     watch( | ||||
|         () => allLearningPathsResult.data.value, | ||||
|         async (learningPaths) => { | ||||
|             if (learningPaths) { | ||||
|  | @ -81,20 +85,20 @@ watch( | |||
|             } | ||||
|         }, | ||||
|         { immediate: true }, | ||||
| ); | ||||
|     ); | ||||
| 
 | ||||
| const learningPathQueryResult = useGetLearningPathQuery(props.hruid, props.language, forGroup); | ||||
|     const learningPathQueryResult = useGetLearningPathQuery(props.hruid, props.language, forGroup); | ||||
| 
 | ||||
| const nodesList: ComputedRef<LearningPathNode[] | null> = computed( | ||||
|     const nodesList: ComputedRef<LearningPathNode[] | null> = computed( | ||||
|         () => learningPathQueryResult.data.value?.nodesAsList ?? null, | ||||
| ); | ||||
|     ); | ||||
| 
 | ||||
| const currentNode = computed(() => { | ||||
|     const currentNode = computed(() => { | ||||
|         const currentHruid = props.learningObjectHruid; | ||||
|         return nodesList.value?.find((it) => it.learningobjectHruid === currentHruid); | ||||
| }); | ||||
|     }); | ||||
| 
 | ||||
| const getQuestionsQuery = useQuestionsQuery( | ||||
|     const getQuestionsQuery = useQuestionsQuery( | ||||
|         computed( | ||||
|             () => | ||||
|                 ({ | ||||
|  | @ -103,25 +107,24 @@ const getQuestionsQuery = useQuestionsQuery( | |||
|                     version: currentNode.value?.version, | ||||
|                 }) as LearningObjectIdentifierDTO, | ||||
|         ), | ||||
| ); | ||||
|     ); | ||||
| 
 | ||||
| watch( | ||||
|     watch( | ||||
|         () => [route.params.hruid, route.params.language, route.params.learningObjectHruid], | ||||
|         () => { | ||||
|             //TODO: moet op een of andere manier createQuestionMutation opnieuw kunnen instellen | ||||
|             //      Momenteel opgelost door de DiscussionsForward page workaround | ||||
|         }, | ||||
| ); | ||||
| 
 | ||||
|     ); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <DiscussionsSideBar></DiscussionsSideBar> | ||||
|     <QuestionBox | ||||
|         :hruid=props.hruid | ||||
|         :language=props.language | ||||
|         :learningObjectHruid=props.learningObjectHruid | ||||
|         :forGroup=forGroup | ||||
|         :hruid="props.hruid" | ||||
|         :language="props.language" | ||||
|         :learningObjectHruid="props.learningObjectHruid" | ||||
|         :forGroup="forGroup" | ||||
|     /> | ||||
|     <using-query-result | ||||
|         :query-result="getQuestionsQuery" | ||||
|  | @ -132,35 +135,35 @@ watch( | |||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| .learning-path-title { | ||||
|     .learning-path-title { | ||||
|         white-space: normal; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .search-field-container { | ||||
|     .search-field-container { | ||||
|         min-width: 250px; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .control-bar-above-content { | ||||
|     .control-bar-above-content { | ||||
|         margin-left: 5px; | ||||
|         margin-right: 5px; | ||||
|         margin-bottom: -30px; | ||||
|         display: flex; | ||||
|         justify-content: space-between; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .learning-object-view-container { | ||||
|     .learning-object-view-container { | ||||
|         padding-left: 20px; | ||||
|         padding-right: 20px; | ||||
|         padding-bottom: 20px; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .navigation-buttons-container { | ||||
|     .navigation-buttons-container { | ||||
|         padding: 20px; | ||||
|         display: flex; | ||||
|         justify-content: space-between; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .assignment-indicator { | ||||
|     .assignment-indicator { | ||||
|         position: absolute; | ||||
|         bottom: 10px; | ||||
|         left: 10px; | ||||
|  | @ -174,55 +177,55 @@ watch( | |||
|         font-size: 14px; | ||||
|         text-transform: uppercase; | ||||
|         z-index: 2; /* Less than modals/popups */ | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .question-box { | ||||
|     .question-box { | ||||
|         width: 100%; | ||||
|         max-width: 400px; | ||||
|         margin: 20px auto; | ||||
|         font-family: sans-serif; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .input-wrapper { | ||||
|     .input-wrapper { | ||||
|         display: flex; | ||||
|         align-items: center; | ||||
|         border: 1px solid #ccc; | ||||
|         border-radius: 999px; | ||||
|         padding: 8px 12px; | ||||
|         box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .question-input { | ||||
|     .question-input { | ||||
|         flex: 1; | ||||
|         border: none; | ||||
|         outline: none; | ||||
|         font-size: 14px; | ||||
|         background-color: transparent; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .question-input::placeholder { | ||||
|     .question-input::placeholder { | ||||
|         color: #999; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .send-button { | ||||
|     .send-button { | ||||
|         background: none; | ||||
|         border: none; | ||||
|         cursor: pointer; | ||||
|         font-size: 16px; | ||||
|         color: #555; | ||||
|         transition: color 0.2s ease; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .send-button:hover { | ||||
|     .send-button:hover { | ||||
|         color: #000; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .discussion-link a { | ||||
|     .discussion-link a { | ||||
|         color: #3b82f6; /* blue */ | ||||
|         text-decoration: none; | ||||
| } | ||||
|     } | ||||
| 
 | ||||
| .discussion-link a:hover { | ||||
|     .discussion-link a:hover { | ||||
|         text-decoration: underline; | ||||
| } | ||||
|     } | ||||
| </style> | ||||
|  |  | |||
|  | @ -1,30 +1,30 @@ | |||
| <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, useRouter } from 'vue-router'; | ||||
| import LearningObjectView from '@/views/learning-paths/learning-object/LearningObjectView.vue'; | ||||
| 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 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 LearningPathGroupSelector from '@/views/learning-paths/LearningPathGroupSelector.vue'; | ||||
| import { useQuestionsQuery } from '@/queries/questions'; | ||||
| import type { QuestionsResponse } from '@/controllers/questions'; | ||||
| import type { LearningObjectIdentifierDTO } from '@dwengo-1/common/interfaces/learning-content'; | ||||
| import QandA from '@/components/QandA.vue'; | ||||
| import type { QuestionDTO } from '@dwengo-1/common/interfaces/question'; | ||||
| import { useStudentAssignmentsQuery } from '@/queries/students'; | ||||
| import type { AssignmentDTO } from '@dwengo-1/common/interfaces/assignment'; | ||||
| import QuestionNotification from '@/components/QuestionNotification.vue'; | ||||
| import QuestionBox from '@/components/QuestionBox.vue'; | ||||
|     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, useRouter } from "vue-router"; | ||||
|     import LearningObjectView from "@/views/learning-paths/learning-object/LearningObjectView.vue"; | ||||
|     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 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 LearningPathGroupSelector from "@/views/learning-paths/LearningPathGroupSelector.vue"; | ||||
|     import { useQuestionsQuery } from "@/queries/questions"; | ||||
|     import type { QuestionsResponse } from "@/controllers/questions"; | ||||
|     import type { LearningObjectIdentifierDTO } from "@dwengo-1/common/interfaces/learning-content"; | ||||
|     import QandA from "@/components/QandA.vue"; | ||||
|     import type { QuestionDTO } from "@dwengo-1/common/interfaces/question"; | ||||
|     import { useStudentAssignmentsQuery } from "@/queries/students"; | ||||
|     import type { AssignmentDTO } from "@dwengo-1/common/interfaces/assignment"; | ||||
|     import QuestionNotification from "@/components/QuestionNotification.vue"; | ||||
|     import QuestionBox from "@/components/QuestionBox.vue"; | ||||
|     import { AccountType } from "@dwengo-1/common/util/account-types"; | ||||
| 
 | ||||
| const router = useRouter(); | ||||
|     const router = useRouter(); | ||||
|     const route = useRoute(); | ||||
|     const { t } = useI18n(); | ||||
| 
 | ||||
|  | @ -157,12 +157,16 @@ const router = useRouter(); | |||
|         ); | ||||
|     }); | ||||
| 
 | ||||
|     const discussionLink = computed(() => | ||||
|         "/discussion" | ||||
|         + "/" + props.hruid | ||||
|         + "/" + currentNode.value?.language | ||||
|         + "/" + currentNode.value?.learningobjectHruid); | ||||
| 
 | ||||
|     const discussionLink = computed( | ||||
|         () => | ||||
|             "/discussion" + | ||||
|             "/" + | ||||
|             props.hruid + | ||||
|             "/" + | ||||
|             currentNode.value?.language + | ||||
|             "/" + | ||||
|             currentNode.value?.learningobjectHruid, | ||||
|     ); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|  | @ -302,10 +306,10 @@ const router = useRouter(); | |||
|             ></learning-object-view> | ||||
|         </div> | ||||
|         <QuestionBox | ||||
|             :hruid=props.hruid | ||||
|             :language=props.language | ||||
|             :learningObjectHruid=props.learningObjectHruid | ||||
|             :forGroup=forGroup | ||||
|             :hruid="props.hruid" | ||||
|             :language="props.language" | ||||
|             :learningObjectHruid="props.learningObjectHruid" | ||||
|             :forGroup="forGroup" | ||||
|         /> | ||||
|         <div class="navigation-buttons-container"> | ||||
|             <v-btn | ||||
|  | @ -331,13 +335,11 @@ const router = useRouter(); | |||
|         > | ||||
|             <v-divider :thickness="6"></v-divider> | ||||
|             <div class="question-header"> | ||||
|                 <span class="question-title">{{t("questions")}}</span> | ||||
|                 <span class="question-title">{{ t("questions") }}</span> | ||||
|                 <span class="discussion-link-text"> | ||||
|                     {{t("view-questions")}} | ||||
|                     <router-link | ||||
|                         :to=discussionLink | ||||
|                     > | ||||
|                         {{t("discussions")}} | ||||
|                     {{ t("view-questions") }} | ||||
|                     <router-link :to="discussionLink"> | ||||
|                         {{ t("discussions") }} | ||||
|                     </router-link> | ||||
|                 </span> | ||||
|             </div> | ||||
|  |  | |||
		Reference in a new issue
	
	 Lint Action
						Lint Action