fix: UI-imperfecties & diverse bugs omtrent het verwijderen en editeren van leerpaden opgelost
This commit is contained in:
		
							parent
							
								
									9400b7f33c
								
							
						
					
					
						commit
						9a58126c7c
					
				
					 6 changed files with 126 additions and 28 deletions
				
			
		|  | @ -0,0 +1,61 @@ | |||
| <script setup lang="ts"> | ||||
|     import { useI18n } from 'vue-i18n'; | ||||
| 
 | ||||
|     const props = defineProps<{ | ||||
|         text: string, | ||||
|         prependIcon?: string, | ||||
|         appendIcon?: string, | ||||
|         confirmQueryText: string, | ||||
|         variant?: "flat" | "text" | "elevated" | "tonal" | "outlined" | "plain" | undefined, | ||||
|         color?: string, | ||||
|         disabled?: boolean | ||||
|     }>(); | ||||
| 
 | ||||
|     const emit = defineEmits<{ (e: 'confirm'): void }>() | ||||
| 
 | ||||
|     const { t } = useI18n(); | ||||
| 
 | ||||
|     function confirm(): void { | ||||
|         emit("confirm"); | ||||
|     } | ||||
| </script> | ||||
| 
 | ||||
| <template> | ||||
|     <v-dialog max-width="500"> | ||||
|   <template v-slot:activator="{ props: activatorProps }"> | ||||
|     <v-btn | ||||
|       v-bind="activatorProps" | ||||
|       :text="props.text" | ||||
|       :prependIcon="props.prependIcon" | ||||
|       :appendIcon="props.appendIcon" | ||||
|       :variant="props.variant" | ||||
|       :color="color" | ||||
|       :disabled="props.disabled" | ||||
|     ></v-btn> | ||||
|   </template> | ||||
| 
 | ||||
|   <template v-slot:default="{ isActive }"> | ||||
|     <v-card :title="t('confirmDialogTitle')"> | ||||
|       <v-card-text> | ||||
|         {{ props.confirmQueryText }} | ||||
|       </v-card-text> | ||||
| 
 | ||||
|       <v-card-actions> | ||||
|         <v-spacer></v-spacer> | ||||
| 
 | ||||
|         <v-btn | ||||
|           :text="t('yes')" | ||||
|           @click="confirm(); isActive.value = false" | ||||
|         ></v-btn> | ||||
|         <v-btn | ||||
|           :text="t('cancel')" | ||||
|           @click="isActive.value = false" | ||||
|         ></v-btn> | ||||
|       </v-card-actions> | ||||
|     </v-card> | ||||
|   </template> | ||||
| </v-dialog> | ||||
| </template> | ||||
| 
 | ||||
| <style scoped> | ||||
| </style> | ||||
|  | @ -139,5 +139,10 @@ | |||
|     "editLearningPath": "Edit learning path", | ||||
|     "newLearningPath": "Create a new learning path", | ||||
|     "saveChanges": "Save changes", | ||||
|     "newLearningObject": "Upload learning object" | ||||
|     "newLearningObject": "Upload learning object", | ||||
|     "confirmDialogTitle": "Please confirm", | ||||
|     "learningPathDeleteQuery": "Are you sure you want to delete this learning path?", | ||||
|     "learningObjectDeleteQuery": "Are you sure you want to delete this learning object?", | ||||
|     "learningPathCantModifyId": "The HRUID or language of a learning path cannot be modified.", | ||||
|     "error": "Error" | ||||
| } | ||||
|  |  | |||
|  | @ -2,6 +2,7 @@ | |||
|     import type { LearningObject } from '@/data-objects/learning-objects/learning-object'; | ||||
|     import UsingQueryResult from '@/components/UsingQueryResult.vue'; | ||||
|     import LearningObjectContentView from '../../learning-paths/learning-object/content/LearningObjectContentView.vue'; | ||||
|     import ButtonWithConfirmation from '@/components/ButtonWithConfirmation.vue'; | ||||
|     import { useDeleteLearningObjectMutation, useLearningObjectHTMLQuery } from '@/queries/learning-objects'; | ||||
|     import { useI18n } from 'vue-i18n'; | ||||
| 
 | ||||
|  | @ -41,7 +42,13 @@ | |||
|             </using-query-result> | ||||
|         </template> | ||||
|         <template v-slot:actions> | ||||
|             <v-btn text="Delete" @click="deleteLearningObject()"></v-btn> | ||||
|             <button-with-confirmation | ||||
|                 @confirm="deleteLearningObject" | ||||
|                 prepend-icon="mdi mdi-delete" | ||||
|                 color="red" | ||||
|                 :text="t('delete')" | ||||
|                 :confirmQueryText="t('learningObjectDeleteQuery')" | ||||
|             /> | ||||
|         </template> | ||||
|     </v-card> | ||||
| </template> | ||||
|  |  | |||
|  | @ -2,10 +2,12 @@ | |||
|     import { useI18n } from 'vue-i18n'; | ||||
|     import { computed, ref, watch, type Ref } from 'vue'; | ||||
|     import JsonEditorVue from 'json-editor-vue' | ||||
|     import ButtonWithConfirmation from '@/components/ButtonWithConfirmation.vue' | ||||
|     import { useDeleteLearningPathMutation, usePostLearningPathMutation, usePutLearningPathMutation } from '@/queries/learning-paths'; | ||||
|     import { Language } from '@/data-objects/language'; | ||||
|     import type { LearningPath } from '@dwengo-1/common/interfaces/learning-content'; | ||||
|     import type { AxiosError } from 'axios'; | ||||
| import { parse } from 'uuid'; | ||||
| 
 | ||||
