Skip to content

Commit

Permalink
enhance(apps/frontend-manage): limit group activity creation to cours…
Browse files Browse the repository at this point in the history
…es where group creation is enabled (#4259)
  • Loading branch information
sjschlapbach authored Sep 11, 2024
1 parent 7ed9ffb commit 2cb5d11
Show file tree
Hide file tree
Showing 16 changed files with 165 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export type ElementSelectCourse = {
label: string
value: string
isGamified: boolean
data: { cy: string }
isGroupCreationEnabled: boolean
data?: { cy: string }
}

interface ElementCreationProps {
Expand Down Expand Up @@ -109,10 +110,16 @@ function ElementCreation({
const courseSelection = useMemo(
() =>
dataCourses?.userCourses?.map(
(course: Pick<Course, 'id' | 'name' | 'isGamificationEnabled'>) => ({
(
course: Pick<
Course,
'id' | 'name' | 'isGamificationEnabled' | 'isGroupCreationEnabled'
>
) => ({
label: course.name,
value: course.id,
isGamified: course.isGamificationEnabled,
isGroupCreationEnabled: course.isGroupCreationEnabled,
})
),
[dataCourses]
Expand Down Expand Up @@ -157,36 +164,14 @@ function ElementCreation({
} as PracticeQuiz
}

const { gamifiedCourses, nonGamifiedCourses } = courseSelection?.reduce<{
gamifiedCourses: ElementSelectCourse[]
nonGamifiedCourses: ElementSelectCourse[]
}>(
(acc, course) => {
if (course.isGamified) {
acc.gamifiedCourses.push({
...course,
data: { cy: `select-course-${course.label}` },
})
} else {
acc.nonGamifiedCourses.push({
...course,
data: { cy: `select-course-${course.label}` },
})
}
return acc
},
{ gamifiedCourses: [], nonGamifiedCourses: [] }
) ?? { gamifiedCourses: [], nonGamifiedCourses: [] }

return (
<div className="print-hidden mb-3 flex flex-col justify-center md:h-[18.25rem] md:min-h-[18.25rem]">
<div className="h-full w-full">
{creationMode === WizardMode.LiveQuiz && (
<LiveSessionWizard
title={t('shared.generic.liveQuiz')}
closeWizard={closeWizard}
gamifiedCourses={gamifiedCourses}
nonGamifiedCourses={nonGamifiedCourses}
courses={courseSelection ?? []}
initialValues={
dataLiveSession?.liveSession
? duplicationMode === WizardMode.LiveQuiz
Expand All @@ -206,8 +191,7 @@ function ElementCreation({
<MicroLearningWizard
title={t('shared.generic.microlearning')}
closeWizard={closeWizard}
gamifiedCourses={gamifiedCourses}
nonGamifiedCourses={nonGamifiedCourses}
courses={courseSelection ?? []}
initialValues={
dataMicroLearning?.getSingleMicroLearning
? duplicationMode === WizardMode.Microlearning
Expand All @@ -228,8 +212,7 @@ function ElementCreation({
<PracticeQuizWizard
title={t('shared.generic.practiceQuiz')}
closeWizard={closeWizard}
gamifiedCourses={gamifiedCourses}
nonGamifiedCourses={nonGamifiedCourses}
courses={courseSelection ?? []}
initialValues={
dataPracticeQuiz?.getSinglePracticeQuiz
? duplicationMode === WizardMode.PracticeQuiz
Expand All @@ -250,8 +233,7 @@ function ElementCreation({
<GroupActivityWizard
title={t('shared.generic.groupActivity')}
closeWizard={closeWizard}
gamifiedCourses={gamifiedCourses}
nonGamifiedCourses={nonGamifiedCourses}
courses={courseSelection ?? []}
selection={selection}
resetSelection={resetSelection}
initialValues={
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,17 @@ function GroupActivityInformationStep({
editMode,
formRef,
formData,
continueDisabled,
activeStep,
stepValidity,
validationSchema,
gamifiedCourses,
nonGamifiedCourses,
coursesWithGroups,
coursesWithoutGroups,
setStepValidity,
onNextStep,
closeWizard,
}: GroupActivityWizardStepProps) {
const t = useTranslations()
const noCourse =
gamifiedCourses?.length === 0 && nonGamifiedCourses?.length === 0
const noCoursesWithGroups = coursesWithGroups?.length === 0

return (
<Formik
Expand All @@ -47,7 +45,7 @@ function GroupActivityInformationStep({
<div className="flex h-full w-full flex-col justify-between gap-1">
<div className="flex flex-row">
<div className="w-full md:w-1/2">
{noCourse ? (
{noCoursesWithGroups ? (
<UserNotification
type="error"
message={t('manage.sessionForms.groupActivityNoCourse')}
Expand Down Expand Up @@ -137,7 +135,7 @@ function GroupActivityInformationStep({
stepValidity={stepValidity}
activeStep={activeStep}
lastStep={activeStep === stepValidity.length - 1}
continueDisabled={continueDisabled}
continueDisabled={noCoursesWithGroups}
onCloseWizard={closeWizard}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { faClock, faCrown } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import useGamifiedCourseGrouping from '@lib/hooks/useGamifiedCourseGrouping'
import useGroupsCourseGrouping from '@lib/hooks/useGroupsCourseGrouping'
import {
FormikDateField,
FormikSelectField,
Expand All @@ -23,18 +23,18 @@ function GroupActivitySettingsStep({
activeStep,
stepValidity,
validationSchema,
gamifiedCourses,
nonGamifiedCourses,
coursesWithGroups,
coursesWithoutGroups,
setStepValidity,
onPrevStep,
onNextStep,
closeWizard,
}: GroupActivityWizardStepProps) {
const t = useTranslations()
const groupedCourses = useGamifiedCourseGrouping({
gamifiedCourses: gamifiedCourses ?? [],
nonGamifiedCourses:
nonGamifiedCourses?.map((course) => {
const groupedCourses = useGroupsCourseGrouping({
coursesWithGroups: coursesWithGroups ?? [],
coursesWithoutGroups:
coursesWithoutGroups?.map((course) => {
return { ...course, disabled: true }
}) ?? [],
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
GroupActivity,
ParameterType,
} from '@klicker-uzh/graphql/dist/ops'
import useCoursesGroupsSplit from '@lib/hooks/useCoursesGroupsSplit'
import dayjs from 'dayjs'
import { FormikProps } from 'formik'
import { findIndex } from 'lodash'
Expand Down Expand Up @@ -36,8 +37,8 @@ export interface GroupActivityWizardStepProps {
activeStep: number
stepValidity: boolean[]
validationSchema: any
gamifiedCourses?: ElementSelectCourse[]
nonGamifiedCourses?: ElementSelectCourse[]
coursesWithGroups?: ElementSelectCourse[]
coursesWithoutGroups?: ElementSelectCourse[]
onSubmit?: (newValues: GroupActivityFormValues) => void
setStepValidity: Dispatch<SetStateAction<boolean[]>>
onPrevStep?: (newValues: GroupActivityFormValues) => void
Expand All @@ -57,8 +58,7 @@ const acceptedTypes = [
interface GroupActivityWizardProps {
title: string
closeWizard: () => void
gamifiedCourses: ElementSelectCourse[]
nonGamifiedCourses: ElementSelectCourse[]
courses: ElementSelectCourse[]
selection: Record<number, Element>
resetSelection: () => void
initialValues?: GroupActivity
Expand All @@ -67,8 +67,7 @@ interface GroupActivityWizardProps {
function GroupActivityWizard({
title,
closeWizard,
gamifiedCourses,
nonGamifiedCourses,
courses,
selection,
resetSelection,
initialValues,
Expand All @@ -88,6 +87,10 @@ function GroupActivityWizard({
)
const formRef = useRef<FormikProps<GroupActivityFormValues>>(null)

const { coursesWithGroups, coursesWithoutGroups } = useCoursesGroupsSplit({
courseSelection: courses,
})

const nameValidationSchema = yup.object().shape({
name: yup
.string()
Expand Down Expand Up @@ -317,14 +320,12 @@ function GroupActivityWizard({
editMode={editMode}
formRef={formRef}
formData={formData}
continueDisabled={
gamifiedCourses?.length === 0 && nonGamifiedCourses?.length === 0
}
activeStep={activeStep}
stepValidity={stepValidity}
validationSchema={nameValidationSchema}
gamifiedCourses={gamifiedCourses}
nonGamifiedCourses={nonGamifiedCourses}
coursesWithGroups={coursesWithGroups}
coursesWithoutGroups={coursesWithoutGroups}
continueDisabled={coursesWithGroups?.length === 0}
setStepValidity={setStepValidity}
onNextStep={(newValues: Partial<GroupActivityFormValues>) => {
setFormData((prev) => ({ ...prev, ...newValues }))
Expand Down Expand Up @@ -361,8 +362,8 @@ function GroupActivityWizard({
activeStep={activeStep}
stepValidity={stepValidity}
validationSchema={settingsValidationSchema}
gamifiedCourses={gamifiedCourses}
nonGamifiedCourses={nonGamifiedCourses}
coursesWithGroups={coursesWithGroups}
coursesWithoutGroups={coursesWithoutGroups}
setStepValidity={setStepValidity}
onNextStep={(newValues: Partial<GroupActivityFormValues>) => {
setFormData((prev) => ({ ...prev, ...newValues }))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Session,
StartSessionDocument,
} from '@klicker-uzh/graphql/dist/ops'
import useCoursesGamificationSplit from '@lib/hooks/useCoursesGamificationSplit'
import { Button } from '@uzh-bf/design-system'
import { FormikProps } from 'formik'
import { findIndex } from 'lodash'
Expand Down Expand Up @@ -45,8 +46,7 @@ export interface LiveQuizWizardStepProps {

interface LiveSessionWizardProps {
title: string
gamifiedCourses: ElementSelectCourse[]
nonGamifiedCourses: ElementSelectCourse[]
courses: ElementSelectCourse[]
initialValues?: Partial<Session>
selection: Record<number, Element>
resetSelection: () => void
Expand All @@ -56,8 +56,7 @@ interface LiveSessionWizardProps {

function LiveSessionWizard({
title,
gamifiedCourses,
nonGamifiedCourses,
courses,
initialValues,
selection,
resetSelection,
Expand All @@ -75,6 +74,10 @@ function LiveSessionWizard({
)
const formRef = useRef<FormikProps<LiveSessionFormValues>>(null)

const { gamifiedCourses, nonGamifiedCourses } = useCoursesGamificationSplit({
courseSelection: courses,
})

const nameValidationSchema = yup.object().shape({
name: yup.string().required(t('manage.sessionForms.sessionName')),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ElementType,
MicroLearning,
} from '@klicker-uzh/graphql/dist/ops'
import useCoursesGamificationSplit from '@lib/hooks/useCoursesGamificationSplit'
import dayjs from 'dayjs'
import { FormikProps } from 'formik'
import { findIndex } from 'lodash'
Expand Down Expand Up @@ -55,8 +56,7 @@ const acceptedTypes = [

interface MicroLearningWizardProps {
title: string
gamifiedCourses: ElementSelectCourse[]
nonGamifiedCourses: ElementSelectCourse[]
courses: ElementSelectCourse[]
initialValues?: MicroLearning
selection: Record<number, Element>
resetSelection: () => void
Expand All @@ -66,8 +66,7 @@ interface MicroLearningWizardProps {

function MicroLearningWizard({
title,
gamifiedCourses,
nonGamifiedCourses,
courses,
initialValues,
selection,
resetSelection,
Expand All @@ -88,6 +87,10 @@ function MicroLearningWizard({
)
const formRef = useRef<FormikProps<MicroLearningFormValues>>(null)

const { gamifiedCourses, nonGamifiedCourses } = useCoursesGamificationSplit({
courseSelection: courses,
})

const nameValidationSchema = yup.object().shape({
name: yup.string().required(t('manage.sessionForms.sessionName')),
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
ElementType,
PracticeQuiz,
} from '@klicker-uzh/graphql/dist/ops'
import useCoursesGamificationSplit from '@lib/hooks/useCoursesGamificationSplit'
import dayjs from 'dayjs'
import { FormikProps } from 'formik'
import { findIndex } from 'lodash'
Expand Down Expand Up @@ -56,8 +57,7 @@ const acceptedTypes = [

interface PracticeQuizWizardProps {
title: string
gamifiedCourses: ElementSelectCourse[]
nonGamifiedCourses: ElementSelectCourse[]
courses: ElementSelectCourse[]
closeWizard: () => void
initialValues?: PracticeQuiz
selection: Record<number, Element>
Expand All @@ -68,8 +68,7 @@ interface PracticeQuizWizardProps {

function PracticeQuizWizard({
title,
gamifiedCourses,
nonGamifiedCourses,
courses,
closeWizard,
initialValues,
selection,
Expand All @@ -92,6 +91,10 @@ function PracticeQuizWizard({
)
const formRef = useRef<FormikProps<PracticeQuizFormValues>>(null)

const { gamifiedCourses, nonGamifiedCourses } = useCoursesGamificationSplit({
courseSelection: courses,
})

const nameValidationSchema = yup.object().shape({
name: yup.string().required(t('manage.sessionForms.sessionName')),
})
Expand Down
32 changes: 32 additions & 0 deletions apps/frontend-manage/src/lib/hooks/useCoursesGamificationSplit.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { ElementSelectCourse } from '../../components/sessions/creation/ElementCreation'

function useCoursesGamificationSplit({
courseSelection,
}: {
courseSelection: ElementSelectCourse[]
}) {
return (
courseSelection?.reduce<{
gamifiedCourses: ElementSelectCourse[]
nonGamifiedCourses: ElementSelectCourse[]
}>(
(acc, course) => {
if (course.isGamified) {
acc.gamifiedCourses.push({
...course,
data: { cy: `select-course-${course.label}` },
})
} else {
acc.nonGamifiedCourses.push({
...course,
data: { cy: `select-course-${course.label}` },
})
}
return acc
},
{ gamifiedCourses: [], nonGamifiedCourses: [] }
) ?? { gamifiedCourses: [], nonGamifiedCourses: [] }
)
}

export default useCoursesGamificationSplit
Loading

0 comments on commit 2cb5d11

Please sign in to comment.