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 { useAssignmentSubmissionsQuery } from "@/queries/assignments.ts"; | ||||
|     import type { SubmissionsResponse } from "@/controllers/submissions.ts"; | ||||
|     import {watch} from "vue"; | ||||
| 
 | ||||
|     const props = defineProps<{ | ||||
|         group: object; | ||||
|  | @ -11,6 +12,8 @@ | |||
|         goToGroupSubmissionLink: (groupNo: number) => void; | ||||
|     }>(); | ||||
| 
 | ||||
|     const emit = defineEmits<(e: "update:hasSubmission", hasSubmission: boolean) => void>(); | ||||
| 
 | ||||
|     const { t } = useI18n(); | ||||
|     const submissionsQuery = useAssignmentSubmissionsQuery( | ||||
|         () => props.classId, | ||||
|  | @ -18,6 +21,16 @@ | |||
|         () => props.group.originalGroupNo, | ||||
|         () => true, | ||||
|     ); | ||||
| 
 | ||||
|     watch( | ||||
|         () => submissionsQuery.data.value, | ||||
|         (data) => { | ||||
|             if (data) { | ||||
|                 emit("update:hasSubmission", data.submissions.length > 0); | ||||
|             } | ||||
|         }, | ||||
|         { immediate: true } | ||||
|     ); | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|  |  | |||
|  | @ -355,7 +355,7 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | |||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <v-card class="pa-4"> | ||||
|     <v-card class="pa-4 minimal-card"> | ||||
|         <!-- Current groups and unassigned students Preview --> | ||||
|         <div v-if="showGroupsPreview" class="mb-6"> | ||||
|             <h3 class="mb-2">{{ t("current-groups") }}</h3> | ||||
|  | @ -364,20 +364,13 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | |||
|                     <label>{{ currentGroups.length }}</label> | ||||
|                 </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> | ||||
| 
 | ||||
|         <v-row justify="center" class="mb-4"> | ||||
|             <v-btn color="primary" @click="activeDialog = 'random'"> | ||||
|                 {{ t("randomly-create-groups") }} | ||||
|             <v-btn color="primary" @click="activeDialog = 'random'" prepend-icon="mdi-shuffle"> | ||||
|                 {{ t("random-grouping") }} | ||||
|             </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") }} | ||||
|             </v-btn> | ||||
|         </v-row> | ||||
|  | @ -388,8 +381,8 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | |||
|             @update:model-value="(val) => (val ? (activeDialog = 'random') : (activeDialog = null))" | ||||
|             max-width="600" | ||||
|         > | ||||
|             <v-card> | ||||
|                 <v-card-title>{{ t("randomly-create-groups") }}</v-card-title> | ||||
|             <v-card class="custom-dialog"> | ||||
|                 <v-card-title class="dialog-title">{{ t("auto-generate-groups") }}</v-card-title> | ||||
|                 <v-card-text> | ||||
|                     <v-row align="center"> | ||||
|                         <v-col cols="6"> | ||||
|  | @ -442,7 +435,7 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | |||
|                     </div> | ||||
|                 </v-card-text> | ||||
| 
 | ||||
