fix: kleine fixes
This commit is contained in:
		
							parent
							
								
									0abe9b1bce
								
							
						
					
					
						commit
						7f1c66c757
					
				
					 5 changed files with 131 additions and 44 deletions
				
			
		|  | @ -3,6 +3,7 @@ | ||||||
|     import UsingQueryResult from "@/components/UsingQueryResult.vue"; |     import UsingQueryResult from "@/components/UsingQueryResult.vue"; | ||||||
|     import { useAssignmentSubmissionsQuery } from "@/queries/assignments.ts"; |     import { useAssignmentSubmissionsQuery } from "@/queries/assignments.ts"; | ||||||
|     import type { SubmissionsResponse } from "@/controllers/submissions.ts"; |     import type { SubmissionsResponse } from "@/controllers/submissions.ts"; | ||||||
|  |     import {watch} from "vue"; | ||||||
| 
 | 
 | ||||||
|     const props = defineProps<{ |     const props = defineProps<{ | ||||||
|         group: object; |         group: object; | ||||||
|  | @ -11,6 +12,8 @@ | ||||||
|         goToGroupSubmissionLink: (groupNo: number) => void; |         goToGroupSubmissionLink: (groupNo: number) => void; | ||||||
|     }>(); |     }>(); | ||||||
| 
 | 
 | ||||||
|  |     const emit = defineEmits<(e: "update:hasSubmission", hasSubmission: boolean) => void>(); | ||||||
|  | 
 | ||||||
|     const { t } = useI18n(); |     const { t } = useI18n(); | ||||||
|     const submissionsQuery = useAssignmentSubmissionsQuery( |     const submissionsQuery = useAssignmentSubmissionsQuery( | ||||||
|         () => props.classId, |         () => props.classId, | ||||||
|  | @ -18,6 +21,16 @@ | ||||||
|         () => props.group.originalGroupNo, |         () => props.group.originalGroupNo, | ||||||
|         () => true, |         () => true, | ||||||
|     ); |     ); | ||||||
|  | 
 | ||||||
