Übungsblätter not shown if none exists
This commit is contained in:
parent
ac5e1b6f4b
commit
882b30951b
@ -19,6 +19,7 @@ should-log-all: "_env:LOG_ALL:false"
|
|||||||
# mutable-static: false
|
# mutable-static: false
|
||||||
# skip-combining: false
|
# skip-combining: false
|
||||||
auth-dummy-login: "_env:DUMMY_LOGIN:false"
|
auth-dummy-login: "_env:DUMMY_LOGIN:false"
|
||||||
|
allow-deprecated: "_env:ALLOW_DEPRECATED:false"
|
||||||
|
|
||||||
# NB: If you need a numeric value (e.g. 123) to parse as a String, wrap it in single quotes (e.g. "_env:PGPASS:'123'")
|
# NB: If you need a numeric value (e.g. 123) to parse as a String, wrap it in single quotes (e.g. "_env:PGPASS:'123'")
|
||||||
# See https://github.com/yesodweb/yesod/wiki/Configuration#parsing-numeric-values-as-strings
|
# See https://github.com/yesodweb/yesod/wiki/Configuration#parsing-numeric-values-as-strings
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
{-# LANGUAGE NoImplicitPrelude #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE OverloadedLists #-}
|
|
||||||
{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}
|
{-# LANGUAGE TemplateHaskell, QuasiQuotes #-}
|
||||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
{-# LANGUAGE TypeFamilies #-}
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
@ -225,12 +224,13 @@ adminAP = APDB $ \case
|
|||||||
|
|
||||||
|
|
||||||
knownTags :: Map (CI Text) AccessPredicate
|
knownTags :: Map (CI Text) AccessPredicate
|
||||||
knownTags = -- should not throw exceptions, i.e. no getBy404 or requireAuthId
|
knownTags = Map.fromList -- should not throw exceptions, i.e. no getBy404 or requireAuthId
|
||||||
[("free", trueAP)
|
[("free", trueAP)
|
||||||
,("deprecated", APHandler $ \r -> do
|
,("deprecated", APHandler $ \r -> do
|
||||||
$logWarnS "AccessControl" ("deprecated route: " <> tshow r)
|
$logWarnS "AccessControl" ("deprecated route: " <> tshow r)
|
||||||
addMessageI "error" MsgDeprecatedRoute
|
addMessageI "error" MsgDeprecatedRoute
|
||||||
return Authorized
|
allow <- appAllowDeprecated . appSettings <$> getYesod
|
||||||
|
return $ bool (Unauthorized "Deprecated Route") Authorized allow
|
||||||
)
|
)
|
||||||
,("lecturer", APDB $ \case
|
,("lecturer", APDB $ \case
|
||||||
CourseR tid csh _ -> exceptT return return $ do
|
CourseR tid csh _ -> exceptT return return $ do
|
||||||
@ -568,7 +568,7 @@ instance YesodBreadcrumbs UniWorX where
|
|||||||
breadcrumb (TermCourseListR term) = return (toPathPiece term, Just TermShowR)
|
breadcrumb (TermCourseListR term) = return (toPathPiece term, Just TermShowR)
|
||||||
breadcrumb (CourseR term course CShowR) = return (course, Just $ TermCourseListR term)
|
breadcrumb (CourseR term course CShowR) = return (course, Just $ TermCourseListR term)
|
||||||
breadcrumb CourseNewR = return ("Neu", Just CourseListR)
|
breadcrumb CourseNewR = return ("Neu", Just CourseListR)
|
||||||
breadcrumb (CourseR _ _ CEditR) = return ("Editieren", Just CourseListR)
|
breadcrumb (CourseR tid csh CEditR) = return ("Editieren", Just $ CourseR tid csh CShowR)
|
||||||
|
|
||||||
breadcrumb (CourseR tid csh SheetListR) = return ("Übungen",Just $ CourseR tid csh CShowR)
|
breadcrumb (CourseR tid csh SheetListR) = return ("Übungen",Just $ CourseR tid csh CShowR)
|
||||||
breadcrumb (CourseR tid csh SheetNewR ) = return ("Neu", Just $ CourseR tid csh SheetListR)
|
breadcrumb (CourseR tid csh SheetNewR ) = return ("Neu", Just $ CourseR tid csh SheetListR)
|
||||||
@ -580,26 +580,37 @@ instance YesodBreadcrumbs UniWorX where
|
|||||||
breadcrumb SubmissionListR = return ("Abgaben", Just HomeR)
|
breadcrumb SubmissionListR = return ("Abgaben", Just HomeR)
|
||||||
|
|
||||||
|
|
||||||
breadcrumb HomeR = return ("UniWorkY", Nothing)
|
breadcrumb HomeR = return ("UniWorkY", Nothing)
|
||||||
breadcrumb (AuthR _) = return ("Login", Just HomeR)
|
breadcrumb (AuthR _) = return ("Login", Just HomeR)
|
||||||
breadcrumb ProfileR = return ("Profile", Just HomeR)
|
breadcrumb ProfileR = return ("Profile", Just HomeR)
|
||||||
breadcrumb ProfileDataR = return ("Data", Just ProfileR)
|
breadcrumb ProfileDataR = return ("Data", Just ProfileR)
|
||||||
breadcrumb _ = return ("home", Nothing)
|
breadcrumb _ = return ("home", Nothing)
|
||||||
|
|
||||||
pageActions :: Route UniWorX -> [MenuTypes]
|
pageActions :: Route UniWorX -> [MenuTypes]
|
||||||
pageActions (CourseR tid csh CShowR) =
|
pageActions (CourseR tid csh CShowR) =
|
||||||
[ PageActionPrime $ MenuItem
|
[ PageActionPrime $ MenuItem
|
||||||
{ menuItemLabel = "Übungsblätter"
|
|
||||||
, menuItemIcon = Nothing
|
|
||||||
, menuItemRoute = CourseR tid csh SheetListR
|
|
||||||
, menuItemAccessCallback' = return True
|
|
||||||
}
|
|
||||||
, PageActionPrime $ MenuItem
|
|
||||||
{ menuItemLabel = "Kurs Editieren"
|
{ menuItemLabel = "Kurs Editieren"
|
||||||
, menuItemIcon = Nothing
|
, menuItemIcon = Nothing
|
||||||
, menuItemRoute = CourseR tid csh CEditR
|
, menuItemRoute = CourseR tid csh CEditR
|
||||||
, menuItemAccessCallback' = return True
|
, menuItemAccessCallback' = return True
|
||||||
}
|
}
|
||||||
|
, PageActionPrime $ MenuItem
|
||||||
|
{ menuItemLabel = "Übungsblätter"
|
||||||
|
, menuItemIcon = Nothing
|
||||||
|
, menuItemRoute = CourseR tid csh SheetListR
|
||||||
|
, menuItemAccessCallback' = do --TODO always show for lecturer
|
||||||
|
let sheetRouteAccess shn = (== Authorized) <$> (isAuthorized (CSheetR tid csh shn SShowR) False)
|
||||||
|
sheets <-runDB $ do
|
||||||
|
cid <- getKeyBy404 $ CourseTermShort tid csh
|
||||||
|
map (sheetName.entityVal) <$> selectList [SheetCourse ==. cid] [Desc SheetActiveFrom]
|
||||||
|
anyM sheets sheetRouteAccess
|
||||||
|
}
|
||||||
|
, PageActionSecondary $ MenuItem
|
||||||
|
{ menuItemLabel = "Neues Übungsblatt anlegen"
|
||||||
|
, menuItemIcon = Nothing
|
||||||
|
, menuItemRoute = CourseR tid csh SheetNewR
|
||||||
|
, menuItemAccessCallback' = return True
|
||||||
|
}
|
||||||
]
|
]
|
||||||
pageActions (CourseR tid csh SheetListR) =
|
pageActions (CourseR tid csh SheetListR) =
|
||||||
[ PageActionPrime $ MenuItem
|
[ PageActionPrime $ MenuItem
|
||||||
@ -617,7 +628,7 @@ pageActions (CSheetR tid csh shn SShowR) =
|
|||||||
, menuItemAccessCallback' = return True -- TODO: check that no submission already exists
|
, menuItemAccessCallback' = return True -- TODO: check that no submission already exists
|
||||||
}
|
}
|
||||||
, PageActionPrime $ MenuItem
|
, PageActionPrime $ MenuItem
|
||||||
{ menuItemLabel = "Abgabe"
|
{ menuItemLabel = "Abgabe ansehen"
|
||||||
, menuItemIcon = Nothing
|
, menuItemIcon = Nothing
|
||||||
, menuItemRoute = CSheetR tid csh shn SubmissionOwnR
|
, menuItemRoute = CSheetR tid csh shn SubmissionOwnR
|
||||||
, menuItemAccessCallback' = return True -- TODO: check that a submission already exists
|
, menuItemAccessCallback' = return True -- TODO: check that a submission already exists
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
{-# LANGUAGE RecordWildCards #-}
|
{-# LANGUAGE RecordWildCards #-}
|
||||||
{-# LANGUAGE NoImplicitPrelude #-}
|
{-# LANGUAGE NoImplicitPrelude #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE OverloadedLists #-}
|
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
{-# LANGUAGE MultiParamTypeClasses #-}
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
@ -15,6 +14,8 @@ module Handler.Home where
|
|||||||
import Import
|
import Import
|
||||||
import Handler.Utils
|
import Handler.Utils
|
||||||
|
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
|
||||||
import Data.Time
|
import Data.Time
|
||||||
-- import qualified Data.Text as T
|
-- import qualified Data.Text as T
|
||||||
-- import Yesod.Form.Bootstrap3
|
-- import Yesod.Form.Bootstrap3
|
||||||
@ -80,7 +81,8 @@ homeAnonymous = do
|
|||||||
courseTable <- dbTable def $ DBTable
|
courseTable <- dbTable def $ DBTable
|
||||||
{ dbtSQLQuery = tableData
|
{ dbtSQLQuery = tableData
|
||||||
, dbtColonnade = colonnade
|
, dbtColonnade = colonnade
|
||||||
, dbtSorting = [ ( "term"
|
, dbtSorting = Map.fromList
|
||||||
|
[ ( "term"
|
||||||
, SortColumn $ \(course) -> course E.^. CourseTerm
|
, SortColumn $ \(course) -> course E.^. CourseTerm
|
||||||
)
|
)
|
||||||
, ( "course"
|
, ( "course"
|
||||||
@ -147,7 +149,8 @@ homeUser uid = do
|
|||||||
sheetTable <- dbTable def $ DBTable
|
sheetTable <- dbTable def $ DBTable
|
||||||
{ dbtSQLQuery = tableData
|
{ dbtSQLQuery = tableData
|
||||||
, dbtColonnade = colonnade
|
, dbtColonnade = colonnade
|
||||||
, dbtSorting = [ ( "term"
|
, dbtSorting = Map.fromList
|
||||||
|
[ ( "term"
|
||||||
, SortColumn $ \(_ `E.InnerJoin` course `E.InnerJoin` _ ) -> course E.^. CourseTerm
|
, SortColumn $ \(_ `E.InnerJoin` course `E.InnerJoin` _ ) -> course E.^. CourseTerm
|
||||||
)
|
)
|
||||||
, ( "course"
|
, ( "course"
|
||||||
|
|||||||
@ -159,7 +159,7 @@ getSheetList courseEnt = do
|
|||||||
let colBase = mconcat
|
let colBase = mconcat
|
||||||
[ headed "Blatt" $ \(sid,sheet,_) -> simpleLink (toWgt $ sheetName sheet) $ CSheetR tid csh (sheetName sheet) SShowR
|
[ headed "Blatt" $ \(sid,sheet,_) -> simpleLink (toWgt $ sheetName sheet) $ CSheetR tid csh (sheetName sheet) SShowR
|
||||||
, headed "Abgabe ab" $ toWgt . formatTimeGerWD . sheetActiveFrom . snd3
|
, headed "Abgabe ab" $ toWgt . formatTimeGerWD . sheetActiveFrom . snd3
|
||||||
, headed "Abgabe bis" $ toWgt . formatTimeGerWD . sheetActiveTo . snd3
|
, headed "Abgabe lbis" $ toWgt . formatTimeGerWD . sheetActiveTo . snd3
|
||||||
, headed "Bewertung" $ toWgt . display . sheetType . snd3
|
, headed "Bewertung" $ toWgt . display . sheetType . snd3
|
||||||
]
|
]
|
||||||
let colAdmin = mconcat -- only show edit button for allowed course assistants
|
let colAdmin = mconcat -- only show edit button for allowed course assistants
|
||||||
@ -177,7 +177,7 @@ getSheetList courseEnt = do
|
|||||||
then colBase `mappend` colAdmin
|
then colBase `mappend` colAdmin
|
||||||
else colBase
|
else colBase
|
||||||
defaultLayout $ do
|
defaultLayout $ do
|
||||||
setTitle $ toHtml $ T.append "Übungsblätter " csh
|
setTitle $ toHtml $ csh <> " Übungsblätter"
|
||||||
if null sheets
|
if null sheets
|
||||||
then [whamlet|Es wurden noch keine Übungsblätter angelegt.|]
|
then [whamlet|Es wurden noch keine Übungsblätter angelegt.|]
|
||||||
else encodeWidgetTable tableDefault colSheets sheets
|
else encodeWidgetTable tableDefault colSheets sheets
|
||||||
|
|||||||
@ -71,6 +71,8 @@ data AppSettings = AppSettings
|
|||||||
|
|
||||||
, appAuthDummyLogin :: Bool
|
, appAuthDummyLogin :: Bool
|
||||||
-- ^ Indicate if auth dummy login should be enabled.
|
-- ^ Indicate if auth dummy login should be enabled.
|
||||||
|
, appAllowDeprecated :: Bool
|
||||||
|
-- ^ Indicate if deprecated routes are accessible for everyone
|
||||||
}
|
}
|
||||||
|
|
||||||
instance FromJSON AppSettings where
|
instance FromJSON AppSettings where
|
||||||
@ -104,6 +106,7 @@ instance FromJSON AppSettings where
|
|||||||
appCryptoIDKeyFile <- o .: "cryptoid-keyfile"
|
appCryptoIDKeyFile <- o .: "cryptoid-keyfile"
|
||||||
|
|
||||||
appAuthDummyLogin <- o .:? "auth-dummy-login" .!= defaultDev
|
appAuthDummyLogin <- o .:? "auth-dummy-login" .!= defaultDev
|
||||||
|
appAllowDeprecated <- o .:? "allow-deprecated" .!= defaultDev
|
||||||
|
|
||||||
return AppSettings {..}
|
return AppSettings {..}
|
||||||
|
|
||||||
|
|||||||
33
src/Utils.hs
33
src/Utils.hs
@ -13,6 +13,7 @@ module Utils
|
|||||||
import ClassyPrelude.Yesod
|
import ClassyPrelude.Yesod
|
||||||
|
|
||||||
import Data.List (foldl)
|
import Data.List (foldl)
|
||||||
|
import Data.Foldable as Fold
|
||||||
import qualified Data.Char as Char
|
import qualified Data.Char as Char
|
||||||
|
|
||||||
import Utils.DB as Utils
|
import Utils.DB as Utils
|
||||||
@ -207,3 +208,35 @@ shortCircuitM sc mx my op = do
|
|||||||
case sc x of
|
case sc x of
|
||||||
True -> return x
|
True -> return x
|
||||||
False -> op <$> pure x <*> my
|
False -> op <$> pure x <*> my
|
||||||
|
|
||||||
|
|
||||||
|
-- Some Utility Functions from Agda.Utils.Monad
|
||||||
|
-- | Monadic if-then-else.
|
||||||
|
ifM :: Monad m => m Bool -> m a -> m a -> m a
|
||||||
|
ifM c m m' =
|
||||||
|
do b <- c
|
||||||
|
if b then m else m'
|
||||||
|
|
||||||
|
-- | @ifNotM mc = ifM (not <$> mc)@
|
||||||
|
ifNotM :: Monad m => m Bool -> m a -> m a -> m a
|
||||||
|
ifNotM c = flip $ ifM c
|
||||||
|
|
||||||
|
-- | Lazy monadic conjunction.
|
||||||
|
and2M :: Monad m => m Bool -> m Bool -> m Bool
|
||||||
|
and2M ma mb = ifM ma mb (return False)
|
||||||
|
|
||||||
|
andM :: (Foldable f, Monad m) => f (m Bool) -> m Bool
|
||||||
|
andM = Fold.foldr and2M (return True)
|
||||||
|
|
||||||
|
allM :: (Functor f, Foldable f, Monad m) => f a -> (a -> m Bool) -> m Bool
|
||||||
|
allM xs f = andM $ fmap f xs
|
||||||
|
|
||||||
|
-- | Lazy monadic disjunction.
|
||||||
|
or2M :: Monad m => m Bool -> m Bool -> m Bool
|
||||||
|
or2M ma mb = ifM ma (return True) mb
|
||||||
|
|
||||||
|
orM :: (Foldable f, Monad m) => f (m Bool) -> m Bool
|
||||||
|
orM = Fold.foldr or2M (return False)
|
||||||
|
|
||||||
|
anyM :: (Functor f, Foldable f, Monad m) => f a -> (a -> m Bool) -> m Bool
|
||||||
|
anyM xs f = orM $ fmap f xs
|
||||||
|
|||||||
Reference in New Issue
Block a user