|     const { t } = useI18n(); | ||||
| 
 | ||||
|  | @ -63,7 +65,7 @@ | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function deleteLearningObject(): void { | ||||
|     function deleteLearningPath(): void { | ||||
|         if (props.selectedLearningPath) { | ||||
|             mutate({ | ||||
|                 hruid: props.selectedLearningPath.hruid, | ||||
|  | @ -72,8 +74,28 @@ | |||
|         } | ||||
|     } | ||||
| 
 | ||||
|     function extractErrorMessage(error: AxiosError | null): string | undefined { | ||||
|         return (error?.response?.data as {error: string}).error ?? error?.message; | ||||
|     function extractErrorMessage(error: AxiosError): string { | ||||
|         return (error.response?.data as {error: string}).error ?? error.message; | ||||
|     } | ||||
| 
 | ||||
|     const isIdModified = computed(() => | ||||
|         props.selectedLearningPath !== undefined && ( | ||||
|             props.selectedLearningPath.hruid !== parsedLearningPath.value.hruid | ||||
|             || props.selectedLearningPath.language !== parsedLearningPath.value.language | ||||
|         ) | ||||
|     ); | ||||
| 
 | ||||
|     function getErrorMessage(): string | null { | ||||
|         if (postError.value) { | ||||
|             return t(extractErrorMessage(postError.value)); | ||||
|         } else if (putError.value) { | ||||
|             return t(extractErrorMessage(putError.value)); | ||||
|         } else if (deleteError.value) { | ||||
|             return t(extractErrorMessage(deleteError.value)); | ||||
|         } else if (isIdModified.value) { | ||||
|             return t('learningPathCantModifyId'); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
| </script> | ||||
| 
 | ||||
|  | @ -84,22 +106,34 @@ | |||
|         <template v-slot:text> | ||||
|             <json-editor-vue v-model="learningPath"></json-editor-vue> | ||||
|             <v-alert | ||||
|                  v-if="postError || putError || deleteError" | ||||
|                  v-if="postError || putError || deleteError || isIdModified" | ||||
|                  icon="mdi mdi-alert-circle" | ||||
|                  type="error" | ||||
|                  :title="t('error')" | ||||
|                  :text="t(extractErrorMessage(postError) || extractErrorMessage(putError) || extractErrorMessage(deleteError)!)" | ||||
|                  :text="getErrorMessage()!" | ||||
|             ></v-alert> | ||||
|         </template> | ||||
|         <template v-slot:actions> | ||||
|             <v-btn @click="uploadLearningPath" :loading="isPostPending || isPutPending" :disabled="parsedLearningPath.hruid === DEFAULT_LEARNING_PATH.hruid"> | ||||
|             <v-btn | ||||
|                 @click="uploadLearningPath" | ||||
|                 prependIcon="mdi mdi-check" | ||||
|                 :loading="isPostPending || isPutPending" | ||||
|                 :disabled="parsedLearningPath.hruid === DEFAULT_LEARNING_PATH.hruid || isIdModified" | ||||
|             > | ||||
|                 {{ props.selectedLearningPath ? t('saveChanges') : t('create') }} | ||||
|             </v-btn> | ||||
|             <v-btn @click="deleteLearningObject" :disabled="!props.selectedLearningPath"> | ||||
|                 {{ t('delete') }} | ||||
|             </v-btn> | ||||
|             <button-with-confirmation | ||||
|                 @confirm="deleteLearningPath" | ||||
|                 :disabled="!props.selectedLearningPath" | ||||
|                 :text="t('delete')" | ||||
|                 color="red" | ||||
|                 prependIcon="mdi mdi-delete" | ||||
|                 :confirmQueryText="t('learningPathDeleteQuery')" | ||||
|             /> | ||||
|             <v-btn | ||||
|                 :href="`/learningPath/${props.selectedLearningPath?.hruid}/${props.selectedLearningPath?.language}/start`" | ||||
|                 target="_blank" | ||||
|                 prepend-icon="mdi mdi-open-in-new" | ||||
|                 :disabled="!props.selectedLearningPath" | ||||
|             > | ||||
|                 {{ t('open') }} | ||||
|  |  | |||
		Reference in a new issue
	
	 Gerald Schmittinger
						Gerald Schmittinger