parent
a731346656
commit
37e4adc0db
@ -273,6 +273,9 @@ DataProtHeading: Datenschutzerklärung
|
|||||||
SystemMessageHeading: Uni2work Statusmeldung
|
SystemMessageHeading: Uni2work Statusmeldung
|
||||||
SystemMessageListHeading: Uni2work Statusmeldungen
|
SystemMessageListHeading: Uni2work Statusmeldungen
|
||||||
|
|
||||||
|
HomeOpenCourses: Kurse mit offener Registrierung
|
||||||
|
HomeUpcomingSheets: Anstehende Übungsblätter
|
||||||
|
|
||||||
NumCourses num@Int64: #{display num} Kurse
|
NumCourses num@Int64: #{display num} Kurse
|
||||||
CloseAlert: Schliessen
|
CloseAlert: Schliessen
|
||||||
|
|
||||||
|
|||||||
@ -76,6 +76,8 @@ import qualified Database.Memcached.Binary.IO as Memcached
|
|||||||
-- (HPack takes care to add new modules to our cabal file nowadays.)
|
-- (HPack takes care to add new modules to our cabal file nowadays.)
|
||||||
import Handler.Common
|
import Handler.Common
|
||||||
import Handler.Home
|
import Handler.Home
|
||||||
|
import Handler.Info
|
||||||
|
import Handler.Help
|
||||||
import Handler.Profile
|
import Handler.Profile
|
||||||
import Handler.Users
|
import Handler.Users
|
||||||
import Handler.Admin
|
import Handler.Admin
|
||||||
|
|||||||
12
src/Data/List/NonEmpty/Instances.hs
Normal file
12
src/Data/List/NonEmpty/Instances.hs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||||
|
|
||||||
|
module Data.List.NonEmpty.Instances
|
||||||
|
(
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Data.List.NonEmpty
|
||||||
|
|
||||||
|
import Language.Haskell.TH.Syntax (Lift(..))
|
||||||
|
|
||||||
|
instance Lift a => Lift (NonEmpty a) where
|
||||||
|
lift (toList -> xs) = [e|fromList xs|]
|
||||||
67
src/Handler/Help.hs
Normal file
67
src/Handler/Help.hs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
module Handler.Help where
|
||||||
|
|
||||||
|
import Import
|
||||||
|
import Handler.Utils
|
||||||
|
import Jobs
|
||||||
|
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
|
||||||
|
data HelpIdentOptions = HIUser | HIEmail | HIAnonymous
|
||||||
|
deriving (Eq, Ord, Bounded, Enum, Show, Read)
|
||||||
|
|
||||||
|
instance Universe HelpIdentOptions
|
||||||
|
instance Finite HelpIdentOptions
|
||||||
|
|
||||||
|
nullaryPathPiece ''HelpIdentOptions (camelToPathPiece' 1)
|
||||||
|
embedRenderMessage ''UniWorX ''HelpIdentOptions (("Help" <>) . dropPrefix "HI")
|
||||||
|
|
||||||
|
data HelpForm = HelpForm
|
||||||
|
{ hfReferer:: Maybe (Route UniWorX)
|
||||||
|
, hfUserId :: Either (Maybe Address) UserId
|
||||||
|
, hfRequest:: Text
|
||||||
|
}
|
||||||
|
|
||||||
|
helpForm :: Maybe (Route UniWorX) -> Maybe UserId -> AForm _ HelpForm
|
||||||
|
helpForm mReferer mUid = HelpForm
|
||||||
|
<$> aopt routeField (fslI MsgHelpProblemPage & inputReadonly) (Just <$> mReferer)
|
||||||
|
<*> multiActionA (fslI MsgHelpAnswer) identActions (HIUser <$ mUid)
|
||||||
|
<*> (unTextarea <$> areq textareaField (fslI MsgHelpRequest) Nothing)
|
||||||
|
where
|
||||||
|
identActions :: Map _ (AForm _ (Either (Maybe Address) UserId))
|
||||||
|
identActions = Map.fromList $ case mUid of
|
||||||
|
(Just uid) -> (HIUser, pure $ Right uid):defaultActions
|
||||||
|
Nothing -> defaultActions
|
||||||
|
|
||||||
|
defaultActions =
|
||||||
|
[ (HIEmail, Left . Just <$> (Address <$> aopt textField (fslI MsgName) Nothing <*> apreq emailField (fslI MsgEMail) Nothing))
|
||||||
|
, (HIAnonymous, pure $ Left Nothing)
|
||||||
|
]
|
||||||
|
|
||||||
|
getHelpR, postHelpR :: Handler Html
|
||||||
|
getHelpR = postHelpR
|
||||||
|
postHelpR = do
|
||||||
|
mUid <- maybeAuthId
|
||||||
|
mReferer <- flip formResultMaybe return <=< runInputGetResult $ iopt routeField (toPathPiece GetReferer)
|
||||||
|
isModal <- hasCustomHeader HeaderIsModal
|
||||||
|
|
||||||
|
((res,formWidget),formEnctype) <- runFormPost $ renderAForm FormStandard $ helpForm mReferer mUid
|
||||||
|
let form = wrapForm formWidget def
|
||||||
|
{ formAction = Just $ SomeRoute HelpR
|
||||||
|
, formEncoding = formEnctype
|
||||||
|
, formAttrs = [ ("data-ajax-submit", "") | isModal ]
|
||||||
|
}
|
||||||
|
|
||||||
|
formResultModal res HelpR $ \HelpForm{..} -> do
|
||||||
|
now <- liftIO getCurrentTime
|
||||||
|
hfReferer' <- traverse toTextUrl hfReferer
|
||||||
|
queueJob' JobHelpRequest
|
||||||
|
{ jSender = hfUserId
|
||||||
|
, jHelpRequest = hfRequest
|
||||||
|
, jRequestTime = now
|
||||||
|
, jReferer = hfReferer'
|
||||||
|
}
|
||||||
|
tell . pure =<< messageI Success MsgHelpSent
|
||||||
|
|
||||||
|
defaultLayout $ do
|
||||||
|
setTitleI MsgHelpTitle
|
||||||
|
$(widgetFile "help")
|
||||||
@ -4,23 +4,20 @@ import Import
|
|||||||
import Handler.Utils
|
import Handler.Utils
|
||||||
|
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
import qualified Data.Set as Set
|
|
||||||
import qualified Database.Esqueleto as E
|
import qualified Database.Esqueleto as E
|
||||||
|
|
||||||
import Jobs
|
|
||||||
import Development.GitRev
|
|
||||||
|
|
||||||
|
|
||||||
getHomeR :: Handler Html
|
getHomeR :: Handler Html
|
||||||
getHomeR = do
|
getHomeR = do
|
||||||
muid <- maybeAuthId
|
muid <- maybeAuthId
|
||||||
case muid of
|
defaultLayout $ do
|
||||||
Nothing -> homeAnonymous
|
setTitleI MsgHomeHeading
|
||||||
Just uid -> homeUser uid
|
maybe mempty homeUpcomingSheets muid
|
||||||
|
homeOpenCourses
|
||||||
|
|
||||||
|
|
||||||
homeAnonymous :: Handler Html
|
homeOpenCourses :: Widget
|
||||||
homeAnonymous = do
|
homeOpenCourses = do
|
||||||
cTime <- liftIO getCurrentTime
|
cTime <- liftIO getCurrentTime
|
||||||
let tableData :: E.SqlExpr (Entity Course)
|
let tableData :: E.SqlExpr (Entity Course)
|
||||||
-> E.SqlQuery (E.SqlExpr (Entity Course))
|
-> E.SqlQuery (E.SqlExpr (Entity Course))
|
||||||
@ -47,7 +44,7 @@ homeAnonymous = do
|
|||||||
, sortable (Just "deadline") (i18nCell MsgRegisterTo) $ \DBRow{ dbrOutput=Entity{entityVal = course} } ->
|
, sortable (Just "deadline") (i18nCell MsgRegisterTo) $ \DBRow{ dbrOutput=Entity{entityVal = course} } ->
|
||||||
cell $ traverse (formatTime SelFormatDateTime) (courseRegisterTo course) >>= maybe mempty toWidget
|
cell $ traverse (formatTime SelFormatDateTime) (courseRegisterTo course) >>= maybe mempty toWidget
|
||||||
]
|
]
|
||||||
courseTable <- runDB $ dbTableWidget' def DBTable
|
courseTable <- liftHandlerT . runDB $ dbTableWidget' def DBTable
|
||||||
{ dbtSQLQuery = tableData
|
{ dbtSQLQuery = tableData
|
||||||
, dbtRowKey = (E.^. CourseId)
|
, dbtRowKey = (E.^. CourseId)
|
||||||
, dbtColonnade = colonnade
|
, dbtColonnade = colonnade
|
||||||
@ -75,16 +72,12 @@ homeAnonymous = do
|
|||||||
, dbtFilterUI = mempty
|
, dbtFilterUI = mempty
|
||||||
, dbtStyle = def
|
, dbtStyle = def
|
||||||
, dbtParams = def
|
, dbtParams = def
|
||||||
, dbtIdent = "upcomingdeadlines" :: Text
|
, dbtIdent = "open-courses" :: Text
|
||||||
}
|
}
|
||||||
-- let features = $(widgetFile "featureList")
|
$(widgetFile "home/openCourses")
|
||||||
-- addMessage Warning "Vorabversion! Die Implementierung von Uni2work ist noch nicht abgeschlossen!"
|
|
||||||
defaultLayout
|
|
||||||
-- (widgetFile "dsgvDisclaimer")
|
|
||||||
$(widgetFile "home")
|
|
||||||
|
|
||||||
homeUser :: Key User -> Handler Html
|
homeUpcomingSheets :: UserId -> Widget
|
||||||
homeUser uid = do
|
homeUpcomingSheets uid = do
|
||||||
cTime <- liftIO getCurrentTime
|
cTime <- liftIO getCurrentTime
|
||||||
let tableData :: E.LeftOuterJoin
|
let tableData :: E.LeftOuterJoin
|
||||||
(E.InnerJoin (E.InnerJoin (E.SqlExpr (Entity CourseParticipant)) (E.SqlExpr (Entity Course))) (E.SqlExpr (Entity Sheet)))
|
(E.InnerJoin (E.InnerJoin (E.SqlExpr (Entity CourseParticipant)) (E.SqlExpr (Entity Course))) (E.SqlExpr (Entity Sheet)))
|
||||||
@ -140,7 +133,7 @@ homeUser uid = do
|
|||||||
(toWidget $ hasTickmark True)
|
(toWidget $ hasTickmark True)
|
||||||
]
|
]
|
||||||
let validator = def & defaultSorting [SortDescBy "done", SortAscBy "deadline"]
|
let validator = def & defaultSorting [SortDescBy "done", SortAscBy "deadline"]
|
||||||
sheetTable <- runDB $ dbTableWidget' validator DBTable
|
sheetTable <- liftHandlerT . runDB $ dbTableWidget' validator DBTable
|
||||||
{ dbtSQLQuery = tableData
|
{ dbtSQLQuery = tableData
|
||||||
, dbtRowKey = \((_ `E.InnerJoin` _ `E.InnerJoin` sheet) `E.LeftOuterJoin` _) -> sheet E.^. SheetId
|
, dbtRowKey = \((_ `E.InnerJoin` _ `E.InnerJoin` sheet) `E.LeftOuterJoin` _) -> sheet E.^. SheetId
|
||||||
, dbtColonnade = colonnade
|
, dbtColonnade = colonnade
|
||||||
@ -175,155 +168,6 @@ homeUser uid = do
|
|||||||
, dbtFilterUI = mempty
|
, dbtFilterUI = mempty
|
||||||
, dbtStyle = def { dbsEmptyStyle = DBESNoHeading, dbsEmptyMessage = MsgNoUpcomingSheetDeadlines }
|
, dbtStyle = def { dbsEmptyStyle = DBESNoHeading, dbsEmptyMessage = MsgNoUpcomingSheetDeadlines }
|
||||||
, dbtParams = def
|
, dbtParams = def
|
||||||
, dbtIdent = "upcomingdeadlines" :: Text
|
, dbtIdent = "upcoming-sheets" :: Text
|
||||||
}
|
}
|
||||||
-- addMessage Warning "Vorabversion! Die Implementierung von Uni2work ist noch nicht abgeschlossen."
|
$(widgetFile "home/upcomingSheets")
|
||||||
defaultLayout $
|
|
||||||
-- setTitle "Willkommen zum Uni2work Test!"
|
|
||||||
$(widgetFile "homeUser")
|
|
||||||
-- (widgetFile "dsgvDisclaimer")
|
|
||||||
|
|
||||||
-- | Versionsgeschichte
|
|
||||||
getVersionR :: Handler TypedContent
|
|
||||||
getVersionR = getInfoR -- TODO
|
|
||||||
|
|
||||||
-- | Impressum
|
|
||||||
getImpressumR :: Handler Html
|
|
||||||
getImpressumR = -- do
|
|
||||||
siteLayoutMsg' MsgMenuImpressum $ do
|
|
||||||
setTitleI MsgImpressumHeading
|
|
||||||
$(i18nWidgetFile "imprint")
|
|
||||||
|
|
||||||
|
|
||||||
-- | Hinweise zu Datenschutz und Aufbewahrungspflichten
|
|
||||||
getDataProtR :: Handler Html
|
|
||||||
getDataProtR = -- do
|
|
||||||
siteLayoutMsg' MsgMenuDataProt $ do
|
|
||||||
setTitleI MsgDataProtHeading
|
|
||||||
$(i18nWidgetFile "data-protection")
|
|
||||||
|
|
||||||
|
|
||||||
-- | Allgemeine Informationen
|
|
||||||
getInfoR :: Handler TypedContent
|
|
||||||
getInfoR = selectRep $ do
|
|
||||||
let infoHeading = [whamlet|Re-Implementierung von <a href="https://uniworx.ifi.lmu.de/">UniWorX</a>|]
|
|
||||||
provideRep . siteLayout infoHeading $ do
|
|
||||||
let features = $(widgetFile "featureList")
|
|
||||||
gitInfo :: Text
|
|
||||||
gitInfo = $gitDescribe <> " (" <> $gitCommitDate <> ")"
|
|
||||||
changeLog <- withUrlRenderer $(textFile "ChangeLog.md")
|
|
||||||
$(widgetFile "versionHistory")
|
|
||||||
provideRep $
|
|
||||||
return ($gitDescribe :: Text)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
data HelpIdentOptions = HIUser | HIEmail | HIAnonymous
|
|
||||||
deriving (Eq, Ord, Bounded, Enum, Show, Read)
|
|
||||||
|
|
||||||
instance Universe HelpIdentOptions
|
|
||||||
instance Finite HelpIdentOptions
|
|
||||||
|
|
||||||
nullaryPathPiece ''HelpIdentOptions (camelToPathPiece' 1)
|
|
||||||
embedRenderMessage ''UniWorX ''HelpIdentOptions (("Help" <>) . dropPrefix "HI")
|
|
||||||
|
|
||||||
data HelpForm = HelpForm
|
|
||||||
{ hfReferer:: Maybe (Route UniWorX)
|
|
||||||
, hfUserId :: Either (Maybe Address) UserId
|
|
||||||
, hfRequest:: Text
|
|
||||||
}
|
|
||||||
|
|
||||||
helpForm :: Maybe (Route UniWorX) -> Maybe UserId -> AForm _ HelpForm
|
|
||||||
helpForm mReferer mUid = HelpForm
|
|
||||||
<$> aopt routeField (fslI MsgHelpProblemPage & inputReadonly) (Just <$> mReferer)
|
|
||||||
<*> multiActionA (fslI MsgHelpAnswer) identActions (HIUser <$ mUid)
|
|
||||||
<*> (unTextarea <$> areq textareaField (fslI MsgHelpRequest) Nothing)
|
|
||||||
where
|
|
||||||
identActions :: Map _ (AForm _ (Either (Maybe Address) UserId))
|
|
||||||
identActions = Map.fromList $ case mUid of
|
|
||||||
(Just uid) -> (HIUser, pure $ Right uid):defaultActions
|
|
||||||
Nothing -> defaultActions
|
|
||||||
|
|
||||||
defaultActions =
|
|
||||||
[ (HIEmail, Left . Just <$> (Address <$> aopt textField (fslI MsgName) Nothing <*> apreq emailField (fslI MsgEMail) Nothing))
|
|
||||||
, (HIAnonymous, pure $ Left Nothing)
|
|
||||||
]
|
|
||||||
|
|
||||||
getHelpR, postHelpR :: Handler Html
|
|
||||||
getHelpR = postHelpR
|
|
||||||
postHelpR = do
|
|
||||||
mUid <- maybeAuthId
|
|
||||||
mReferer <- flip formResultMaybe return <=< runInputGetResult $ iopt routeField (toPathPiece GetReferer)
|
|
||||||
isModal <- hasCustomHeader HeaderIsModal
|
|
||||||
|
|
||||||
((res,formWidget),formEnctype) <- runFormPost $ renderAForm FormStandard $ helpForm mReferer mUid
|
|
||||||
let form = wrapForm formWidget def
|
|
||||||
{ formAction = Just $ SomeRoute HelpR
|
|
||||||
, formEncoding = formEnctype
|
|
||||||
, formAttrs = [ ("data-ajax-submit", "") | isModal ]
|
|
||||||
}
|
|
||||||
|
|
||||||
formResultModal res HelpR $ \HelpForm{..} -> do
|
|
||||||
now <- liftIO getCurrentTime
|
|
||||||
hfReferer' <- traverse toTextUrl hfReferer
|
|
||||||
queueJob' JobHelpRequest
|
|
||||||
{ jSender = hfUserId
|
|
||||||
, jHelpRequest = hfRequest
|
|
||||||
, jRequestTime = now
|
|
||||||
, jReferer = hfReferer'
|
|
||||||
}
|
|
||||||
tell . pure =<< messageI Success MsgHelpSent
|
|
||||||
|
|
||||||
defaultLayout $ do
|
|
||||||
setTitleI MsgHelpTitle
|
|
||||||
$(widgetFile "help")
|
|
||||||
|
|
||||||
|
|
||||||
getInfoLecturerR :: Handler Html
|
|
||||||
getInfoLecturerR =
|
|
||||||
siteLayoutMsg' MsgInfoLecturerTitle $ do
|
|
||||||
setTitleI MsgInfoLecturerTitle
|
|
||||||
$(i18nWidgetFile "info-lecturer")
|
|
||||||
|
|
||||||
|
|
||||||
getAuthPredsR, postAuthPredsR :: Handler Html
|
|
||||||
getAuthPredsR = postAuthPredsR
|
|
||||||
postAuthPredsR = do
|
|
||||||
(AuthTagActive authTagCurrentActive) <- fromMaybe def <$> lookupSessionJson SessionActiveAuthTags
|
|
||||||
|
|
||||||
let
|
|
||||||
blacklist = Set.fromList [ AuthFree, AuthDevelopment, AuthDeprecated ]
|
|
||||||
taForm authTag
|
|
||||||
| authTag `Set.member` blacklist = aforced checkBoxField (fslI authTag) (authTagIsActive def authTag)
|
|
||||||
| otherwise = fromMaybe False <$> aopt checkBoxField (fslI authTag) (Just . Just $ authTagCurrentActive authTag)
|
|
||||||
|
|
||||||
((authActiveRes, authActiveWidget), authActiveEnctype) <- runFormPost . renderAForm FormStandard
|
|
||||||
$ AuthTagActive <$> funcForm taForm (fslI MsgActiveAuthTags) True
|
|
||||||
|
|
||||||
mReferer <- runMaybeT $ do
|
|
||||||
param <- MaybeT (lookupGetParam $ toPathPiece GetReferer) <|> MaybeT (lookupPostParam $ toPathPiece GetReferer)
|
|
||||||
MaybeT . return $ fromPathPiece param
|
|
||||||
|
|
||||||
let authActiveForm = wrapForm authActiveWidget' def
|
|
||||||
{ formAction = Just $ SomeRoute AuthPredsR
|
|
||||||
, formEncoding = authActiveEnctype
|
|
||||||
, formSubmit = FormDualSubmit
|
|
||||||
}
|
|
||||||
authActiveWidget'
|
|
||||||
= [whamlet|
|
|
||||||
$newline never
|
|
||||||
$maybe referer <- mReferer
|
|
||||||
<input type=hidden name=#{toPathPiece GetReferer} value=#{toPathPiece referer}>
|
|
||||||
^{authActiveWidget}
|
|
||||||
|]
|
|
||||||
|
|
||||||
formResult authActiveRes $ \authTagActive -> do
|
|
||||||
setSessionJson SessionActiveAuthTags authTagActive
|
|
||||||
modifySessionJson SessionInactiveAuthTags . fmap $ Set.filter (not . authTagIsActive authTagActive)
|
|
||||||
addMessageI Success MsgAuthPredsActiveChanged
|
|
||||||
redirect $ fromMaybe AuthPredsR mReferer
|
|
||||||
|
|
||||||
siteLayoutMsg MsgAuthPredsActive $ do
|
|
||||||
setTitleI MsgAuthPredsActive
|
|
||||||
$(widgetFile "authpreds")
|
|
||||||
|
|||||||
48
src/Handler/Info.hs
Normal file
48
src/Handler/Info.hs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
module Handler.Info where
|
||||||
|
|
||||||
|
import Import
|
||||||
|
import Handler.Utils
|
||||||
|
|
||||||
|
import Development.GitRev
|
||||||
|
|
||||||
|
-- | Versionsgeschichte
|
||||||
|
getVersionR :: Handler TypedContent
|
||||||
|
getVersionR = selectRep $ do
|
||||||
|
provideRep $
|
||||||
|
return ($gitDescribe :: Text)
|
||||||
|
provideRep getInfoR
|
||||||
|
|
||||||
|
-- | Impressum
|
||||||
|
getImpressumR :: Handler Html
|
||||||
|
getImpressumR = -- do
|
||||||
|
siteLayoutMsg' MsgMenuImpressum $ do
|
||||||
|
setTitleI MsgImpressumHeading
|
||||||
|
$(i18nWidgetFile "imprint")
|
||||||
|
|
||||||
|
|
||||||
|
-- | Hinweise zu Datenschutz und Aufbewahrungspflichten
|
||||||
|
getDataProtR :: Handler Html
|
||||||
|
getDataProtR = -- do
|
||||||
|
siteLayoutMsg' MsgMenuDataProt $ do
|
||||||
|
setTitleI MsgDataProtHeading
|
||||||
|
$(i18nWidgetFile "data-protection")
|
||||||
|
|
||||||
|
|
||||||
|
-- | Allgemeine Informationen
|
||||||
|
getInfoR :: Handler Html
|
||||||
|
getInfoR = do
|
||||||
|
let infoHeading = [whamlet|Re-Implementierung von <a href="https://uniworx.ifi.lmu.de/">UniWorX</a>|]
|
||||||
|
siteLayout infoHeading $ do
|
||||||
|
let features = $(widgetFile "featureList")
|
||||||
|
gitInfo :: Text
|
||||||
|
gitInfo = $gitDescribe <> " (" <> $gitCommitDate <> ")"
|
||||||
|
changeLog <- withUrlRenderer $(textFile "ChangeLog.md")
|
||||||
|
$(widgetFile "versionHistory")
|
||||||
|
|
||||||
|
|
||||||
|
getInfoLecturerR :: Handler Html
|
||||||
|
getInfoLecturerR =
|
||||||
|
siteLayoutMsg' MsgInfoLecturerTitle $ do
|
||||||
|
setTitleI MsgInfoLecturerTitle
|
||||||
|
$(i18nWidgetFile "info-lecturer")
|
||||||
|
|
||||||
@ -10,7 +10,7 @@ import Utils.Lens
|
|||||||
-- import Yesod.Colonnade
|
-- import Yesod.Colonnade
|
||||||
import Data.Monoid (Any(..))
|
import Data.Monoid (Any(..))
|
||||||
import qualified Data.Map as Map
|
import qualified Data.Map as Map
|
||||||
-- import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
import qualified Database.Esqueleto as E
|
import qualified Database.Esqueleto as E
|
||||||
-- import Database.Esqueleto ((^.))
|
-- import Database.Esqueleto ((^.))
|
||||||
|
|
||||||
@ -491,3 +491,44 @@ mkCorrectionsTable =
|
|||||||
in \uid -> let dbtSQLQuery = dbtSQLQuery' uid
|
in \uid -> let dbtSQLQuery = dbtSQLQuery' uid
|
||||||
in dbTableWidget' validator DBTable{..}
|
in dbTableWidget' validator DBTable{..}
|
||||||
|
|
||||||
|
|
||||||
|
getAuthPredsR, postAuthPredsR :: Handler Html
|
||||||
|
getAuthPredsR = postAuthPredsR
|
||||||
|
postAuthPredsR = do
|
||||||
|
(AuthTagActive authTagCurrentActive) <- fromMaybe def <$> lookupSessionJson SessionActiveAuthTags
|
||||||
|
|
||||||
|
let
|
||||||
|
blacklist = Set.fromList [ AuthFree, AuthDevelopment, AuthDeprecated ]
|
||||||
|
taForm authTag
|
||||||
|
| authTag `Set.member` blacklist = aforced checkBoxField (fslI authTag) (authTagIsActive def authTag)
|
||||||
|
| otherwise = fromMaybe False <$> aopt checkBoxField (fslI authTag) (Just . Just $ authTagCurrentActive authTag)
|
||||||
|
|
||||||
|
((authActiveRes, authActiveWidget), authActiveEnctype) <- runFormPost . renderAForm FormStandard
|
||||||
|
$ AuthTagActive <$> funcForm taForm (fslI MsgActiveAuthTags) True
|
||||||
|
|
||||||
|
mReferer <- runMaybeT $ do
|
||||||
|
param <- MaybeT (lookupGetParam $ toPathPiece GetReferer) <|> MaybeT (lookupPostParam $ toPathPiece GetReferer)
|
||||||
|
MaybeT . return $ fromPathPiece param
|
||||||
|
|
||||||
|
let authActiveForm = wrapForm authActiveWidget' def
|
||||||
|
{ formAction = Just $ SomeRoute AuthPredsR
|
||||||
|
, formEncoding = authActiveEnctype
|
||||||
|
, formSubmit = FormDualSubmit
|
||||||
|
}
|
||||||
|
authActiveWidget'
|
||||||
|
= [whamlet|
|
||||||
|
$newline never
|
||||||
|
$maybe referer <- mReferer
|
||||||
|
<input type=hidden name=#{toPathPiece GetReferer} value=#{toPathPiece referer}>
|
||||||
|
^{authActiveWidget}
|
||||||
|
|]
|
||||||
|
|
||||||
|
formResult authActiveRes $ \authTagActive -> do
|
||||||
|
setSessionJson SessionActiveAuthTags authTagActive
|
||||||
|
modifySessionJson SessionInactiveAuthTags . fmap $ Set.filter (not . authTagIsActive authTagActive)
|
||||||
|
addMessageI Success MsgAuthPredsActiveChanged
|
||||||
|
redirect $ fromMaybe AuthPredsR mReferer
|
||||||
|
|
||||||
|
siteLayoutMsg MsgAuthPredsActive $ do
|
||||||
|
setTitleI MsgAuthPredsActive
|
||||||
|
$(widgetFile "authpreds")
|
||||||
|
|||||||
@ -10,7 +10,8 @@ import qualified Data.Set as Set
|
|||||||
import Data.CaseInsensitive (original)
|
import Data.CaseInsensitive (original)
|
||||||
-- import qualified Data.CaseInsensitive as CI
|
-- import qualified Data.CaseInsensitive as CI
|
||||||
|
|
||||||
import Language.Haskell.TH (Q, Exp)
|
import Language.Haskell.TH
|
||||||
|
import Language.Haskell.TH.Syntax (qRunIO)
|
||||||
-- import Language.Haskell.TH.Datatype
|
-- import Language.Haskell.TH.Datatype
|
||||||
|
|
||||||
import Text.Hamlet (shamletFile)
|
import Text.Hamlet (shamletFile)
|
||||||
@ -26,6 +27,12 @@ import Handler.Utils.Rating as Handler.Utils hiding (extractRatings)
|
|||||||
import Handler.Utils.Sheet as Handler.Utils
|
import Handler.Utils.Sheet as Handler.Utils
|
||||||
import Handler.Utils.Mail as Handler.Utils
|
import Handler.Utils.Mail as Handler.Utils
|
||||||
|
|
||||||
|
import System.Directory (listDirectory)
|
||||||
|
import System.FilePath.Posix (takeBaseName)
|
||||||
|
|
||||||
|
import qualified Data.List as List
|
||||||
|
import qualified Data.List.NonEmpty as NonEmpty
|
||||||
|
|
||||||
|
|
||||||
downloadFiles :: (MonadHandler m, HandlerSite m ~ UniWorX) => m Bool
|
downloadFiles :: (MonadHandler m, HandlerSite m ~ UniWorX) => m Bool
|
||||||
downloadFiles = do
|
downloadFiles = do
|
||||||
@ -140,6 +147,15 @@ warnTermDays tid times = do
|
|||||||
-- which contains a file for each language,
|
-- which contains a file for each language,
|
||||||
-- eg. /templates/imprint/de.hamlet and /templates/imprint/en.hamlet
|
-- eg. /templates/imprint/de.hamlet and /templates/imprint/en.hamlet
|
||||||
i18nWidgetFile :: FilePath -> Q Exp
|
i18nWidgetFile :: FilePath -> Q Exp
|
||||||
i18nWidgetFile =
|
i18nWidgetFile basename = do
|
||||||
-- TODO write code to distinguish languages here
|
let i18nDirectory = "templates" </> basename
|
||||||
widgetFile . (</> "de")
|
availableFiles <- qRunIO $ listDirectory i18nDirectory
|
||||||
|
let availableTranslations = sortWith (NTop . flip List.elemIndex (NonEmpty.toList appLanguages)) . List.nub $ pack . takeBaseName <$> availableFiles
|
||||||
|
availableTranslations' <- maybe (fail $ "‘" <> i18nDirectory <> "’ is empty") return $ NonEmpty.nonEmpty availableTranslations
|
||||||
|
|
||||||
|
ws <- newName "ws"
|
||||||
|
letE
|
||||||
|
[ funD ws $ [ clause [litP $ stringL l] (normalB . widgetFile $ basename </> l) []
|
||||||
|
| l <- unpack <$> NonEmpty.toList availableTranslations'
|
||||||
|
] ++ [ clause [wildP] (normalB [e| error "selectLanguage returned an invalid translation" |]) [] ]
|
||||||
|
] [e|selectLanguage availableTranslations' >>= $(varE ws)|]
|
||||||
|
|||||||
@ -42,7 +42,8 @@ import GHC.Exts as Import (IsList)
|
|||||||
|
|
||||||
import Data.Hashable as Import
|
import Data.Hashable as Import
|
||||||
import Data.List.NonEmpty as Import (NonEmpty(..))
|
import Data.List.NonEmpty as Import (NonEmpty(..))
|
||||||
import Data.Text.Encoding.Error as Import(UnicodeException(..))
|
import Data.List.NonEmpty.Instances as Import ()
|
||||||
|
import Data.Text.Encoding.Error as Import(UnicodeException(..))
|
||||||
import Data.Semigroup as Import (Semigroup)
|
import Data.Semigroup as Import (Semigroup)
|
||||||
import Data.Monoid as Import (Last(..), First(..))
|
import Data.Monoid as Import (Last(..), First(..))
|
||||||
import Data.Monoid.Instances as Import ()
|
import Data.Monoid.Instances as Import ()
|
||||||
|
|||||||
@ -1,5 +0,0 @@
|
|||||||
<div .container>
|
|
||||||
<h2>
|
|
||||||
Kurse mit offener Registrierung
|
|
||||||
<div .container>
|
|
||||||
^{courseTable}
|
|
||||||
3
templates/home/openCourses.hamlet
Normal file
3
templates/home/openCourses.hamlet
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<section>
|
||||||
|
<h2>_{MsgHomeOpenCourses}
|
||||||
|
^{courseTable}
|
||||||
3
templates/home/upcomingSheets.hamlet
Normal file
3
templates/home/upcomingSheets.hamlet
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<section>
|
||||||
|
<h2>_{MsgHomeUpcomingSheets}
|
||||||
|
^{sheetTable}
|
||||||
@ -1,17 +0,0 @@
|
|||||||
<div .container>
|
|
||||||
<h2>
|
|
||||||
Anstehende Übungsblätter
|
|
||||||
<div .container>
|
|
||||||
^{sheetTable}
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<div .container>
|
|
||||||
<h1>
|
|
||||||
Anstehende Klausuren
|
|
||||||
TODO
|
|
||||||
|
|
||||||
<div .container>
|
|
||||||
<h1>
|
|
||||||
Anstehende Kursanmeldungen
|
|
||||||
TODO
|
|
||||||
-->
|
|
||||||
Reference in New Issue
Block a user