|  |     watch( | ||||||
|  |         () => submissionsQuery.data.value, | ||||||
|  |         (data) => { | ||||||
|  |             if (data) { | ||||||
|  |                 emit("update:hasSubmission", data.submissions.length > 0); | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         { immediate: true } | ||||||
|  |     ); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <template> | <template> | ||||||
|  |  | ||||||
|  | @ -355,7 +355,7 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <template> | <template> | ||||||
|     <v-card class="pa-4"> |     <v-card class="pa-4 minimal-card"> | ||||||
|         <!-- Current groups and unassigned students Preview --> |         <!-- Current groups and unassigned students Preview --> | ||||||
|         <div v-if="showGroupsPreview" class="mb-6"> |         <div v-if="showGroupsPreview" class="mb-6"> | ||||||
|             <h3 class="mb-2">{{ t("current-groups") }}</h3> |             <h3 class="mb-2">{{ t("current-groups") }}</h3> | ||||||
|  | @ -364,20 +364,13 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | ||||||
|                     <label>{{ currentGroups.length }}</label> |                     <label>{{ currentGroups.length }}</label> | ||||||
|                 </div> |                 </div> | ||||||
|             </div> |             </div> | ||||||
| 
 |  | ||||||
|             <div v-if="unassignedStudents.length > 0" class="mt-3"> |  | ||||||
|                 <strong>{{ t("unassigned-students") }}:</strong> |  | ||||||
|                 <div class="d-flex flex-wrap"> |  | ||||||
|                     <label>{{ unassignedStudents.length }}</label> |  | ||||||
|                 </div> |  | ||||||
|             </div> |  | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
|         <v-row justify="center" class="mb-4"> |         <v-row justify="center" class="mb-4"> | ||||||
|             <v-btn color="primary" @click="activeDialog = 'random'"> |             <v-btn color="primary" @click="activeDialog = 'random'" prepend-icon="mdi-shuffle"> | ||||||
|                 {{ t("randomly-create-groups") }} |                 {{ t("random-grouping") }} | ||||||
|             </v-btn> |             </v-btn> | ||||||
|             <v-btn color="secondary" class="ml-4" @click="activeDialog = 'dragdrop'"> |             <v-btn color="secondary" class="ml-4" @click="activeDialog = 'dragdrop'" prepend-icon="mdi-drag"> | ||||||
|                 {{ t("drag-and-drop") }} |                 {{ t("drag-and-drop") }} | ||||||
|             </v-btn> |             </v-btn> | ||||||
|         </v-row> |         </v-row> | ||||||
|  | @ -388,8 +381,8 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | ||||||
|             @update:model-value="(val) => (val ? (activeDialog = 'random') : (activeDialog = null))" |             @update:model-value="(val) => (val ? (activeDialog = 'random') : (activeDialog = null))" | ||||||
|             max-width="600" |             max-width="600" | ||||||
|         > |         > | ||||||
|             <v-card> |             <v-card class="custom-dialog"> | ||||||
|                 <v-card-title>{{ t("randomly-create-groups") }}</v-card-title> |                 <v-card-title class="dialog-title">{{ t("auto-generate-groups") }}</v-card-title> | ||||||
|                 <v-card-text> |                 <v-card-text> | ||||||
|                     <v-row align="center"> |                     <v-row align="center"> | ||||||
|                         <v-col cols="6"> |                         <v-col cols="6"> | ||||||
|  | @ -442,7 +435,7 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | ||||||
|                     </div> |                     </div> | ||||||
|                 </v-card-text> |                 </v-card-text> | ||||||
| 
 | 
 | ||||||
|                 <v-card-actions> |                 <v-card-actions class="dialog-actions"> | ||||||
|                     <v-spacer/> |                     <v-spacer/> | ||||||
|                     <v-btn text @click="activeDialog = null">{{ t("cancel") }}</v-btn> |                     <v-btn text @click="activeDialog = null">{{ t("cancel") }}</v-btn> | ||||||
|                     <v-btn |                     <v-btn | ||||||
|  | @ -462,8 +455,8 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | ||||||
|             @update:model-value="(val) => (val ? (activeDialog = 'dragdrop') : (activeDialog = null))" |             @update:model-value="(val) => (val ? (activeDialog = 'dragdrop') : (activeDialog = null))" | ||||||
|             max-width="900" |             max-width="900" | ||||||
|         > |         > | ||||||
|             <v-card> |             <v-card class="custom-dialog"> | ||||||
|                 <v-card-title class="d-flex justify-space-between align-center"> |                 <v-card-title class=" dialog-title d-flex justify-space-between align-center"> | ||||||
|                     <div>{{ t("drag-and-drop") }}</div> |                     <div>{{ t("drag-and-drop") }}</div> | ||||||
|                     <v-btn color="primary" small @click="addNewGroup">+</v-btn> |                     <v-btn color="primary" small @click="addNewGroup">+</v-btn> | ||||||
|                 </v-card-title> |                 </v-card-title> | ||||||
|  | @ -603,4 +596,60 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | ||||||
|     visibility: hidden; |     visibility: hidden; | ||||||
|     display: inline-block; |     display: inline-block; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | .custom-dialog { | ||||||
|  |     border-radius: 16px; | ||||||
|  |     padding: 24px; | ||||||
|  |     box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .dialog-title { | ||||||
|  |     color: #00796b; /* teal-like green */ | ||||||
|  |     font-weight: bold; | ||||||
|  |     font-size: 1.25rem; | ||||||
|  |     margin-bottom: 16px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .dialog-actions { | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: flex-end; | ||||||
|  |     gap: 12px; | ||||||
|  |     margin-top: 24px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .v-btn.custom-green { | ||||||
|  |     background-color: #43a047; | ||||||
|  |     color: white; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .v-btn.custom-green:hover { | ||||||
|  |     background-color: #388e3c | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .v-btn.custom-blue { | ||||||
|  |     background-color: #1e88e5; | ||||||
|  |     color: white; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .v-btn.custom-blue:hover { | ||||||
|  |     background-color: #1565c0 ; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .v-btn.cancel-button { | ||||||
|  |     background-color: #e0f2f1; | ||||||
|  |     color: #00695c; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .minimal-card { | ||||||
|  |     box-shadow: none;           /* remove card shadow */ | ||||||
|  |     border: none;               /* remove border */ | ||||||
|  |     background-color: transparent;  /* make background transparent */ | ||||||
|  |     padding: 0;                 /* reduce padding */ | ||||||
|  |     margin-bottom: 1rem;        /* keep some spacing below */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* Optionally, keep some padding only around buttons */ | ||||||
|  | .minimal-card > .v-row { | ||||||
|  |     padding: 1rem 0;            /* give vertical padding around buttons */ | ||||||
|  | } | ||||||
| </style> | </style> | ||||||
|  |  | ||||||
|  | @ -36,6 +36,7 @@ const assignmentTitle = ref(""); | ||||||
| 
 | 
 | ||||||
| const selectedLearningPath = ref<LearningPath | undefined>(undefined); | const selectedLearningPath = ref<LearningPath | undefined>(undefined); | ||||||
| const lpIsSelected = ref(false); | const lpIsSelected = ref(false); | ||||||
|  | 
 | ||||||
| watch(learningPathsQueryResults.data, (data) => { | watch(learningPathsQueryResults.data, (data) => { | ||||||
|     const hruidFromRoute = route.query.hruid?.toString(); |     const hruidFromRoute = route.query.hruid?.toString(); | ||||||
|     if (!hruidFromRoute || !data) return; |     if (!hruidFromRoute || !data) return; | ||||||
|  | @ -61,9 +62,8 @@ async function submitFormHandler(): Promise<void> { | ||||||
|     if (!valid) return; |     if (!valid) return; | ||||||
| 
 | 
 | ||||||
|     const lp = lpIsSelected.value |     const lp = lpIsSelected.value | ||||||
|         ? route.query.hruid |         ? route.query.hruid?.toString() | ||||||
|         : selectedLearningPath.value?.hruid; |         : selectedLearningPath.value?.hruid; | ||||||
| 
 |  | ||||||
|     if (!lp) { |     if (!lp) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
|  | @ -71,10 +71,10 @@ async function submitFormHandler(): Promise<void> { | ||||||
|     const assignmentDTO: AssignmentDTO = { |     const assignmentDTO: AssignmentDTO = { | ||||||
|         id: 0, |         id: 0, | ||||||
|         within: selectedClass.value?.id || "", |         within: selectedClass.value?.id || "", | ||||||
|         title: assignmentTitle.value.toString(), |         title: assignmentTitle.value, | ||||||
|         description: "", |         description: "", | ||||||
|         learningPath: lp.toString(), |         learningPath: lp, | ||||||
|         language: language.value.toString(), |         language: language.value, | ||||||
|         deadline: null, |         deadline: null, | ||||||
|         groups: [], |         groups: [], | ||||||
|     }; |     }; | ||||||
|  | @ -83,9 +83,9 @@ async function submitFormHandler(): Promise<void> { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const learningPathRules = [ | const learningPathRules = [ | ||||||
|     (value: any) => { |     (value: LearningPath): string | boolean => { | ||||||
| 
 | 
 | ||||||
|         if(lpIsSelected.value) return; |         if(lpIsSelected.value) return true; | ||||||
| 
 | 
 | ||||||
|         if (!value) return t("lp-required"); |         if (!value) return t("lp-required"); | ||||||
| 
 | 
 | ||||||
|  | @ -146,17 +146,17 @@ const classRules = [ | ||||||
|                         v-slot="{ data }: { data: LearningPath[] }" |                         v-slot="{ data }: { data: LearningPath[] }" | ||||||
|                     > |                     > | ||||||
|                         <v-combobox |                         <v-combobox | ||||||
|  |                             v-model="selectedLearningPath" | ||||||
|                             :items="data" |                             :items="data" | ||||||
|                             :label="t('choose-lp')" |                             :label="t('choose-lp')" | ||||||
|                             :rules="lpIsSelected ? [] : learningPathRules" |                             :rules="lpIsSelected ? [] : learningPathRules" | ||||||
|                             variant="solo-filled" |                             variant="solo-filled" | ||||||
|                             clearable |                             clearable | ||||||
|                             :model-value="lpIsSelected ? data.find(lp => lp.hruid === route.query.hruid?.toString()) : selectedLearningPath" |  | ||||||
|                             item-title="title" |                             item-title="title" | ||||||
|                             item-value="hruid" |  | ||||||
|                             :disabled="lpIsSelected" |                             :disabled="lpIsSelected" | ||||||
|                             return-object |                             return-object | ||||||
|                         /> |                         /> | ||||||
|  | 
 | ||||||
|                     </using-query-result> |                     </using-query-result> | ||||||
| 
 | 
 | ||||||
|                     <!-- Klas keuze --> |                     <!-- Klas keuze --> | ||||||
|  |  | ||||||
|  | @ -60,6 +60,9 @@ watchEffect(() => { | ||||||
|     } |     } | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | const hasSubmissions = ref<boolean>(false); | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| const allGroups = computed(() => { | const allGroups = computed(() => { | ||||||
|     const groups = groupsQueryResult.data.value?.groups; |     const groups = groupsQueryResult.data.value?.groups; | ||||||
| 
 | 
 | ||||||
|  | @ -73,7 +76,7 @@ const allGroups = computed(() => { | ||||||
|         groupNo: index + 1, // New group number that will be used |         groupNo: index + 1, // New group number that will be used | ||||||
|         name: `${t("group")} ${index + 1}`, |         name: `${t("group")} ${index + 1}`, | ||||||
|         members: group.members, |         members: group.members, | ||||||
|         originalGroupNo: group.groupNumber, // Keep original number if needed |         originalGroupNo: group.groupNumber | ||||||
|     })); |     })); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | @ -298,29 +301,42 @@ async function handleGroupsUpdated(updatedGroups: string[][]): Promise<void> { | ||||||
|                         <!-- A pop up to show group members --> |                         <!-- A pop up to show group members --> | ||||||
|                         <v-dialog |                         <v-dialog | ||||||
|                             v-model="dialog" |                             v-model="dialog" | ||||||
|                             max-width="50%" |                             max-width="600" | ||||||
|  |                             persistent | ||||||
|                         > |                         > | ||||||
|                             <v-card> |                             <v-card class="pa-4 rounded-xl elevation-6 group-members-dialog"> | ||||||
|                                 <v-card-title class="headline">{{ t("members") }}</v-card-title> |                                 <v-card-title class="text-h6 font-weight-bold"> | ||||||
|  |                                     {{ t("members") }} | ||||||
|  |                                 </v-card-title> | ||||||
|  | 
 | ||||||
|  |                                 <v-divider class="my-2" /> | ||||||
|  | 
 | ||||||
|                                 <v-card-text> |                                 <v-card-text> | ||||||
|                                     <v-list> |                                     <v-list> | ||||||
|                                         <v-list-item |                                         <v-list-item | ||||||
|                                             v-for="(member, index) in selectedGroup.members" |                                             v-for="(member, index) in selectedGroup.members" | ||||||
|                                             :key="index" |                                             :key="index" | ||||||
|  |                                             class="py-2" | ||||||
|                                         > |                                         > | ||||||
|                                             <v-list-item-content> |                                             <v-list-item-content> | ||||||
|                                                 <v-list-item-title |                                                 <v-list-item-title class="text-body-1"> | ||||||
|                                                 >{{ member.firstName + " " + member.lastName }} |                                                     {{ member.firstName }} {{ member.lastName }} | ||||||
|                                                 </v-list-item-title> |                                                 </v-list-item-title> | ||||||
|                                             </v-list-item-content> |                                             </v-list-item-content> | ||||||
|                                         </v-list-item> |                                         </v-list-item> | ||||||
|                                     </v-list> |                                     </v-list> | ||||||
|                                 </v-card-text> |                                 </v-card-text> | ||||||
|                                 <v-card-actions> | 
 | ||||||
|  |                                 <v-divider class="my-2" /> | ||||||
|  | 
 | ||||||
|  |                                 <v-card-actions class="justify-end"> | ||||||
|                                     <v-btn |                                     <v-btn | ||||||
|                                         color="primary" |                                         color="primary" | ||||||
|  |                                         variant="outlined" | ||||||
|                                         @click="dialog = false" |                                         @click="dialog = false" | ||||||
|                                     >Close |                                         prepend-icon="mdi-close-circle" | ||||||
|  |                                     > | ||||||
|  |                                         {{ t("close") }} | ||||||
|                                     </v-btn> |                                     </v-btn> | ||||||
|                                 </v-card-actions> |                                 </v-card-actions> | ||||||
|                             </v-card> |                             </v-card> | ||||||
|  | @ -345,6 +361,7 @@ async function handleGroupsUpdated(updatedGroups: string[][]): Promise<void> { | ||||||
|                                         <v-btn |                                         <v-btn | ||||||
|                                             @click="editGroups = true" |                                             @click="editGroups = true" | ||||||
|                                             variant="text" |                                             variant="text" | ||||||
|  |                                             :disabled="hasSubmissions" | ||||||
|                                         > |                                         > | ||||||
|                                             <v-icon>mdi-pencil</v-icon> |                                             <v-icon>mdi-pencil</v-icon> | ||||||
|                                         </v-btn> |                                         </v-btn> | ||||||
|  | @ -358,11 +375,9 @@ async function handleGroupsUpdated(updatedGroups: string[][]): Promise<void> { | ||||||
|                                 > |                                 > | ||||||
|                                     <td> |                                     <td> | ||||||
|                                         <v-btn |                                         <v-btn | ||||||
|                                             @click="openGroupDetails(g)" |  | ||||||
|                                             variant="text" |                                             variant="text" | ||||||
|                                         > |                                         > | ||||||
|                                             {{ g.name }} |                                             {{ g.name }} | ||||||
|                                             <v-icon end>mdi-menu-right</v-icon> |  | ||||||
|                                         </v-btn> |                                         </v-btn> | ||||||
|                                     </td> |                                     </td> | ||||||
| 
 | 
 | ||||||
|  | @ -383,16 +398,18 @@ async function handleGroupsUpdated(updatedGroups: string[][]): Promise<void> { | ||||||
|                                             :class-id="classId" |                                             :class-id="classId" | ||||||
|                                             :language="lang" |                                             :language="lang" | ||||||
|                                             :go-to-group-submission-link="goToGroupSubmissionLink" |                                             :go-to-group-submission-link="goToGroupSubmissionLink" | ||||||
|  |                                             @update:hasSubmission="(hasSubmission) => hasSubmissions = hasSubmission" | ||||||
|  | 
 | ||||||
|                                         /> |                                         /> | ||||||
|                                     </td> |                                     </td> | ||||||
| 
 | 
 | ||||||
|                                     <!-- Edit icon --> |                                     <!-- Edit icon --> | ||||||
|                                     <td> |                                     <td> | ||||||
|                                         <v-btn |                                         <v-btn | ||||||
|                                             @click="" |                                             @click="openGroupDetails(g)" | ||||||
|                                             variant="text" |                                             variant="text" | ||||||
|                                         > |                                         > | ||||||
|                                             <v-icon color="red">mdi-delete</v-icon> |                                             <v-icon>mdi-eye</v-icon> | ||||||
|                                         </v-btn> |                                         </v-btn> | ||||||
|                                     </td> |                                     </td> | ||||||
|                                 </tr> |                                 </tr> | ||||||
|  | @ -416,16 +433,18 @@ async function handleGroupsUpdated(updatedGroups: string[][]): Promise<void> { | ||||||
|                                 @close="editGroups = false" |                                 @close="editGroups = false" | ||||||
|                             /> |                             /> | ||||||
|                         </v-card-text> |                         </v-card-text> | ||||||
|  | 
 | ||||||
|  |                         <v-divider></v-divider> | ||||||
|  | 
 | ||||||
|                         <v-card-actions> |                         <v-card-actions> | ||||||
|                             <v-btn |                             <v-spacer></v-spacer> | ||||||
|                                 text |                             <v-btn text @click="editGroups = false"> | ||||||
|                                 @click="editGroups = false" |                                 {{ t("cancel") }} | ||||||
|                             >{{ t("cancel") }} |                             </v-btn> | ||||||
|                             </v-btn |  | ||||||
|                             > |  | ||||||
|                         </v-card-actions> |                         </v-card-actions> | ||||||
|                     </v-card> |                     </v-card> | ||||||
|                 </v-dialog> |                 </v-dialog> | ||||||
|  | 
 | ||||||
|             </v-container> |             </v-container> | ||||||
|         </using-query-result> |         </using-query-result> | ||||||
|     </div> |     </div> | ||||||
|  | @ -557,4 +576,10 @@ main { | ||||||
|         flex-basis: 100% !important; |         flex-basis: 100% !important; | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | .group-members-dialog { | ||||||
|  |     max-height: 80vh; | ||||||
|  |     overflow-y: auto; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| </style> | </style> | ||||||
|  |  | ||||||
|  | @ -146,7 +146,7 @@ | ||||||
| 
 | 
 | ||||||
|         <v-btn |         <v-btn | ||||||
|             v-if="isTeacher" |             v-if="isTeacher" | ||||||
|             color="primary" |             :style="{ backgroundColor: '#0E6942' }" | ||||||
|             class="mb-4 center-btn" |             class="mb-4 center-btn" | ||||||
|             @click="goToCreateAssignment" |             @click="goToCreateAssignment" | ||||||
|         > |         > | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Joyelle Ndagijimana
						Joyelle Ndagijimana