Skip to content

Commit

Permalink
enhance(apps/frontend-manage): make sure that live quiz deletion work…
Browse files Browse the repository at this point in the history
…flow is consistent with other deletions (#4433)
  • Loading branch information
sjschlapbach authored Jan 6, 2025
1 parent c350ca5 commit 60c0768
Show file tree
Hide file tree
Showing 15 changed files with 465 additions and 309 deletions.
69 changes: 34 additions & 35 deletions apps/frontend-manage/src/components/courses/LiveQuizElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import EvaluationLinkLiveQuiz from './actions/EvaluationLinkLiveQuiz'
import RunningLiveQuizLink from './actions/RunningLiveQuizLink'
import StartLiveQuizButton from './actions/StartLiveQuizButton'
import getActivityDuplicationAction from './actions/getActivityDuplicationAction'
import DeletionModal from './modals/DeletionModal'
import LiveQuizDeletionModal from './modals/LiveQuizDeletionModal'

export type LiveQuizListElementType = Pick<
LiveQuiz,
Expand Down Expand Up @@ -87,37 +87,40 @@ function LiveQuizElement({ quiz }: { quiz: LiveQuizListElementType }) {
[PublicationStatus.Graded]: null,
}

const [deleteLiveQuiz] = useMutation(DeleteLiveQuizDocument, {
variables: { id: quiz.id },
update(cache, res) {
const data = cache.readQuery({
query: GetSingleCourseDocument,
})
const [deleteLiveQuiz, { loading: deletingLiveQuiz }] = useMutation(
DeleteLiveQuizDocument,
{
variables: { id: quiz.id },
update(cache, res) {
const data = cache.readQuery({
query: GetSingleCourseDocument,
})

if (!data?.course || !res.data?.deleteLiveQuiz) {
return null
}
if (!data?.course || !res.data?.deleteLiveQuiz) {
return null
}

cache.writeQuery({
query: GetSingleCourseDocument,
data: {
course: {
...data.course,
liveQuizzes: data.course.liveQuizzes?.filter(
(quiz) => quiz.id !== res.data!.deleteLiveQuiz!.id
),
cache.writeQuery({
query: GetSingleCourseDocument,
data: {
course: {
...data.course,
liveQuizzes: data.course.liveQuizzes?.filter(
(quiz) => quiz.id !== res.data!.deleteLiveQuiz!.id
),
},
},
})
},
optimisticResponse: {
deleteLiveQuiz: {
__typename: 'LiveQuiz',
id: quiz.id,
},
})
},
optimisticResponse: {
deleteLiveQuiz: {
__typename: 'LiveQuiz',
id: quiz.id,
},
},
refetchQueries: [GetSingleCourseDocument],
})
refetchQueries: [GetSingleCourseDocument],
}
)

const href = `${process.env.NEXT_PUBLIC_PWA_URL}/${dataUser?.userProfile?.shortname}`

Expand Down Expand Up @@ -285,16 +288,12 @@ function LiveQuizElement({ quiz }: { quiz: LiveQuizListElementType }) {
</div>

<CopyConfirmationToast open={copyToast} setOpen={setCopyToast} />
<DeletionModal
title={t('manage.liveQuizzes.deleteLiveQuiz')}
description={t('manage.liveQuizzes.confirmLiveQuizDeletion')}
elementName={quiz.name}
message={t('manage.liveQuizzes.liveQuizDeletionHint')}
deleteElement={deleteLiveQuiz}
<LiveQuizDeletionModal
quizId={quiz.id}
open={deletionModal}
setOpen={setDeletionModal}
primaryData={{ cy: 'confirm-delete-live-quiz' }}
secondaryData={{ cy: 'cancel-delete-live-quiz' }}
onDelete={deleteLiveQuiz}
deleting={deletingLiveQuiz}
/>
</div>

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
import { useQuery } from '@apollo/client'
import { GetLiveQuizSummaryDocument } from '@klicker-uzh/graphql/dist/ops'
import { useTranslations } from 'next-intl'
import { useEffect, useState } from 'react'
import ConfirmationItem from '../../common/ConfirmationItem'
import ActivityConfirmationModal from './ActivityConfirmationModal'

interface LiveQuizDeletionModalProps {
open: boolean
setOpen: (open: boolean) => void
quizId: string
onDelete: () => Promise<any>
deleting: boolean
}

function LiveQuizDeletionModal({
open,
setOpen,
quizId,
onDelete,
deleting,
}: LiveQuizDeletionModalProps) {
const t = useTranslations()
const {
data: summaryData,
loading: summaryLoading,
refetch,
} = useQuery(GetLiveQuizSummaryDocument, {
variables: { quizId },
skip: !open,
})

const [confirmations, setConfirmations] = useState({
deleteResponses: false,
deleteLeaderboardEntries: false,
deleteFeedbacks: false, // Q&A channel
deleteConfusionFeedbacks: false, // Confusion channel
})

// manually re-trigger the query when the modal is opened
useEffect(() => {
if (open) {
refetch()
}
}, [open])

useEffect(() => {
if (summaryData?.getLiveQuizSummary) {
setConfirmations({
deleteResponses: summaryData?.getLiveQuizSummary.numOfResponses === 0,
deleteLeaderboardEntries:
summaryData.getLiveQuizSummary.numOfLeaderboardEntries === 0,
deleteFeedbacks: summaryData.getLiveQuizSummary.numOfFeedbacks === 0,
deleteConfusionFeedbacks:
summaryData.getLiveQuizSummary.numOfConfusionFeedbacks === 0,
})
}
}, [summaryData?.getLiveQuizSummary])

if (!summaryData?.getLiveQuizSummary) return null

const summary = summaryData.getLiveQuizSummary

return (
<ActivityConfirmationModal
open={open}
setOpen={setOpen}
title={t('manage.liveQuizzes.deleteLiveQuiz')}
message={t('manage.liveQuizzes.deleteLiveQuizMessage')}
onSubmit={async () => await onDelete()}
submitting={deleting}
confirmations={confirmations}
confirmationsInitializing={summaryLoading}
confirmationType="delete"
>
<div className="flex flex-col gap-2">
<ConfirmationItem
label={
summary.numOfResponses === 0
? t('manage.liveQuizzes.noResponsesToDelete')
: t('manage.liveQuizzes.deleteResponses', {
number: summary.numOfResponses,
})
}
onClick={() => {
setConfirmations((prev) => ({
...prev,
deleteResponses: true,
}))
}}
confirmed={confirmations.deleteResponses}
notApplicable={summary.numOfResponses === 0}
confirmationType="delete"
data={{ cy: 'confirm-deletion-responses' }}
/>
<ConfirmationItem
label={
summary.numOfFeedbacks === 0
? t('manage.liveQuizzes.noFeedbacksToDelete')
: t('manage.liveQuizzes.deleteFeedbacks', {
number: summary.numOfFeedbacks,
})
}
onClick={() => {
setConfirmations((prev) => ({
...prev,
deleteFeedbacks: true,
}))
}}
confirmed={confirmations.deleteFeedbacks}
notApplicable={summary.numOfFeedbacks === 0}
confirmationType="delete"
data={{ cy: 'confirm-deletion-qa-feedbacks' }}
/>
<ConfirmationItem
label={
summary.numOfConfusionFeedbacks === 0
? t('manage.liveQuizzes.noConfusionFeedbacksToDelete')
: t('manage.liveQuizzes.deleteConfusionFeedbacks', {
number: summary.numOfConfusionFeedbacks,
})
}
onClick={() => {
setConfirmations((prev) => ({
...prev,
deleteConfusionFeedbacks: true,
}))
}}
confirmed={confirmations.deleteConfusionFeedbacks}
notApplicable={summary.numOfConfusionFeedbacks === 0}
confirmationType="delete"
data={{ cy: 'confirm-deletion-confusion-feedbacks' }}
/>
</div>
</ActivityConfirmationModal>
)
}

export default LiveQuizDeletionModal
Loading

0 comments on commit 60c0768

Please sign in to comment.