feat: assignment description en lp editen is mogelijk
This commit is contained in:
		
							parent
							
								
									f83d5b54c0
								
							
						
					
					
						commit
						cc31effd61
					
				
					 4 changed files with 353 additions and 290 deletions
				
			
		
							
								
								
									
										47
									
								
								frontend/src/components/GroupProgressRow.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								frontend/src/components/GroupProgressRow.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | ||||||
|  | <script setup lang="ts"> | ||||||
|  | import { useGetLearningPathQuery } from "@/queries/learning-paths.ts"; | ||||||
|  | import { computed } from "vue"; | ||||||
|  | import type { Language } from "@/data-objects/language.ts"; | ||||||
|  | import { calculateProgress } from "@/utils/assignment-utils.ts"; | ||||||
|  | 
 | ||||||
|  | const props = defineProps<{ | ||||||
|  |     groupNumber: number; | ||||||
|  |     learningPath: string; | ||||||
|  |     language: Language; | ||||||
|  |     assignmentId: number; | ||||||
|  |     classId: string; | ||||||
|  | }>(); | ||||||
|  | 
 | ||||||
|  | const query = useGetLearningPathQuery( | ||||||
|  |     () => props.learningPath, | ||||||
|  |     () => props.language, | ||||||
|  |     () => ({ | ||||||
|  |         forGroup: props.groupNumber, | ||||||
|  |         assignmentNo: props.assignmentId, | ||||||
|  |         classId: props.classId, | ||||||
|  |     }), | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | const progress = computed(() => { | ||||||
|  |     if (!query.data.value) return 0; | ||||||
|  |     return calculateProgress(query.data.value); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const progressColor = computed(() => { | ||||||
|  |     if (progress.value < 50) return "error"; | ||||||
|  |     if (progress.value < 80) return "warning"; | ||||||
|  |     return "success"; | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |     <v-progress-linear | ||||||
|  |         :model-value="progress" | ||||||
|  |         :color="progressColor" | ||||||
|  |         height="25" | ||||||
|  |     > | ||||||
|  |         <template v-slot:default="{ value }"> | ||||||
|  |             <strong>{{ Math.ceil(value) }}%</strong> | ||||||
|  |         </template> | ||||||
|  |     </v-progress-linear> | ||||||
|  | </template> | ||||||
							
								
								
									
										37
									
								
								frontend/src/components/GroupSubmissionStatus.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								frontend/src/components/GroupSubmissionStatus.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,37 @@ | ||||||
|  | <script setup lang="ts"> | ||||||
|  | import { useI18n } from "vue-i18n"; | ||||||
|  | import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||||
|  | import { useAssignmentSubmissionsQuery } from "@/queries/assignments.ts"; | ||||||
|  | import type { SubmissionsResponse } from "@/controllers/submissions.ts"; | ||||||
|  | 
 | ||||||
|  | const props = defineProps<{ | ||||||
|  |     group: object; | ||||||
|  |     assignmentId: number; | ||||||
|  |     classId: string; | ||||||
|  |     goToGroupSubmissionLink: (groupNo: number) => void; | ||||||
|  | }>(); | ||||||
|  | 
 | ||||||
|  | const { t } = useI18n(); | ||||||
|  | const submissionsQuery = useAssignmentSubmissionsQuery( | ||||||
|  |     () => props.classId, | ||||||
|  |     () => props.assignmentId, | ||||||
|  |     () => props.group.originalGroupNo, | ||||||
|  |     () => true, | ||||||
|  | ); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |     <using-query-result | ||||||
|  |         :query-result="submissionsQuery" | ||||||
|  |         v-slot="{ data }: { data: SubmissionsResponse }" | ||||||
|  |     > | ||||||
|  |         <v-btn | ||||||
|  |             :color="data.submissions.length > 0 ? 'green' : 'red'" | ||||||
|  |             variant="text" | ||||||
|  |             :to="data.submissions.length > 0 ? goToGroupSubmissionLink(props.group.groupNo) : undefined" | ||||||
|  |             :disabled="data.submissions.length === 0" | ||||||
|  |         > | ||||||
|  |             {{ data.submissions.length > 0 ? t("submission") : t("noSubmissionsYet") }} | ||||||
|  |         </v-btn> | ||||||
|  |     </using-query-result> | ||||||
|  | </template> | ||||||
|  | @ -181,7 +181,7 @@ export function useAssignmentSubmissionsQuery( | ||||||
| 
 | 
 | ||||||
|     return useQuery({ |     return useQuery({ | ||||||
|         queryKey: computed(() => assignmentSubmissionsQueryKey(cid!, an!, f)), |         queryKey: computed(() => assignmentSubmissionsQueryKey(cid!, an!, f)), | ||||||
|         queryFn: async () => new AssignmentController(cid!).getSubmissions(gn!, f), |         queryFn: async () => new AssignmentController(cid!).getSubmissions(an!, f), | ||||||
|         enabled: () => checkEnabled(cid, an, gn), |         enabled: () => checkEnabled(cid, an, gn), | ||||||
|     }); |     }); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,15 +1,23 @@ | ||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
|     import { computed, type Ref, ref } from "vue"; | import {computed, type Ref, ref, watch, watchEffect} from "vue"; | ||||||
| import {useI18n} from "vue-i18n"; | import {useI18n} from "vue-i18n"; | ||||||
|     import { useAssignmentQuery, useDeleteAssignmentMutation } from "@/queries/assignments.ts"; | import { | ||||||
|  |     useAssignmentQuery, | ||||||
|  |     useDeleteAssignmentMutation, | ||||||
|  |     useUpdateAssignmentMutation | ||||||
|  | } from "@/queries/assignments.ts"; | ||||||
| import UsingQueryResult from "@/components/UsingQueryResult.vue"; | import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||||
| import {useGroupsQuery} from "@/queries/groups.ts"; | import {useGroupsQuery} from "@/queries/groups.ts"; | ||||||
| import {useGetAllLearningPaths, useGetLearningPathQuery} from "@/queries/learning-paths.ts"; | import {useGetAllLearningPaths, useGetLearningPathQuery} from "@/queries/learning-paths.ts"; | ||||||
| import type {Language} from "@/data-objects/language.ts"; | import type {Language} from "@/data-objects/language.ts"; | ||||||
| import type {AssignmentResponse} from "@/controllers/assignments.ts"; | import type {AssignmentResponse} from "@/controllers/assignments.ts"; | ||||||
|     import type { GroupDTO } from "@dwengo-1/common/interfaces/group"; | import type {GroupDTO, GroupDTOId} from "@dwengo-1/common/interfaces/group"; | ||||||
|     import type { StudentDTO } from "@dwengo-1/common/interfaces/student"; |  | ||||||
| import type {LearningPath} from "@/data-objects/learning-paths/learning-path"; | import type {LearningPath} from "@/data-objects/learning-paths/learning-path"; | ||||||
|  | import {descriptionRules, learningPathRules} from "@/utils/assignment-rules.ts"; | ||||||
|  | import GroupSubmissionStatus from "@/components/GroupSubmissionStatus.vue" | ||||||
|  | import GroupProgressRow from "@/components/GroupProgressRow.vue" | ||||||
|  | import type {AssignmentDTO} from "@dwengo-1/common/dist/interfaces/assignment.ts"; | ||||||
|  | import router from "@/router"; | ||||||
| 
 | 
 | ||||||
| const props = defineProps<{ | const props = defineProps<{ | ||||||
|     classId: string; |     classId: string; | ||||||
|  | @ -23,53 +31,45 @@ | ||||||
| 
 | 
 | ||||||
| const isEditing = ref(false); | const isEditing = ref(false); | ||||||
| 
 | 
 | ||||||
|     const { t, locale } = useI18n(); | const {t} = useI18n(); | ||||||
|     const language = computed(() => locale.value); | const lang = ref(); | ||||||
|     const groups = ref(); | const groups = ref<GroupDTO[] | GroupDTOId[]>([]); | ||||||
| const learningPath = ref(); | const learningPath = ref(); | ||||||
|  | 
 | ||||||
| const editingLearningPath = ref(learningPath); | const editingLearningPath = ref(learningPath); | ||||||
| const description = ref(""); | const description = ref(""); | ||||||
| 
 | 
 | ||||||
|     const assignmentQueryResult = useAssignmentQuery(props.classId, props.assignmentId); |  | ||||||
|     learningPath.value = assignmentQueryResult.data.value?.assignment?.learningPath; |  | ||||||
|     const learningPathsQueryResults = useGetAllLearningPaths(language); |  | ||||||
| 
 | 
 | ||||||
|  | const assignmentQueryResult = useAssignmentQuery(() => props.classId, props.assignmentId); | ||||||
| // Get learning path object | // Get learning path object | ||||||
| const lpQueryResult = useGetLearningPathQuery( | const lpQueryResult = useGetLearningPathQuery( | ||||||
|     computed(() => assignmentQueryResult.data.value?.assignment?.learningPath ?? ""), |     computed(() => assignmentQueryResult.data.value?.assignment?.learningPath ?? ""), | ||||||
|         computed(() => language.value as Language), |     computed(() => assignmentQueryResult.data.value?.assignment?.language as Language), | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
|     const learningPathRules = [ |  | ||||||
|         (value: { hruid: string; title: string }): string | boolean => { |  | ||||||
|             if (value && value.hruid) { |  | ||||||
|                 return true; // Valid if hruid is present |  | ||||||
|             } |  | ||||||
|             return "You must select a learning path."; |  | ||||||
|         }, |  | ||||||
|     ]; |  | ||||||
| 
 |  | ||||||
| // Get all the groups withing the assignment | // Get all the groups withing the assignment | ||||||
| const groupsQueryResult = useGroupsQuery(props.classId, props.assignmentId, true); | const groupsQueryResult = useGroupsQuery(props.classId, props.assignmentId, true); | ||||||
|     groups.value = groupsQueryResult.data.value?.groups; | groups.value = groupsQueryResult.data.value?.groups ?? []; | ||||||
| 
 | 
 | ||||||
|     /* Crashes right now cause api data has inexistent hruid TODO: uncomment later and use it in progress bar | watchEffect(() => { | ||||||
| Const {groupProgressMap} = props.useGroupsWithProgress( |     learningPath.value = assignmentQueryResult.data.value?.assignment?.learningPath; | ||||||
|     groups, |     lang.value = assignmentQueryResult.data.value?.assignment?.language as Language; | ||||||
|     learningPath, | }); | ||||||
|     language |  | ||||||
| ); |  | ||||||
| */ |  | ||||||
| 
 | 
 | ||||||
| const allGroups = computed(() => { | const allGroups = computed(() => { | ||||||
|     const groups = groupsQueryResult.data.value?.groups; |     const groups = groupsQueryResult.data.value?.groups; | ||||||
|  | 
 | ||||||
|     if (!groups) return []; |     if (!groups) return []; | ||||||
| 
 | 
 | ||||||
|         return groups.map((group) => ({ |     // Sort by original groupNumber | ||||||
|             name: `${t("group")} ${group.groupNumber}`, |     const sortedGroups = [...groups].sort((a, b) => a.groupNumber - b.groupNumber); | ||||||
|             progress: 0, //GroupProgressMap[group.groupNumber], | 
 | ||||||
|  |     // Assign new sequential numbers starting from 1 | ||||||
|  |     return sortedGroups.map((group, index) => ({ | ||||||
|  |         groupNo: index + 1, // New group number that will be used | ||||||
|  |         name: `${t("group")} ${index + 1}`, | ||||||
|         members: group.members, |         members: group.members, | ||||||
|             submitted: false, //TODO: fetch from submission |         originalGroupNo: group.groupNumber, // Keep original number if needed | ||||||
|     })); |     })); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | @ -81,15 +81,8 @@ Const {groupProgressMap} = props.useGroupsWithProgress( | ||||||
|     dialog.value = true; |     dialog.value = true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|     const headers = computed(() => [ |  | ||||||
|         { title: t("group"), align: "start", key: "name" }, |  | ||||||
|         { title: t("progress"), align: "center", key: "progress" }, |  | ||||||
|         { title: t("submission"), align: "center", key: "submission" }, |  | ||||||
|     ]); |  | ||||||
| 
 |  | ||||||
|     const { mutate } = useDeleteAssignmentMutation(); |  | ||||||
| 
 |  | ||||||
| async function deleteAssignment(num: number, clsId: string): Promise<void> { | async function deleteAssignment(num: number, clsId: string): Promise<void> { | ||||||
|  |     const {mutate} = useDeleteAssignmentMutation(); | ||||||
|     mutate( |     mutate( | ||||||
|         {cid: clsId, an: num}, |         {cid: clsId, an: num}, | ||||||
|         { |         { | ||||||
|  | @ -100,11 +93,47 @@ Const {groupProgressMap} = props.useGroupsWithProgress( | ||||||
|     ); |     ); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|     function saveChanges() { | function goToLearningPathLink(): string | undefined { | ||||||
|         //TODO |     const assignment = assignmentQueryResult.data.value?.assignment; | ||||||
|         const new_learningpath = editingLearningPath.value; |     const lp = lpQueryResult.data.value; | ||||||
|         const new_description = description.value; | 
 | ||||||
|  |     if (!assignment || !lp) return undefined; | ||||||
|  | 
 | ||||||
|  |     return `/learningPath/${lp.hruid}/${assignment.language}/${lp.startNode.learningobjectHruid}?assignmentNo=${props.assignmentId}&classId=${props.classId}`; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function goToGroupSubmissionLink(groupNo: number): string | undefined { | ||||||
|  |     const lp = lpQueryResult.data.value; | ||||||
|  |     if (!lp) return undefined; | ||||||
|  | 
 | ||||||
|  |     return `/learningPath/${lp.hruid}/${lp.language}/${lp.startNode.learningobjectHruid}?forGroup=${groupNo}&assignmentNo=${props.assignmentId}&classId=${props.classId}`; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const learningPathsQueryResults = useGetAllLearningPaths(lang); | ||||||
|  | 
 | ||||||
|  | const { mutate, data, isSuccess } = useUpdateAssignmentMutation(); | ||||||
|  | 
 | ||||||
|  | watch([isSuccess, data], ([success, newData]) => { | ||||||
|  |     if (success && newData?.assignment) { | ||||||
|  |         window.location.reload(); | ||||||
|  |     } | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | async function saveChanges(): Promise<void> { | ||||||
|     isEditing.value = false; |     isEditing.value = false; | ||||||
|  |     //const { valid } = await form.value.validate(); | ||||||
|  |     //if (!valid) return; | ||||||
|  | 
 | ||||||
|  |     const lp = learningPath.value; | ||||||
|  | 
 | ||||||
|  |     const assignmentDTO: AssignmentDTO = { | ||||||
|  |         id: assignmentQueryResult.data.value?.assignment.id, | ||||||
|  |         description: description.value, | ||||||
|  |         learningPath: lp || "", | ||||||
|  |         deadline: new Date(), | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     mutate({ cid: assignmentQueryResult.data.value?.assignment.within, an: assignmentQueryResult.data.value?.assignment.id, data: assignmentDTO }); | ||||||
| } | } | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
|  | @ -162,7 +191,8 @@ Const {groupProgressMap} = props.useGroupsWithProgress( | ||||||
|                                             variant="text" |                                             variant="text" | ||||||
|                                             class="top-right-btn" |                                             class="top-right-btn" | ||||||
|                                             @click="() => {isEditing = false; editingLearningPath=learningPath}" |                                             @click="() => {isEditing = false; editingLearningPath=learningPath}" | ||||||
|                                             >{{ t("cancel") }}</v-btn |                                         >{{ t("cancel") }} | ||||||
|  |                                         </v-btn | ||||||
|                                         > |                                         > | ||||||
| 
 | 
 | ||||||
|                                         <v-btn |                                         <v-btn | ||||||
|  | @ -194,7 +224,8 @@ Const {groupProgressMap} = props.useGroupsWithProgress( | ||||||
| 
 | 
 | ||||||
|                             <v-card-title class="text-h4 assignmentTopTitle">{{ |                             <v-card-title class="text-h4 assignmentTopTitle">{{ | ||||||
|                                     assignmentResponse.data.assignment.title |                                     assignmentResponse.data.assignment.title | ||||||
|                             }}</v-card-title> |                                 }} | ||||||
|  |                             </v-card-title> | ||||||
|                             <v-card-subtitle |                             <v-card-subtitle | ||||||
|                                 v-if="!isEditing" |                                 v-if="!isEditing" | ||||||
|                                 class="subtitle-section" |                                 class="subtitle-section" | ||||||
|  | @ -205,7 +236,7 @@ Const {groupProgressMap} = props.useGroupsWithProgress( | ||||||
|                                 > |                                 > | ||||||
|                                     <v-btn |                                     <v-btn | ||||||
|                                         v-if="lpData" |                                         v-if="lpData" | ||||||
|                                         :to="`/learningPath/${lpData.hruid}/${language}/${lpData.startNode.learningobjectHruid}?assignmentNo=${assignmentId}&classId=${classId}`" |                                         :to="goToLearningPathLink()" | ||||||
|                                         variant="tonal" |                                         variant="tonal" | ||||||
|                                         color="primary" |                                         color="primary" | ||||||
|                                     > |                                     > | ||||||
|  | @ -258,50 +289,6 @@ Const {groupProgressMap} = props.useGroupsWithProgress( | ||||||
|                                 ></v-textarea> |                                 ></v-textarea> | ||||||
|                             </v-card-text> |                             </v-card-text> | ||||||
| 
 | 
 | ||||||
|                             <v-card-text class="group-section"> |  | ||||||
|                                 <h3>{{ t("groups") }}</h3> |  | ||||||
|                                 <div class="table-scroll"> |  | ||||||
|                                     <v-data-table |  | ||||||
|                                         :headers="headers" |  | ||||||
|                                         :items="allGroups" |  | ||||||
|                                         item-key="id" |  | ||||||
|                                         class="elevation-1" |  | ||||||
|                                     > |  | ||||||
|                                         <template #[`item.name`]="{ item }"> |  | ||||||
|                                             <v-btn |  | ||||||
|                                                 @click="openGroupDetails(item)" |  | ||||||
|                                                 variant="text" |  | ||||||
|                                                 color="primary" |  | ||||||
|                                             > |  | ||||||
|                                                 {{ item.name }} |  | ||||||
|                                             </v-btn> |  | ||||||
|                                         </template> |  | ||||||
| 
 |  | ||||||
|                                         <template #[`item.progress`]="{ item }"> |  | ||||||
|                                             <v-progress-linear |  | ||||||
|                                                 :model-value="item.progress" |  | ||||||
|                                                 color="blue-grey" |  | ||||||
|                                                 height="25" |  | ||||||
|                                             > |  | ||||||
|                                                 <template v-slot:default="{ value }"> |  | ||||||
|                                                     <strong>{{ Math.ceil(value) }}%</strong> |  | ||||||
|                                                 </template> |  | ||||||
|                                             </v-progress-linear> |  | ||||||
|                                         </template> |  | ||||||
| 
 |  | ||||||
|                                         <template #[`item.submission`]="{ item }"> |  | ||||||
|                                             <v-btn |  | ||||||
|                                                 :to="item.submitted ? `${props.assignmentId}/submissions/` : undefined" |  | ||||||
|                                                 :color="item.submitted ? 'green' : 'red'" |  | ||||||
|                                                 variant="text" |  | ||||||
|                                                 class="text-capitalize" |  | ||||||
|                                             > |  | ||||||
|                                                 {{ item.submitted ? t("see-submission") : t("no-submission") }} |  | ||||||
|                                             </v-btn> |  | ||||||
|                                         </template> |  | ||||||
|                                     </v-data-table> |  | ||||||
|                                 </div> |  | ||||||
|                             </v-card-text> |  | ||||||
| 
 | 
 | ||||||
|                             <v-dialog |                             <v-dialog | ||||||
|                                 v-model="dialog" |                                 v-model="dialog" | ||||||
|  | @ -327,22 +314,12 @@ Const {groupProgressMap} = props.useGroupsWithProgress( | ||||||
|                                         <v-btn |                                         <v-btn | ||||||
|                                             color="primary" |                                             color="primary" | ||||||
|                                             @click="dialog = false" |                                             @click="dialog = false" | ||||||
|                                             >Close</v-btn |                                         >Close | ||||||
|  |                                         </v-btn | ||||||
|                                         > |                                         > | ||||||
|                                     </v-card-actions> |                                     </v-card-actions> | ||||||
|                                 </v-card> |                                 </v-card> | ||||||
|                             </v-dialog> |                             </v-dialog> | ||||||
|                             <!-- |  | ||||||
|                         <v-card-actions class="justify-end"> |  | ||||||
|                             <v-btn |  | ||||||
|                                 size="large" |  | ||||||
|                                 color="success" |  | ||||||
|                                 variant="text" |  | ||||||
|                             > |  | ||||||
|                                 {{ t("view-submissions") }} |  | ||||||
|                             </v-btn> |  | ||||||
|                         </v-card-actions> |  | ||||||
|                         --> |  | ||||||
|                         </v-card> |                         </v-card> | ||||||
|                     </v-col> |                     </v-col> | ||||||
|                     <v-col |                     <v-col | ||||||
|  | @ -355,51 +332,52 @@ Const {groupProgressMap} = props.useGroupsWithProgress( | ||||||
|                             <thead> |                             <thead> | ||||||
|                             <tr> |                             <tr> | ||||||
|                                 <th class="header">{{ t("group") }}</th> |                                 <th class="header">{{ t("group") }}</th> | ||||||
|  |                                 <th class="header">{{ t("progress") }}</th> | ||||||
|  |                                 <th class="header">{{ t("submission") }}</th> | ||||||
|                                 <th class="header"> |                                 <th class="header"> | ||||||
|                                         {{ t("progress") }} |  | ||||||
|                                     </th> |  | ||||||
|                                     <th class="header">{{ t("Members") }}</th> |  | ||||||
|                                     <th class="header"> |  | ||||||
|                                         <v-btn |  | ||||||
|                                             :to="`/assignment/${assignmentResponse.data.assignment.within}/${assignmentResponse.data.assignment.id}`" |  | ||||||
|                                             variant="text" |  | ||||||
|                                         > |  | ||||||
|                                     <v-icon>mdi-pencil</v-icon> |                                     <v-icon>mdi-pencil</v-icon> | ||||||
|                                         </v-btn> |  | ||||||
|                                 </th> |                                 </th> | ||||||
|                             </tr> |                             </tr> | ||||||
|                             </thead> |                             </thead> | ||||||
|                             <tbody> |                             <tbody> | ||||||
|                             <tr |                             <tr | ||||||
|                                     v-for="g in assignmentResponse.data.assignment.groups as GroupDTO[]" |                                 v-for="g in allGroups" | ||||||
|                                     :key="g.groupNumber" |                                 :key="g.originalGroupNo" | ||||||
|                             > |                             > | ||||||
|                                 <td> |                                 <td> | ||||||
|                                     <v-btn |                                     <v-btn | ||||||
|                                             :to="`/assignment/${assignmentResponse.data.assignment.within}/${assignmentResponse.data.assignment.id}`" |                                         @click="openGroupDetails(g)" | ||||||
|                                         variant="text" |                                         variant="text" | ||||||
|                                     > |                                     > | ||||||
|                                             {{ g.groupNumber }} |                                         {{ g.name }} | ||||||
|                                         <v-icon end>mdi-menu-right</v-icon> |                                         <v-icon end>mdi-menu-right</v-icon> | ||||||
|                                     </v-btn> |                                     </v-btn> | ||||||
|                                 </td> |                                 </td> | ||||||
|  | 
 | ||||||
|                                 <td> |                                 <td> | ||||||
|                                         <v-progress-linear |                                     <GroupProgressRow | ||||||
|                                             :model-value="0" |                                         :group-number="g.originalGroupNo" | ||||||
|                                             color="blue-grey" |                                         :learning-path="learningPath" | ||||||
|                                             height="25" |                                         :language="lang" | ||||||
|                                         > |                                         :assignment-id="assignmentId" | ||||||
|                                             <template v-slot:default="{ value }"> |                                         :class-id="classId" | ||||||
|                                                 <strong>{{ Math.ceil(value) }}%</strong> |                                     /> | ||||||
|                                             </template> |  | ||||||
|                                         </v-progress-linear> |  | ||||||
|                                 </td> |                                 </td> | ||||||
|  | 
 | ||||||
|                                 <td> |                                 <td> | ||||||
|                                         {{ (g.members! as StudentDTO[]).map((member) => member.username).join(", ") }} |                                     <GroupSubmissionStatus | ||||||
|  |                                         :group="g" | ||||||
|  |                                         :assignment-id="assignmentId" | ||||||
|  |                                         :class-id="classId" | ||||||
|  |                                         :language="lang" | ||||||
|  |                                         :go-to-group-submission-link="goToGroupSubmissionLink" | ||||||
|  |                                     /> | ||||||
|                                 </td> |                                 </td> | ||||||
|  | 
 | ||||||
|  |                                 <!-- Edit icon --> | ||||||
|                                 <td> |                                 <td> | ||||||
|                                     <v-btn |                                     <v-btn | ||||||
|                                             :to="`/assignment/${assignmentResponse.data.assignment.within}/${assignmentResponse.data.assignment.id}`" |                                         to="/user" | ||||||
|                                         variant="text" |                                         variant="text" | ||||||
|                                     > |                                     > | ||||||
|                                         <v-icon color="red"> mdi-delete</v-icon> |                                         <v-icon color="red"> mdi-delete</v-icon> | ||||||
|  | @ -408,6 +386,7 @@ Const {groupProgressMap} = props.useGroupsWithProgress( | ||||||
|                             </tr> |                             </tr> | ||||||
|                             </tbody> |                             </tbody> | ||||||
|                         </v-table> |                         </v-table> | ||||||
|  | 
 | ||||||
|                     </v-col> |                     </v-col> | ||||||
|                 </v-row> |                 </v-row> | ||||||
|             </v-container> |             </v-container> | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Joyelle Ndagijimana
						Joyelle Ndagijimana