102 lines
5.2 KiB
Haskell
102 lines
5.2 KiB
Haskell
module Handler.Tutorial.Form
|
|
( TutorialForm(..)
|
|
, tutorialForm
|
|
) where
|
|
|
|
import Import
|
|
import Handler.Utils
|
|
import Handler.Utils.Form.Occurrences
|
|
|
|
import qualified Database.Esqueleto as E
|
|
|
|
import Data.Map ((!))
|
|
import qualified Data.Set as Set
|
|
|
|
import qualified Data.CaseInsensitive as CI
|
|
|
|
|
|
data TutorialForm = TutorialForm
|
|
{ tfName :: TutorialName
|
|
, tfType :: CI Text
|
|
, tfRegGroup :: Maybe (CI Text)
|
|
, tfTutorControlled :: Bool
|
|
, tfCapacity :: Maybe Int
|
|
, tfRoom :: Maybe RoomReference
|
|
, tfRoomHidden :: Bool
|
|
, tfTime :: Occurrences
|
|
, tfRegisterFrom :: Maybe UTCTime
|
|
, tfRegisterTo :: Maybe UTCTime
|
|
, tfDeregisterUntil :: Maybe UTCTime
|
|
, tfTutors :: Set (Either UserEmail UserId)
|
|
}
|
|
|
|
tutorialForm :: CourseId -> Maybe TutorialForm -> Form TutorialForm
|
|
tutorialForm cid template html = do
|
|
MsgRenderer mr <- getMsgRenderer
|
|
cRoute <- fromMaybe (error "tutorialForm called from 404-Handler") <$> getCurrentRoute
|
|
uid <- liftHandler requireAuthId
|
|
|
|
let
|
|
tutorForm = Set.fromList <$> massInputAccumA miAdd' miCell' (\p -> Just . SomeRoute $ cRoute :#: p) miLayout' ("tutors" :: Text) (fslI MsgTutorialTutors) False (Set.toList . tfTutors <$> template)
|
|
where
|
|
miAdd' :: (Text -> Text) -> FieldView UniWorX -> Form ([Either UserEmail UserId] -> FormResult [Either UserEmail UserId])
|
|
miAdd' nudge submitView csrf = do
|
|
(addRes, addView) <- mpreq (multiUserInvitationField . MUILookupAnyUser . Just $ tutUserSuggestions uid) (fslI MsgTutorEmail & addName (nudge "email") & addPlaceholder (mr MsgLdapIdentificationOrEmail)) Nothing
|
|
let
|
|
addRes'
|
|
|
|
= addRes <&> \newDat oldDat -> if
|
|
| existing <- newDat `Set.intersection` Set.fromList oldDat
|
|
, not $ Set.null existing
|
|
-> FormFailure [mr MsgTutorialTutorAlreadyAdded]
|
|
| otherwise
|
|
-> FormSuccess $ Set.toList newDat
|
|
return (addRes', $(widgetFile "tutorial/tutorMassInput/add"))
|
|
|
|
|
|
miCell' :: Either UserEmail UserId -> Widget
|
|
miCell' (Left email) = do
|
|
invWarnMsg <- messageIconI Info IconEmail MsgEmailInvitationWarning
|
|
$(widgetFile "tutorial/tutorMassInput/cellInvitation")
|
|
miCell' (Right userId) = do
|
|
User{..} <- liftHandler . runDB $ get404 userId
|
|
$(widgetFile "tutorial/tutorMassInput/cellKnown")
|
|
|
|
miLayout' :: MassInputLayout ListLength (Either UserEmail UserId) ()
|
|
miLayout' lLength _ cellWdgts delButtons addWdgts = $(widgetFile "tutorial/tutorMassInput/layout")
|
|
|
|
flip (renderAForm FormStandard) html $ TutorialForm
|
|
<$> areq (textField & cfStrip & cfCI) (fslpI MsgTutorialName (mr MsgTutorialName) & setTooltip MsgTutorialNameTip) (tfName <$> template)
|
|
<*> areq (textField & cfStrip & cfCI & addDatalist tutTypeDatalist) (fslpI MsgTutorialType (mr MsgTutorialTypePlaceholder) & setTooltip MsgTutorialTypeTip) (tfType <$> template)
|
|
<*> aopt (textField & cfStrip & cfCI) (fslI MsgTutorialRegGroup & setTooltip MsgTutorialRegGroupTip) ((tfRegGroup <$> template) <|> Just (Just "tutorial"))
|
|
<*> apopt checkBoxField (fslI MsgTutorialTutorControlled & setTooltip MsgTutorialTutorControlledTip) (tfTutorControlled <$> template)
|
|
<*> aopt (natFieldI MsgTutorialCapacityNonPositive) (fslpI MsgTutorialCapacity (mr MsgTutorialCapacity) & setTooltip MsgTutorialCapacityTip) (tfCapacity <$> template)
|
|
<*> roomReferenceFormOpt (fslI MsgTutorialRoom) (tfRoom <$> template)
|
|
<*> apopt checkBoxField (fslI MsgTutorialRoomHidden & setTooltip MsgTutorialRoomHiddenTip) (tfRoomHidden <$> template <|> Just False)
|
|
<*> occurrencesAForm ("occurrences" :: Text) (tfTime <$> template)
|
|
<*> aopt utcTimeField (fslpI MsgRegisterFrom (mr MsgDate)
|
|
& setTooltip MsgCourseRegisterFromTip
|
|
) (tfRegisterFrom <$> template)
|
|
<*> aopt utcTimeField (fslpI MsgRegisterTo (mr MsgDate)
|
|
& setTooltip MsgCourseRegisterToTip
|
|
) (tfRegisterTo <$> template)
|
|
<*> aopt utcTimeField (fslpI MsgDeRegUntil (mr MsgDate)
|
|
& setTooltip MsgCourseDeregisterUntilTip
|
|
) (tfDeregisterUntil <$> template)
|
|
<*> tutorForm
|
|
where
|
|
tutTypeDatalist :: HandlerFor UniWorX (OptionList (CI Text))
|
|
tutTypeDatalist = fmap (mkOptionList . map (\t -> Option (CI.original t) t (CI.original t)) . Set.toAscList) . runDB $
|
|
fmap (setOf $ folded . _Value) . E.select . E.from $ \tutorial -> do
|
|
E.where_ $ tutorial E.^. TutorialCourse E.==. E.val cid
|
|
return $ tutorial E.^. TutorialType
|
|
|
|
tutUserSuggestions :: UserId -> E.SqlQuery (E.SqlExpr (Entity User))
|
|
tutUserSuggestions uid = E.from $ \(lecturer `E.InnerJoin` course `E.InnerJoin` tutorial `E.InnerJoin` tutor `E.InnerJoin` tutorUser) -> do
|
|
E.on $ tutorUser E.^. UserId E.==. tutor E.^. TutorUser
|
|
E.on $ tutor E.^. TutorTutorial E.==. tutorial E.^. TutorialId
|
|
E.on $ tutorial E.^. TutorialCourse E.==. course E.^. CourseId
|
|
E.on $ course E.^. CourseId E.==. lecturer E.^. LecturerCourse
|
|
E.where_ $ lecturer E.^. LecturerUser E.==. E.val uid
|
|
return tutorUser
|