fix(exams): prevent double-submit from creating duplicate exams
Deploy banu-front / deploy (push) Successful in 2m3s
Deploy banu-front / deploy (push) Successful in 2m3s
The submit button only disabled after Vue re-rendered on mutation pending state, leaving a window where a fast double-click fired onSubmit twice — creating two exam rows, with the losing request usually failing to attach its questions (an "empty" duplicate exam).
This commit is contained in:
@@ -283,8 +283,11 @@ const addExamMutation = useAddAdminExamMutation()
|
|||||||
const updateExamMutation = useUpdateAdminExamMutation()
|
const updateExamMutation = useUpdateAdminExamMutation()
|
||||||
const addQuestionMutation = useAddAdminExamQuestionMutation()
|
const addQuestionMutation = useAddAdminExamQuestionMutation()
|
||||||
|
|
||||||
|
const isSubmitting = ref(false)
|
||||||
|
|
||||||
const submitting = computed(
|
const submitting = computed(
|
||||||
() =>
|
() =>
|
||||||
|
isSubmitting.value ||
|
||||||
addExamMutation.isPending.value ||
|
addExamMutation.isPending.value ||
|
||||||
updateExamMutation.isPending.value ||
|
updateExamMutation.isPending.value ||
|
||||||
addQuestionMutation.isPending.value
|
addQuestionMutation.isPending.value
|
||||||
@@ -298,23 +301,29 @@ const postQuestionsSequentially = async (id, list) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onSubmit = async () => {
|
const onSubmit = async () => {
|
||||||
const { isValid } = await validate(form.value)
|
if (isSubmitting.value) return
|
||||||
const newQuestions = validateLocalQuestions()
|
isSubmitting.value = true
|
||||||
if (!isValid || !newQuestions) return
|
try {
|
||||||
|
const { isValid } = await validate(form.value)
|
||||||
|
const newQuestions = validateLocalQuestions()
|
||||||
|
if (!isValid || !newQuestions) return
|
||||||
|
|
||||||
const examPayload = buildExamPayload(form.value)
|
const examPayload = buildExamPayload(form.value)
|
||||||
let targetExamId = examId.value
|
let targetExamId = examId.value
|
||||||
if (isEditMode.value) {
|
if (isEditMode.value) {
|
||||||
await updateExamMutation.mutateAsync({ id: targetExamId, payload: examPayload })
|
await updateExamMutation.mutateAsync({ id: targetExamId, payload: examPayload })
|
||||||
} else {
|
} else {
|
||||||
const created = await addExamMutation.mutateAsync(examPayload)
|
const created = await addExamMutation.mutateAsync(examPayload)
|
||||||
targetExamId = created?.data?.id ?? created?.id ?? targetExamId
|
targetExamId = created?.data?.id ?? created?.id ?? targetExamId
|
||||||
|
}
|
||||||
|
if (targetExamId && newQuestions.length > 0) {
|
||||||
|
await postQuestionsSequentially(targetExamId, newQuestions)
|
||||||
|
}
|
||||||
|
await queryClient.invalidateQueries({ queryKey: adminExamsKeys.all, refetchType: 'all' })
|
||||||
|
router.push({ name: 'admin-exams' })
|
||||||
|
} finally {
|
||||||
|
isSubmitting.value = false
|
||||||
}
|
}
|
||||||
if (targetExamId && newQuestions.length > 0) {
|
|
||||||
await postQuestionsSequentially(targetExamId, newQuestions)
|
|
||||||
}
|
|
||||||
await queryClient.invalidateQueries({ queryKey: adminExamsKeys.all, refetchType: 'all' })
|
|
||||||
router.push({ name: 'admin-exams' })
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const onCancel = () => router.push({ name: 'admin-exams' })
|
const onCancel = () => router.push({ name: 'admin-exams' })
|
||||||
|
|||||||
Reference in New Issue
Block a user