feat(exams): exam staff & additional schools
This commit is contained in:
parent
d43b7caa43
commit
94436ee0e1
@ -1832,6 +1832,11 @@ ExamRoomDescription: Beschreibung
|
|||||||
ExamTimeTip: Nur zur Information der Studierenden, die tatsächliche Zeitangabe erfolgt pro Prüfungstermin/Raum
|
ExamTimeTip: Nur zur Information der Studierenden, die tatsächliche Zeitangabe erfolgt pro Prüfungstermin/Raum
|
||||||
ExamRoomAssigned: Zugeteilt
|
ExamRoomAssigned: Zugeteilt
|
||||||
ExamRoomRegistered: Anmeldung
|
ExamRoomRegistered: Anmeldung
|
||||||
|
ExamStaff: Prüfer/Verantwortliche Hochschullehrer
|
||||||
|
ExamStaffTip: Geben Sie bitte in jedem Fall einen Namen an, der den Prüfer/Veranstalter/Verantwortlichen Hochschullehrer eindeutig identifiziert! Sollte der Name des Prüfers allein womöglich nicht eindeutig sein, so geben Sie bitte eindeutig identifizierende Zusatzinfos, wie beispielsweise den Lehrstuhl bzw. die LFE o.Ä., an.
|
||||||
|
ExamStaffRequired: „Prüfer/Verantwortilche Hochschullehrer” muss angegeben werden
|
||||||
|
ExamExamOfficeSchools: Zusätzliche Institute
|
||||||
|
ExamExamOfficeSchoolsTip: Prüfungsbeauftragte von Instituten, die Sie hier angeben, erhalten im System (zusätzlich zum primären Institut des zugehörigen Kurses) volle Einsicht in sämtliche für diese Prüfung hinterlegten Leistungen, unabhängig von den Studiendaten der Teilnehmer.
|
||||||
|
|
||||||
ExamOccurrenceStart: Prüfungsbeginn
|
ExamOccurrenceStart: Prüfungsbeginn
|
||||||
|
|
||||||
@ -1841,6 +1846,7 @@ ExamFormAutomaticFunctions: Automatische Funktionen
|
|||||||
ExamFormCorrection: Korrektur
|
ExamFormCorrection: Korrektur
|
||||||
ExamFormParts: Teile
|
ExamFormParts: Teile
|
||||||
ExamFormMode: Ausgestaltung der Prüfung
|
ExamFormMode: Ausgestaltung der Prüfung
|
||||||
|
ExamFormGrades: Prüfungsleistungen
|
||||||
|
|
||||||
ExamModeFormNone: Keine Angabe
|
ExamModeFormNone: Keine Angabe
|
||||||
ExamModeFormCustom: Benutzerdefiniert
|
ExamModeFormCustom: Benutzerdefiniert
|
||||||
|
|||||||
@ -1831,6 +1831,11 @@ ExamRoomDescription: Description
|
|||||||
ExamTimeTip: Only for informational purposes. The actual times are set for each occurrence/room
|
ExamTimeTip: Only for informational purposes. The actual times are set for each occurrence/room
|
||||||
ExamRoomAssigned: Assigned
|
ExamRoomAssigned: Assigned
|
||||||
ExamRoomRegistered: Registration
|
ExamRoomRegistered: Registration
|
||||||
|
ExamStaff: Examiner/Responsible university teacher
|
||||||
|
ExamStaffTip: Please always specify a name that uniquely identifies the examiner/organiser/repsonsible university teacher! If there is a possibility that the name alone is ambiguous please also specify some additional information e.g. the professorial chair or the educational and research unit.
|
||||||
|
ExamStaffRequired: “Examiner/Responsible university teacher” must be specified
|
||||||
|
ExamExamOfficeSchools: Additional departments
|
||||||
|
ExamExamOfficeSchoolsTip: Exam offices of departments you specify here will also have full access to all results for this exam disregarding the individual participants' features of study.
|
||||||
|
|
||||||
ExamOccurrenceStart: Exam starts
|
ExamOccurrenceStart: Exam starts
|
||||||
|
|
||||||
@ -1840,6 +1845,7 @@ ExamFormAutomaticFunctions: Automatic functions
|
|||||||
ExamFormCorrection: Correction
|
ExamFormCorrection: Correction
|
||||||
ExamFormParts: Exam parts
|
ExamFormParts: Exam parts
|
||||||
ExamFormMode: Exam design
|
ExamFormMode: Exam design
|
||||||
|
ExamFormGrades: Exam achievements
|
||||||
|
|
||||||
ExamModeFormNone: Not specified
|
ExamModeFormNone: Not specified
|
||||||
ExamModeFormCustom: Custom
|
ExamModeFormCustom: Custom
|
||||||
@ -2838,4 +2844,4 @@ SystemExamOffice: Exam office
|
|||||||
SystemFaculty: Faculty member
|
SystemFaculty: Faculty member
|
||||||
|
|
||||||
ChangelogItemFeature: Feature
|
ChangelogItemFeature: Feature
|
||||||
ChangelogItemBugfix: Bugfix
|
ChangelogItemBugfix: Bugfix
|
||||||
|
|||||||
@ -18,6 +18,7 @@ Exam
|
|||||||
gradingMode ExamGradingMode
|
gradingMode ExamGradingMode
|
||||||
description Html Maybe
|
description Html Maybe
|
||||||
examMode ExamMode
|
examMode ExamMode
|
||||||
|
staff Text Maybe
|
||||||
UniqueExam course name
|
UniqueExam course name
|
||||||
ExamPart
|
ExamPart
|
||||||
exam ExamId
|
exam ExamId
|
||||||
@ -67,4 +68,8 @@ ExamCorrector
|
|||||||
ExamPartCorrector
|
ExamPartCorrector
|
||||||
part ExamPartId
|
part ExamPartId
|
||||||
corrector ExamCorrectorId
|
corrector ExamCorrectorId
|
||||||
UniqueExamPartCorrector part corrector
|
UniqueExamPartCorrector part corrector
|
||||||
|
ExamOfficeSchool
|
||||||
|
school SchoolId
|
||||||
|
exam ExamId
|
||||||
|
UniqueExamOfficeSchool exam school
|
||||||
@ -49,6 +49,7 @@ postEEditR tid ssh csh examn = do
|
|||||||
, examGradingMode = efGradingMode
|
, examGradingMode = efGradingMode
|
||||||
, examDescription = efDescription
|
, examDescription = efDescription
|
||||||
, examExamMode = efExamMode
|
, examExamMode = efExamMode
|
||||||
|
, examStaff = efStaff
|
||||||
}
|
}
|
||||||
|
|
||||||
when (is _Nothing insertRes) $ do
|
when (is _Nothing insertRes) $ do
|
||||||
@ -80,7 +81,6 @@ postEEditR tid ssh csh examn = do
|
|||||||
, examOccurrenceDescription = eofDescription
|
, examOccurrenceDescription = eofDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pIds <- fmap catMaybes . forM (Set.toList efExamParts) $ traverse decrypt . epfId
|
pIds <- fmap catMaybes . forM (Set.toList efExamParts) $ traverse decrypt . epfId
|
||||||
deleteWhere [ ExamPartExam ==. eId, ExamPartId /<-. pIds ]
|
deleteWhere [ ExamPartExam ==. eId, ExamPartId /<-. pIds ]
|
||||||
forM_ (Set.toList efExamParts) $ \case
|
forM_ (Set.toList efExamParts) $ \case
|
||||||
@ -105,6 +105,8 @@ postEEditR tid ssh csh examn = do
|
|||||||
, examPartWeight = epfWeight
|
, examPartWeight = epfWeight
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deleteWhere [ ExamOfficeSchoolExam ==. eId ]
|
||||||
|
insertMany_ . map (flip ExamOfficeSchool eId) $ Set.toList efOfficeSchools
|
||||||
|
|
||||||
let (invites, adds) = partitionEithers $ Set.toList efCorrectors
|
let (invites, adds) = partitionEithers $ Set.toList efCorrectors
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,6 @@ import Text.Blaze.Html.Renderer.String (renderHtml)
|
|||||||
data ExamForm = ExamForm
|
data ExamForm = ExamForm
|
||||||
{ efName :: ExamName
|
{ efName :: ExamName
|
||||||
, efDescription :: Maybe Html
|
, efDescription :: Maybe Html
|
||||||
, efGradingMode :: ExamGradingMode
|
|
||||||
, efStart :: Maybe UTCTime
|
, efStart :: Maybe UTCTime
|
||||||
, efEnd :: Maybe UTCTime
|
, efEnd :: Maybe UTCTime
|
||||||
, efVisibleFrom :: Maybe UTCTime
|
, efVisibleFrom :: Maybe UTCTime
|
||||||
@ -43,6 +42,9 @@ data ExamForm = ExamForm
|
|||||||
, efBonusRule :: Maybe ExamBonusRule
|
, efBonusRule :: Maybe ExamBonusRule
|
||||||
, efOccurrenceRule :: ExamOccurrenceRule
|
, efOccurrenceRule :: ExamOccurrenceRule
|
||||||
, efExamMode :: ExamMode
|
, efExamMode :: ExamMode
|
||||||
|
, efGradingMode :: ExamGradingMode
|
||||||
|
, efOfficeSchools :: Set SchoolId
|
||||||
|
, efStaff :: Maybe Text
|
||||||
, efCorrectors :: Set (Either UserEmail UserId)
|
, efCorrectors :: Set (Either UserEmail UserId)
|
||||||
, efExamParts :: Set ExamPartForm
|
, efExamParts :: Set ExamPartForm
|
||||||
}
|
}
|
||||||
@ -103,7 +105,6 @@ examForm template html = do
|
|||||||
flip (renderAForm FormStandard) html $ ExamForm
|
flip (renderAForm FormStandard) html $ ExamForm
|
||||||
<$> areq ciField (fslpI MsgExamName (mr MsgExamName) & setTooltip MsgExamNameTip) (efName <$> template)
|
<$> areq ciField (fslpI MsgExamName (mr MsgExamName) & setTooltip MsgExamNameTip) (efName <$> template)
|
||||||
<*> aopt htmlField (fslI MsgExamDescription) (efDescription <$> template)
|
<*> aopt htmlField (fslI MsgExamDescription) (efDescription <$> template)
|
||||||
<*> apopt (selectField optionsFinite) (fslI MsgExamGradingMode & setTooltip MsgExamGradingModeTip) (efGradingMode <$> template <|> Just ExamGradingMixed)
|
|
||||||
<* aformSection MsgExamFormTimes
|
<* aformSection MsgExamFormTimes
|
||||||
<*> aopt utcTimeField (fslpI MsgExamStart (mr MsgDate) & setTooltip MsgExamTimeTip) (efStart <$> template)
|
<*> aopt utcTimeField (fslpI MsgExamStart (mr MsgDate) & setTooltip MsgExamTimeTip) (efStart <$> template)
|
||||||
<*> aopt utcTimeField (fslpI MsgExamEnd (mr MsgDate) & setTooltip MsgExamTimeTip) (efEnd <$> template)
|
<*> aopt utcTimeField (fslpI MsgExamEnd (mr MsgDate) & setTooltip MsgExamTimeTip) (efEnd <$> template)
|
||||||
@ -122,11 +123,39 @@ examForm template html = do
|
|||||||
<*> examOccurrenceRuleForm (efOccurrenceRule <$> template)
|
<*> examOccurrenceRuleForm (efOccurrenceRule <$> template)
|
||||||
<* aformSection MsgExamFormMode
|
<* aformSection MsgExamFormMode
|
||||||
<*> examModeForm (efExamMode <$> template)
|
<*> examModeForm (efExamMode <$> template)
|
||||||
|
<* aformSection MsgExamFormGrades
|
||||||
|
<*> apopt (selectField optionsFinite) (fslI MsgExamGradingMode & setTooltip MsgExamGradingModeTip) (efGradingMode <$> template <|> Just ExamGradingMixed)
|
||||||
|
<*> officeSchoolsForm (efOfficeSchools <$> template)
|
||||||
|
<*> apreq' (textField & cfStrip) (fslpI MsgExamStaff (mr MsgExamStaff) & setTooltip MsgExamStaffTip) (efStaff <$> template)
|
||||||
<* aformSection MsgExamFormCorrection
|
<* aformSection MsgExamFormCorrection
|
||||||
<*> examCorrectorsForm (efCorrectors <$> template)
|
<*> examCorrectorsForm (efCorrectors <$> template)
|
||||||
<* aformSection MsgExamFormParts
|
<* aformSection MsgExamFormParts
|
||||||
<*> examPartsForm (efExamParts <$> template)
|
<*> examPartsForm (efExamParts <$> template)
|
||||||
|
|
||||||
|
officeSchoolsForm :: Maybe (Set SchoolId) -> AForm Handler (Set SchoolId)
|
||||||
|
officeSchoolsForm mPrev = wFormToAForm $ do
|
||||||
|
currentRoute <- fromMaybe (error "officeSchoolsForm called from 404-handler") <$> getCurrentRoute
|
||||||
|
|
||||||
|
let
|
||||||
|
miButtonAction' :: forall p. PathPiece p => p -> Maybe (SomeRoute UniWorX)
|
||||||
|
miButtonAction' frag = Just . SomeRoute $ currentRoute :#: frag
|
||||||
|
|
||||||
|
miAdd' :: (Text -> Text) -> FieldView UniWorX -> Form ([SchoolId] -> FormResult [SchoolId])
|
||||||
|
miAdd' nudge submitView csrf = do
|
||||||
|
(schoolRes, addView) <- mpopt schoolField ("" & addName (nudge "school")) Nothing
|
||||||
|
let schoolRes' = schoolRes <&> \newDat oldDat -> FormSuccess (guardOn (newDat `notElem` oldDat) newDat)
|
||||||
|
return (schoolRes', $(widgetFile "exam/schoolMassInput/add"))
|
||||||
|
|
||||||
|
miCell' :: SchoolId -> Widget
|
||||||
|
miCell' ssh = do
|
||||||
|
School{..} <- liftHandler . runDB $ getJust ssh
|
||||||
|
$(widgetFile "exam/schoolMassInput/cell")
|
||||||
|
|
||||||
|
miLayout' :: MassInputLayout ListLength SchoolId ()
|
||||||
|
miLayout' lLength _ cellWdgts delButtons addWdgts = $(widgetFile "exam/schoolMassInput/layout")
|
||||||
|
|
||||||
|
fmap Set.fromList <$> massInputAccumW miAdd' miCell' miButtonAction' miLayout' ("exam-schools" :: Text) (fslI MsgExamExamOfficeSchools & setTooltip MsgExamExamOfficeSchoolsTip) False (Set.toList <$> mPrev)
|
||||||
|
|
||||||
examCorrectorsForm :: Maybe (Set (Either UserEmail UserId)) -> AForm Handler (Set (Either UserEmail UserId))
|
examCorrectorsForm :: Maybe (Set (Either UserEmail UserId)) -> AForm Handler (Set (Either UserEmail UserId))
|
||||||
examCorrectorsForm mPrev = wFormToAForm $ do
|
examCorrectorsForm mPrev = wFormToAForm $ do
|
||||||
MsgRenderer mr <- getMsgRenderer
|
MsgRenderer mr <- getMsgRenderer
|
||||||
@ -261,6 +290,7 @@ examFormTemplate (Entity eId Exam{..}) = do
|
|||||||
occurrences <- selectList [ ExamOccurrenceExam ==. eId ] []
|
occurrences <- selectList [ ExamOccurrenceExam ==. eId ] []
|
||||||
correctors <- selectList [ ExamCorrectorExam ==. eId ] []
|
correctors <- selectList [ ExamCorrectorExam ==. eId ] []
|
||||||
invitations <- Map.keysSet <$> sourceInvitationsF @ExamCorrector eId
|
invitations <- Map.keysSet <$> sourceInvitationsF @ExamCorrector eId
|
||||||
|
extraSchools <- selectList [ ExamOfficeSchoolExam ==. eId ] []
|
||||||
|
|
||||||
examParts' <- forM examParts $ \(Entity pid part) -> (,) <$> encrypt pid <*> pure part
|
examParts' <- forM examParts $ \(Entity pid part) -> (,) <$> encrypt pid <*> pure part
|
||||||
occurrences' <- forM occurrences $ \(Entity oid occ) -> (,) <$> encrypt oid <*> pure occ
|
occurrences' <- forM occurrences $ \(Entity oid occ) -> (,) <$> encrypt oid <*> pure occ
|
||||||
@ -308,13 +338,15 @@ examFormTemplate (Entity eId Exam{..}) = do
|
|||||||
return examCorrectorUser
|
return examCorrectorUser
|
||||||
]
|
]
|
||||||
, efExamMode = examExamMode
|
, efExamMode = examExamMode
|
||||||
|
, efOfficeSchools = Set.fromList $ examOfficeSchoolSchool . entityVal <$> extraSchools
|
||||||
|
, efStaff = examStaff
|
||||||
}
|
}
|
||||||
|
|
||||||
examTemplate :: CourseId -> DB (Maybe ExamForm)
|
examTemplate :: CourseId -> DB (Maybe ExamForm)
|
||||||
examTemplate cid = runMaybeT $ do
|
examTemplate cid = runMaybeT $ do
|
||||||
newCourse <- MaybeT $ get cid
|
newCourse <- MaybeT $ get cid
|
||||||
|
|
||||||
[(Entity _ oldCourse, Entity _ oldExam)] <- lift . E.select . E.from $ \(course `E.InnerJoin` exam) -> do
|
[(Entity _ oldCourse, Entity oldExamId oldExam)] <- lift . E.select . E.from $ \(course `E.InnerJoin` exam) -> do
|
||||||
E.on $ course E.^. CourseId E.==. exam E.^. ExamCourse
|
E.on $ course E.^. CourseId E.==. exam E.^. ExamCourse
|
||||||
E.where_ $ ( course E.^. CourseShorthand E.==. E.val (courseShorthand newCourse)
|
E.where_ $ ( course E.^. CourseShorthand E.==. E.val (courseShorthand newCourse)
|
||||||
E.||. course E.^. CourseName E.==. E.val (courseName newCourse)
|
E.||. course E.^. CourseName E.==. E.val (courseName newCourse)
|
||||||
@ -327,6 +359,8 @@ examTemplate cid = runMaybeT $ do
|
|||||||
E.limit 1
|
E.limit 1
|
||||||
E.orderBy [ E.desc $ course E.^. CourseTerm, E.asc $ exam E.^. ExamVisibleFrom ]
|
E.orderBy [ E.desc $ course E.^. CourseTerm, E.asc $ exam E.^. ExamVisibleFrom ]
|
||||||
return (course, exam)
|
return (course, exam)
|
||||||
|
|
||||||
|
extraSchools <- lift $ selectList [ ExamOfficeSchoolExam ==. oldExamId ] []
|
||||||
|
|
||||||
oldTerm <- MaybeT . get $ courseTerm oldCourse
|
oldTerm <- MaybeT . get $ courseTerm oldCourse
|
||||||
newTerm <- MaybeT . get $ courseTerm newCourse
|
newTerm <- MaybeT . get $ courseTerm newCourse
|
||||||
@ -354,6 +388,8 @@ examTemplate cid = runMaybeT $ do
|
|||||||
, efExamParts = Set.empty
|
, efExamParts = Set.empty
|
||||||
, efCorrectors = Set.empty
|
, efCorrectors = Set.empty
|
||||||
, efExamMode = examExamMode oldExam
|
, efExamMode = examExamMode oldExam
|
||||||
|
, efStaff = examStaff oldExam
|
||||||
|
, efOfficeSchools = Set.fromList $ examOfficeSchoolSchool . entityVal <$> extraSchools
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -431,3 +467,6 @@ validateExam cId oldExam = do
|
|||||||
]
|
]
|
||||||
|
|
||||||
warnValidation MsgExamModeSchoolDiscouraged . not $ evalExamModeDNF schoolExamDiscouragedModes efExamMode
|
warnValidation MsgExamModeSchoolDiscouraged . not $ evalExamModeDNF schoolExamDiscouragedModes efExamMode
|
||||||
|
|
||||||
|
unless (has (_Just . _examStaff . _Nothing) oldExam) $
|
||||||
|
guardValidation MsgExamStaffRequired $ isn't _Nothing efStaff
|
||||||
|
|||||||
@ -50,6 +50,7 @@ postCExamNewR tid ssh csh = do
|
|||||||
, examPublicStatistics = efPublicStatistics
|
, examPublicStatistics = efPublicStatistics
|
||||||
, examDescription = efDescription
|
, examDescription = efDescription
|
||||||
, examExamMode = efExamMode
|
, examExamMode = efExamMode
|
||||||
|
, examStaff = efStaff
|
||||||
}
|
}
|
||||||
whenIsJust insertRes $ \examid -> do
|
whenIsJust insertRes $ \examid -> do
|
||||||
insertMany_
|
insertMany_
|
||||||
@ -74,6 +75,8 @@ postCExamNewR tid ssh csh = do
|
|||||||
examOccurrenceDescription = eofDescription
|
examOccurrenceDescription = eofDescription
|
||||||
]
|
]
|
||||||
|
|
||||||
|
insertMany_ . map (flip ExamOfficeSchool examid) $ Set.toList efOfficeSchools
|
||||||
|
|
||||||
let (invites, adds) = partitionEithers $ Set.toList efCorrectors
|
let (invites, adds) = partitionEithers $ Set.toList efCorrectors
|
||||||
insertMany_ [ ExamCorrector{..}
|
insertMany_ [ ExamCorrector{..}
|
||||||
| let examCorrectorExam = examid
|
| let examCorrectorExam = examid
|
||||||
|
|||||||
@ -26,7 +26,7 @@ getEShowR tid ssh csh examn = do
|
|||||||
cTime <- liftIO getCurrentTime
|
cTime <- liftIO getCurrentTime
|
||||||
mUid <- maybeAuthId
|
mUid <- maybeAuthId
|
||||||
|
|
||||||
(Entity eId Exam{..}, School{..}, examParts, examVisible, (gradingVisible, gradingShown), (occurrenceAssignmentsVisible, occurrenceAssignmentsShown), results, result, bonus, occurrences, (registered, mayRegister), registeredCount, lecturerInfoShown) <- runDB $ do
|
(Entity eId Exam{..}, School{..}, examParts, examVisible, (gradingVisible, gradingShown), (occurrenceAssignmentsVisible, occurrenceAssignmentsShown), results, result, bonus, occurrences, (registered, mayRegister), registeredCount, lecturerInfoShown, staffInfoShown, extraSchools) <- runDB $ do
|
||||||
exam@(Entity eId Exam{..}) <- fetchExam tid ssh csh examn
|
exam@(Entity eId Exam{..}) <- fetchExam tid ssh csh examn
|
||||||
school <- getJust examCourse >>= belongsToJust courseSchool
|
school <- getJust examCourse >>= belongsToJust courseSchool
|
||||||
|
|
||||||
@ -83,7 +83,14 @@ getEShowR tid ssh csh examn = do
|
|||||||
|
|
||||||
lecturerInfoShown <- hasReadAccessTo $ CExamR tid ssh csh examn EEditR
|
lecturerInfoShown <- hasReadAccessTo $ CExamR tid ssh csh examn EEditR
|
||||||
|
|
||||||
return (exam, school, examParts, examVisible, (gradingVisible, gradingShown), (occurrenceAssignmentsVisible, occurrenceAssignmentsShown), results, result, bonus, occurrences, (registered, mayRegister), registeredCount, lecturerInfoShown)
|
staffInfoShown <- hasReadAccessTo $ CExamR tid ssh csh examn EGradesR
|
||||||
|
|
||||||
|
extraSchools <- E.select . E.from $ \(school' `E.InnerJoin` examOfficeSchool) -> do
|
||||||
|
E.on $ school' E.^. SchoolId E.==. examOfficeSchool E.^. ExamOfficeSchoolSchool
|
||||||
|
E.where_ $ examOfficeSchool E.^. ExamOfficeSchoolExam E.==. E.val eId
|
||||||
|
return school'
|
||||||
|
|
||||||
|
return (exam, school, examParts, examVisible, (gradingVisible, gradingShown), (occurrenceAssignmentsVisible, occurrenceAssignmentsShown), results, result, bonus, occurrences, (registered, mayRegister), registeredCount, lecturerInfoShown, staffInfoShown, extraSchools)
|
||||||
|
|
||||||
let occurrenceNamesShown = lecturerInfoShown
|
let occurrenceNamesShown = lecturerInfoShown
|
||||||
partNumbersShown = lecturerInfoShown
|
partNumbersShown = lecturerInfoShown
|
||||||
|
|||||||
@ -1261,8 +1261,7 @@ mpreq :: (RenderMessage site (ValueRequired site), HandlerSite m ~ site, MonadHa
|
|||||||
-- Otherwise acts exactly like `mopt`.
|
-- Otherwise acts exactly like `mopt`.
|
||||||
mpreq f fs@FieldSettings{..} mx = do
|
mpreq f fs@FieldSettings{..} mx = do
|
||||||
mr <- getMessageRender
|
mr <- getMessageRender
|
||||||
(res, fv) <- mopt f fs (Just <$> mx)
|
(res, fv') <- mpreq' f fs $ Just <$> mx
|
||||||
let fv' = fv { fvRequired = True }
|
|
||||||
return $ case res of
|
return $ case res of
|
||||||
FormSuccess (Just res')
|
FormSuccess (Just res')
|
||||||
-> (FormSuccess res', fv')
|
-> (FormSuccess res', fv')
|
||||||
@ -1293,6 +1292,25 @@ wpreq :: (RenderMessage site (ValueRequired site), HandlerSite m ~ site, MonadHa
|
|||||||
wpreq f fs mx = mFormToWForm $ mpreq f fs mx
|
wpreq f fs mx = mFormToWForm $ mpreq f fs mx
|
||||||
|
|
||||||
|
|
||||||
|
mpreq' :: (HandlerSite m ~ site, MonadHandler m)
|
||||||
|
=> Field m a -> FieldSettings site -> Maybe (Maybe a) -> MForm m (FormResult (Maybe a), FieldView site)
|
||||||
|
-- ^ Pseudo required
|
||||||
|
--
|
||||||
|
-- `FieldView` has `fvRequired` set to `True`.
|
||||||
|
-- Otherwise acts exactly like `mopt`.
|
||||||
|
mpreq' f fs mx = do
|
||||||
|
(res, fv) <- mopt f fs mx
|
||||||
|
return (res, fv { fvRequired = True })
|
||||||
|
|
||||||
|
apreq' :: (HandlerSite m ~ site, MonadHandler m)
|
||||||
|
=> Field m a -> FieldSettings site -> Maybe (Maybe a) -> AForm m (Maybe a)
|
||||||
|
apreq' f fs mx = formToAForm $ over _2 pure <$> mpreq' f fs mx
|
||||||
|
|
||||||
|
wpreq' :: (HandlerSite m ~ site, MonadHandler m)
|
||||||
|
=> Field m a -> FieldSettings site -> Maybe (Maybe a) -> WForm m (FormResult (Maybe a))
|
||||||
|
wpreq' f fs mx = mFormToWForm $ mpreq' f fs mx
|
||||||
|
|
||||||
|
|
||||||
mpopt :: (RenderMessage site (ValueRequired site), HandlerSite m ~ site, MonadHandler m)
|
mpopt :: (RenderMessage site (ValueRequired site), HandlerSite m ~ site, MonadHandler m)
|
||||||
=> Field m a -> FieldSettings site -> Maybe a -> MForm m (FormResult a, FieldView site)
|
=> Field m a -> FieldSettings site -> Maybe a -> MForm m (FormResult a, FieldView site)
|
||||||
-- ^ Pseudo optional
|
-- ^ Pseudo optional
|
||||||
|
|||||||
@ -94,6 +94,16 @@ $maybe desc <- examDescription
|
|||||||
$maybe closed <- examClosed
|
$maybe closed <- examClosed
|
||||||
<dt .deflist__dt>_{MsgExamClosed} ^{isVisible False}
|
<dt .deflist__dt>_{MsgExamClosed} ^{isVisible False}
|
||||||
<dd .deflist__dd>^{formatTimeW SelFormatDateTime closed}
|
<dd .deflist__dd>^{formatTimeW SelFormatDateTime closed}
|
||||||
|
$maybe staff <- examStaff
|
||||||
|
$if staffInfoShown
|
||||||
|
<dd .deflist__dt>_{MsgExamStaff} ^{isVisible False}
|
||||||
|
<dt .deflist__dd>#{staff}
|
||||||
|
$if staffInfoShown && not (onull extraSchools)
|
||||||
|
<dd .deflist__dt>_{MsgExamExamOfficeSchools} ^{isVisible False}
|
||||||
|
<dt .deflist__dd>
|
||||||
|
<ul>
|
||||||
|
$forall Entity _ School{schoolName} <- extraSchools
|
||||||
|
<li>#{schoolName}
|
||||||
$if gradingShown
|
$if gradingShown
|
||||||
$maybe gradingRule <- examGradingRule
|
$maybe gradingRule <- examGradingRule
|
||||||
<dt .deflist__dt>
|
<dt .deflist__dt>
|
||||||
|
|||||||
6
templates/exam/schoolMassInput/add.hamlet
Normal file
6
templates/exam/schoolMassInput/add.hamlet
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
$newline never
|
||||||
|
<td>
|
||||||
|
#{csrf}
|
||||||
|
^{fvWidget addView}
|
||||||
|
<td>
|
||||||
|
^{fvWidget submitView}
|
||||||
3
templates/exam/schoolMassInput/cell.hamlet
Normal file
3
templates/exam/schoolMassInput/cell.hamlet
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
$newline never
|
||||||
|
<td>
|
||||||
|
#{schoolName}
|
||||||
11
templates/exam/schoolMassInput/layout.hamlet
Normal file
11
templates/exam/schoolMassInput/layout.hamlet
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
$newline never
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
$forall coord <- review liveCoords lLength
|
||||||
|
<tr .massinput__cell>
|
||||||
|
^{cellWdgts ! coord}
|
||||||
|
<td>
|
||||||
|
^{fvWidget (delButtons ! coord)}
|
||||||
|
<tfoot>
|
||||||
|
<tr .massinput__cell.massinput__cell--add>
|
||||||
|
^{addWdgts ! (0, 0)}
|
||||||
@ -677,6 +677,7 @@ fillDb = do
|
|||||||
, examSynchronicity = Just $ ExamSynchronicityPreset ExamSynchronous
|
, examSynchronicity = Just $ ExamSynchronicityPreset ExamSynchronous
|
||||||
, examRequiredEquipment = Just $ ExamRequiredEquipmentPreset ExamRequiredEquipmentNone
|
, examRequiredEquipment = Just $ ExamRequiredEquipmentPreset ExamRequiredEquipmentNone
|
||||||
}
|
}
|
||||||
|
, examStaff = Just "Hofmann"
|
||||||
}
|
}
|
||||||
void . insertMany $ map (\u -> ExamRegistration examFFP u Nothing now)
|
void . insertMany $ map (\u -> ExamRegistration examFFP u Nothing now)
|
||||||
[ fhamann
|
[ fhamann
|
||||||
|
|||||||
Reference in New Issue
Block a user