|                 <v-card-actions> | ||||
|                 <v-card-actions class="dialog-actions"> | ||||
|                     <v-spacer/> | ||||
|                     <v-btn text @click="activeDialog = null">{{ t("cancel") }}</v-btn> | ||||
|                     <v-btn | ||||
|  | @ -462,8 +455,8 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | |||
|             @update:model-value="(val) => (val ? (activeDialog = 'dragdrop') : (activeDialog = null))" | ||||
|             max-width="900" | ||||
|         > | ||||
|             <v-card> | ||||
|                 <v-card-title class="d-flex justify-space-between align-center"> | ||||
|             <v-card class="custom-dialog"> | ||||
|                 <v-card-title class=" dialog-title d-flex justify-space-between align-center"> | ||||
|                     <div>{{ t("drag-and-drop") }}</div> | ||||
|                     <v-btn color="primary" small @click="addNewGroup">+</v-btn> | ||||
|                 </v-card-title> | ||||
|  | @ -603,4 +596,60 @@ function removeStudent(groupIndex: number, student: StudentItem): void { | |||
|     visibility: hidden; | ||||
|     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> | ||||
|  |  | |||
|  | @ -36,6 +36,7 @@ const assignmentTitle = ref(""); | |||
| 
 | ||||
| const selectedLearningPath = ref<LearningPath | undefined>(undefined); | ||||
| const lpIsSelected = ref(false); | ||||
| 
 | ||||
| watch(learningPathsQueryResults.data, (data) => { | ||||
|     const hruidFromRoute = route.query.hruid?.toString(); | ||||
|     if (!hruidFromRoute || !data) return; | ||||
|  | @ -61,9 +62,8 @@ async function submitFormHandler(): Promise<void> { | |||
|     if (!valid) return; | ||||
| 
 | ||||
|     const lp = lpIsSelected.value | ||||
|         ? route.query.hruid | ||||
|         ? route.query.hruid?.toString() | ||||
|         : selectedLearningPath.value?.hruid; | ||||
| 
 | ||||
|     if (!lp) { | ||||
|         return; | ||||
|     } | ||||
|  | @ -71,10 +71,10 @@ async function submitFormHandler(): Promise<void> { | |||
|     const assignmentDTO: AssignmentDTO = { | ||||
|         id: 0, | ||||
|         within: selectedClass.value?.id || "", | ||||
|         title: assignmentTitle.value.toString(), | ||||
|         title: assignmentTitle.value, | ||||
|         description: "", | ||||
|         learningPath: lp.toString(), | ||||
|         language: language.value.toString(), | ||||
|         learningPath: lp, | ||||
|         language: language.value, | ||||
|         deadline: null, | ||||
|         groups: [], | ||||
|     }; | ||||
|  | @ -83,9 +83,9 @@ async function submitFormHandler(): Promise<void> { | |||
| } | ||||
| 
 | ||||
| const learningPathRules = [ | ||||
|     (value: any) => { | ||||
|     (value: LearningPath): string | boolean => { | ||||
| 
 | ||||
|         if(lpIsSelected.value) return; | ||||
|         if(lpIsSelected.value) return true; | ||||
| 
 | ||||
|         if (!value) return t("lp-required"); | ||||
| 
 | ||||
|  | @ -146,17 +146,17 @@ const classRules = [ | |||
|                         v-slot="{ data }: { data: LearningPath[] }" | ||||
|                     > | ||||
|                         <v-combobox | ||||
|                             v-model="selectedLearningPath" | ||||
|                             :items="data" | ||||
|                             :label="t('choose-lp')" | ||||
|                             :rules="lpIsSelected ? [] : learningPathRules" | ||||
|                             variant="solo-filled" | ||||
|                             clearable | ||||
|                             :model-value="lpIsSelected ? data.find(lp => lp.hruid === route.query.hruid?.toString()) : selectedLearningPath" | ||||
|                             item-title="title" | ||||
|                             item-value="hruid" | ||||
|                             :disabled="lpIsSelected" | ||||
|                             return-object | ||||
|                         /> | ||||
| 
 | ||||
|                     </using-query-result> | ||||
| 
 | ||||
|                     <!-- Klas keuze --> | ||||
|  |  | |||
|  | @ -60,6 +60,9 @@ watchEffect(() => { | |||
|     } | ||||
| }); | ||||
| 
 | ||||
| const hasSubmissions = ref<boolean>(false); | ||||
| 
 | ||||
| 
 | ||||
| const allGroups = computed(() => { | ||||
|     const groups = groupsQueryResult.data.value?.groups; | ||||
| 
 | ||||
|  | @ -73,7 +76,7 @@ const allGroups = computed(() => { | |||
|         groupNo: index + 1, // New group number that will be used | ||||
|         name: `${t("group")} ${index + 1}`, | ||||
|         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 --> | ||||
|                         <v-dialog | ||||
|                             v-model="dialog" | ||||
|                             max-width="50%" | ||||
|                             max-width="600" | ||||
|                             persistent | ||||
|                         > | ||||
|                             <v-card> | ||||
|                                 <v-card-title class="headline">{{ t("members") }}</v-card-title> | ||||
|                             <v-card class="pa-4 rounded-xl elevation-6 group-members-dialog"> | ||||
|                                 <v-card-title class="text-h6 font-weight-bold"> | ||||
|                                     {{ t("members") }} | ||||
|                                 </v-card-title> | ||||
| 
 | ||||
|                                 <v-divider class="my-2" /> | ||||
| 
 | ||||
|                                 <v-card-text> | ||||
|                                     <v-list> | ||||
|                                         <v-list-item | ||||
|                                             v-for="(member, index) in selectedGroup.members" | ||||
|                                             :key="index" | ||||
|                                             class="py-2" | ||||
|                                         > | ||||
|                                             <v-list-item-content> | ||||
|                                                 <v-list-item-title | ||||
|                                                 >{{ member.firstName + " " + member.lastName }} | ||||
|                                                 <v-list-item-title class="text-body-1"> | ||||
|                                                     {{ member.firstName }} {{ member.lastName }} | ||||
|                                                 </v-list-item-title> | ||||
|                                             </v-list-item-content> | ||||
|                                         </v-list-item> | ||||
|                                     </v-list> | ||||
|                                 </v-card-text> | ||||
|                                 <v-card-actions> | ||||
| 
 | ||||
|                                 <v-divider class="my-2" /> | ||||
| 
 | ||||
|                                 <v-card-actions class="justify-end"> | ||||
|                                     <v-btn | ||||
|                                         color="primary" | ||||
|                                         variant="outlined" | ||||
|                                         @click="dialog = false" | ||||
|                                     >Close | ||||
|                                         prepend-icon="mdi-close-circle" | ||||
|                                     > | ||||
|                                         {{ t("close") }} | ||||
|                                     </v-btn> | ||||
|                                 </v-card-actions> | ||||
|                             </v-card> | ||||
|  | @ -345,6 +361,7 @@ async function handleGroupsUpdated(updatedGroups: string[][]): Promise<void> { | |||
|                                         <v-btn | ||||
|                                             @click="editGroups = true" | ||||
|                                             variant="text" | ||||
|                                             :disabled="hasSubmissions" | ||||
|                                         > | ||||
|                                             <v-icon>mdi-pencil</v-icon> | ||||
|                                         </v-btn> | ||||
|  | @ -358,11 +375,9 @@ async function handleGroupsUpdated(updatedGroups: string[][]): Promise<void> { | |||
|                                 > | ||||
|                                     <td> | ||||
|                                         <v-btn | ||||
|                                             @click="openGroupDetails(g)" | ||||
|                                             variant="text" | ||||
|                                         > | ||||
|                                             {{ g.name }} | ||||
|                                             <v-icon end>mdi-menu-right</v-icon> | ||||
|                                         </v-btn> | ||||
|                                     </td> | ||||
| 
 | ||||
|  | @ -383,16 +398,18 @@ async function handleGroupsUpdated(updatedGroups: string[][]): Promise<void> { | |||
|                                             :class-id="classId" | ||||
|                                             :language="lang" | ||||
|                                             :go-to-group-submission-link="goToGroupSubmissionLink" | ||||
|                                             @update:hasSubmission="(hasSubmission) => hasSubmissions = hasSubmission" | ||||
| 
 | ||||
|                                         /> | ||||
|                                     </td> | ||||
| 
 | ||||
|                                     <!-- Edit icon --> | ||||
|                                     <td> | ||||
|                                         <v-btn | ||||
|                                             @click="" | ||||
|                                             @click="openGroupDetails(g)" | ||||
|                                             variant="text" | ||||
|                                         > | ||||
|                                             <v-icon color="red">mdi-delete</v-icon> | ||||
|                                             <v-icon>mdi-eye</v-icon> | ||||
|                                         </v-btn> | ||||
|                                     </td> | ||||
|                                 </tr> | ||||
|  | @ -416,16 +433,18 @@ async function handleGroupsUpdated(updatedGroups: string[][]): Promise<void> { | |||
|                                 @close="editGroups = false" | ||||
|                             /> | ||||
|                         </v-card-text> | ||||
| 
 | ||||
|                         <v-divider></v-divider> | ||||
| 
 | ||||
|                         <v-card-actions> | ||||
|                             <v-btn | ||||
|                                 text | ||||
|                                 @click="editGroups = false" | ||||
|                             >{{ t("cancel") }} | ||||
|                             </v-btn | ||||
|                             > | ||||
|                             <v-spacer></v-spacer> | ||||
|                             <v-btn text @click="editGroups = false"> | ||||
|                                 {{ t("cancel") }} | ||||
|                             </v-btn> | ||||
|                         </v-card-actions> | ||||
|                     </v-card> | ||||
|                 </v-dialog> | ||||
| 
 | ||||
|             </v-container> | ||||
|         </using-query-result> | ||||
|     </div> | ||||
|  | @ -557,4 +576,10 @@ main { | |||
|         flex-basis: 100% !important; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| .group-members-dialog { | ||||
|     max-height: 80vh; | ||||
|     overflow-y: auto; | ||||
| } | ||||
| 
 | ||||
| </style> | ||||
|  |  | |||
|  | @ -146,7 +146,7 @@ | |||
| 
 | ||||
|         <v-btn | ||||
|             v-if="isTeacher" | ||||
|             color="primary" | ||||
|             :style="{ backgroundColor: '#0E6942' }" | ||||
|             class="mb-4 center-btn" | ||||
|             @click="goToCreateAssignment" | ||||
|         > | ||||
|  |  | |||
		Reference in a new issue
	
	 Joyelle Ndagijimana
						Joyelle Ndagijimana