From 9793141090543fdb67c96ae9e649d5d07d072af4 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Fri, 29 Jun 2018 11:49:03 +0200 Subject: [PATCH] Fix behaviour of correctors-form --- messages/de.msg | 1 + src/Handler/Sheet.hs | 78 +++++++++++++++++++++++++++++--------------- 2 files changed, 52 insertions(+), 27 deletions(-) diff --git a/messages/de.msg b/messages/de.msg index 51152d5b2..ab977b42c 100644 --- a/messages/de.msg +++ b/messages/de.msg @@ -87,6 +87,7 @@ DeleteRow: Zeile entfernen ProportionNegative: Anteile dürfen nicht negativ sein CorrectorsUpdated: Korrektoren erfolgreich aktualisiert CorrectorsPlaceholder: Korrektoren... +CorrectorsDefaulted: Korrektoren-Liste wurde aus bisherigen Übungsblättern diesen Kurses generiert. Es sind keine Daten gespeichert. HomeHeading: Aktuelle Termine ProfileHeading: Benutzerprofil und Einstellungen diff --git a/src/Handler/Sheet.hs b/src/Handler/Sheet.hs index eb1fba369..6d92f16e2 100644 --- a/src/Handler/Sheet.hs +++ b/src/Handler/Sheet.hs @@ -11,6 +11,8 @@ {-# LANGUAGE ViewPatterns #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE TypeOperators #-} +{-# LANGUAGE MultiWayIf, LambdaCase #-} +{-# LANGUAGE TupleSections #-} module Handler.Sheet where @@ -24,7 +26,7 @@ import Handler.Utils.Zip import qualified Data.Text as T -- import Data.Function ((&)) -- -import Colonnade hiding (fromMaybe, singleton) +import Colonnade hiding (fromMaybe, singleton, bool) import Yesod.Colonnade import Text.Blaze (text) -- @@ -106,7 +108,6 @@ makeSheetForm msId template = identForm FIDsheet $ \html -> do <*> fileAFormOpt (fsb "Hinweis") <*> aopt utcTimeField (fsb "Lösung ab") (sfSolutionFrom <$> template) <*> fileAFormOpt (fsb "Lösung") - <*> formToAForm (correctorForm msId (maybe [] sfCorrectors template)) <* submitButton return $ case result of FormSuccess sheetResult @@ -431,16 +432,20 @@ defaultLoads :: SheetId -> DB Loads -- -- For every user, that ever was a corrector for this course, return their last `Load`. -- "Last `Load`" is taken to mean their `Load` on the `Sheet` with the most recent creation time (first edit). -defaultLoads shid = fmap toMap . E.select . E.from $ \(sheet `E.InnerJoin` sheetCorrector) -> E.distinctOnOrderBy [E.asc (sheetCorrector E.^. SheetCorrectorUser)] $ do - E.on $ sheet E.^. SheetId E.==. sheetCorrector E.^. SheetCorrectorSheet +defaultLoads shid = do + cId <- sheetCourse <$> getJust shid + fmap toMap . E.select . E.from $ \(sheet `E.InnerJoin` sheetCorrector) -> E.distinctOnOrderBy [E.asc (sheetCorrector E.^. SheetCorrectorUser)] $ do + E.on $ sheet E.^. SheetId E.==. sheetCorrector E.^. SheetCorrectorSheet - let creationTime = E.sub_select . E.from $ \sheetEdit -> do - E.where_ $ sheetEdit E.^. SheetEditSheet E.==. sheet E.^. SheetId - return . E.min_ $ sheetEdit E.^. SheetEditTime + let creationTime = E.sub_select . E.from $ \sheetEdit -> do + E.where_ $ sheetEdit E.^. SheetEditSheet E.==. sheet E.^. SheetId + return . E.min_ $ sheetEdit E.^. SheetEditTime - E.orderBy [E.desc creationTime] + E.where_ $ sheet E.^. SheetCourse E.==. E.val cId + + E.orderBy [E.desc creationTime] - return (sheetCorrector E.^. SheetCorrectorUser, sheetCorrector E.^. SheetCorrectorLoad) + return (sheetCorrector E.^. SheetCorrectorUser, sheetCorrector E.^. SheetCorrectorLoad) where toMap :: [(E.Value UserId, E.Value Load)] -> Loads toMap = foldMap $ \(E.Value uid, E.Value load) -> Map.singleton uid load @@ -450,17 +455,27 @@ correctorForm :: SheetId -> MForm Handler (FormResult (Set SheetCorrector), [Fie correctorForm shid = do cListIdent <- newFormIdent let - guardNonDeleted :: CryptoUUIDUser -> Handler (Maybe CryptoUUIDUser) - guardNonDeleted cID@CryptoID{..} = do + guardNonDeleted :: UserId -> Handler (Maybe UserId) + guardNonDeleted uid = do + cID@CryptoID{..} <- encrypt uid :: Handler CryptoUUIDUser deleted <- lookupPostParam $ tshow ciphertext <> "-" <> "del" - case deleted of - Just _ -> return Nothing - Nothing -> return $ Just cID - formCIDs <- lift $ (mapM decrypt <=< fmap catMaybes . mapM (maybe (return Nothing) guardNonDeleted)) =<< (map fromPathPiece <$> lookupPostParams cListIdent :: Handler [Maybe CryptoUUIDUser]) - loads'' <- lift . runDB $ defaultLoads shid - let loads' = loads'' `Map.union` Map.fromList [(uid, mempty) | uid <- formCIDs] - - (countTutRes, countTutView) <- mreq checkBoxField (fsm MsgCountTutProp) Nothing + return $ bool Just (const Nothing) (isJust deleted) uid + formCIDs <- mapM decrypt =<< catMaybes <$> liftHandlerT (map fromPathPiece <$> lookupPostParams cListIdent :: Handler [Maybe CryptoUUIDUser]) + let + currentLoads :: DB Loads + currentLoads = Map.fromList . map (\(Entity _ SheetCorrector{..}) -> (sheetCorrectorUser, sheetCorrectorLoad)) <$> selectList [ SheetCorrectorSheet ==. shid ] [] + (defaultLoads', currentLoads') <- lift . runDB $ (,) <$> defaultLoads shid <*> currentLoads + loads' <- fmap (Map.fromList [(uid, mempty) | uid <- formCIDs] `Map.union`) $ if + | Map.null currentLoads' + , null formCIDs -> defaultLoads' <$ when (not $ Map.null defaultLoads') (addMessageI "warn" MsgCorrectorsDefaulted) + | otherwise -> return $ Map.fromList (map (, mempty) formCIDs) `Map.union` currentLoads' + + deletions <- lift $ foldM (\dels uid -> maybe (Set.insert uid dels) (const dels) <$> guardNonDeleted uid) Set.empty (Map.keys loads') + + let loads'' = Map.restrictKeys loads' (Map.keysSet loads' `Set.difference` deletions) + didDelete = any (flip Set.member deletions) formCIDs + + (countTutRes, countTutView) <- mreq checkBoxField (fsm MsgCountTutProp) . Just $ any (\Load{..} -> fromMaybe False byTutorial) $ Map.elems loads' let tutorField :: Field Handler [Text] tutorField = multiEmailField @@ -488,12 +503,14 @@ correctorForm shid = do FormSuccess (Just emails) -> fmap Map.unions . forM emails $ \email -> do mUid <- fmap (fmap entityKey) . lift . runDB $ getBy (UniqueEmail email) case mUid of - Nothing -> loads' <$ addMessageI "error" (MsgEMailUnknown email) + Nothing -> loads'' <$ addMessageI "error" (MsgEMailUnknown email) Just uid - | not (Map.member uid loads') -> return $ Map.insert uid mempty loads' - | otherwise -> loads' <$ addMessageI "warning" (MsgCorrectorExists email) - FormFailure errs -> loads' <$ mapM_ (addMessage "error" . toHtml) errs - _ -> return loads' + | not (Map.member uid loads') -> return $ Map.insert uid mempty loads'' + | otherwise -> loads'' <$ addMessageI "warning" (MsgCorrectorExists email) + FormFailure errs -> loads'' <$ mapM_ (addMessage "error" . toHtml) errs + _ -> return loads'' + + let deletions' = deletions `Set.difference` Map.keysSet loads names <- fmap (Map.fromList . map (\(E.Value a, E.Value b) -> (a, b))) . lift . runDB . E.select . E.from $ \user -> do E.where_ $ user E.^. UserId `E.in_` E.valList (Map.keys loads) @@ -526,6 +543,8 @@ correctorForm shid = do mr <- getMessageRender + $logDebugS "SCorrR" $ tshow (didDelete, addTutRes) + let corrColonnade = mconcat [ headed (textCell $ mr MsgCorrector) $ \CorrectorForm{..} -> textCell cfUserName @@ -536,6 +555,7 @@ correctorForm shid = do corrResults | FormSuccess (Just es) <- addTutRes , not $ null es = FormMissing + | didDelete = FormMissing | otherwise = fmap Set.fromList $ sequenceA [ SheetCorrector <$> pure cfUserId <*> pure shid <*> cfResult | CorrectorForm{..} <- corrData ] @@ -543,12 +563,16 @@ correctorForm shid = do cID <- encrypt cfUserId :: WidgetT UniWorX IO CryptoUUIDUser toWidget [hamlet||] + delField uid = do + cID <- encrypt uid :: WidgetT UniWorX IO CryptoUUIDUser + toWidget [hamlet||] + return (corrResults, [ countTutView , FieldView { fvLabel = text $ mr MsgCorrectors , fvTooltip = Nothing , fvId = "" - , fvInput = encodeCellTable tableDefault corrColonnade corrData >> mapM_ idField corrData + , fvInput = encodeCellTable tableDefault corrColonnade corrData >> mapM_ idField corrData >> mapM_ delField deletions , fvErrors = Nothing , fvRequired = True } @@ -585,8 +609,8 @@ getSCorrR tid@(unTermKey -> tident) csh shn = do let formTitle = MsgSheetCorrectorsTitle tident csh shn formText = Nothing :: Maybe (SomeMessage UniWorX) - -- actionUrl = CSheetR tid csh shn SCorrR - actionUrl = CSheetR tid csh shn SShowR + actionUrl = CSheetR tid csh shn SCorrR + -- actionUrl = CSheetR tid csh shn SShowR defaultLayout $ do setTitleI $ MsgSheetCorrectorsTitle tident csh shn $(widgetFile "formPageI18n")