fradrive/src/Handler/Help.hs
2022-10-12 09:35:16 +02:00

121 lines
4.1 KiB
Haskell

-- SPDX-FileCopyrightText: 2022 Gregor Kleen <gregor.kleen@ifi.lmu.de>,Sarah Vaupel <sarah.vaupel@ifi.lmu.de>,Sarah Vaupel <vaupel.sarah@campus.lmu.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
module Handler.Help where
import Import
import Handler.Utils
import Handler.Info (faqsWidget)
import Jobs
import qualified Data.Map as Map
import qualified Data.Yaml as Yaml
import qualified Control.Monad.State.Class as State
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
, hfSubject :: Maybe Text
, hfRequest :: Maybe Html
, hfError :: Maybe ErrorResponse
}
helpForm :: Maybe (Route UniWorX) -> Maybe UserId -> Form HelpForm
helpForm mReferer mUid = renderWForm FormStandard $ do
MsgRenderer mr <- getMsgRenderer
let defaultActions =
[ ( HIEmail
, Left . Just <$> (Address <$> aopt textField (fslpI MsgHelpName (mr MsgHelpName) & addAttr "autocomplete" "name") Nothing <*> apreq emailField (fslpI MsgHelpEmail (mr MsgEMail) & addAttr "autocomplete" "email") Nothing)
)
, ( HIAnonymous
, pure $ Left Nothing
)
]
identActions :: Map _ (AForm _ (Either (Maybe Address) UserId))
identActions = Map.fromList $ case mUid of
(Just uid) -> (HIUser, pure $ Right uid):defaultActions
Nothing -> defaultActions
sessErr <- lookupSessionJson SessionError
hfReferer' <- wopt routeField (fslI MsgHelpProblemPage & inputReadonly) (Just <$> mReferer)
hfUserId' <- multiActionW identActions (fslI MsgHelpAnswer) (HIUser <$ mUid)
hfSubject' <- wopt textField (fslpI MsgHelpSubject $ mr MsgHelpSubject) Nothing
wformMessage =<< messageWidget Info $(i18nWidgetFile "help-instructions")
hfRequest' <- case sessErr of
Nothing -> fmap Just <$> wreq htmlField (fslpI MsgHelpRequest $ mr MsgHelpRequest) Nothing
Just _ -> wopt htmlField (fslpI MsgHelpRequest $ mr MsgHelpRequest) Nothing
hfError' <- case sessErr of
Nothing -> return $ pure Nothing
Just err ->
let prettyErr = decodeUtf8 $ Yaml.encode err
in optionalActionW
(err <$ aforced textareaField (fslI MsgHelpError) (Textarea prettyErr))
(fslI MsgHelpSendLastError)
(Just True)
return $ HelpForm
<$> hfReferer'
<*> hfUserId'
<*> hfSubject'
<*> (fmap markupOutput <$> hfRequest')
<*> hfError'
validateHelpForm :: FormValidator HelpForm Handler ()
validateHelpForm = do
HelpForm{..} <- State.get
guardValidation MsgHelpErrorOrRequestRequired $ is _Just hfRequest || is _Just hfError
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 . validateForm validateHelpForm $ helpForm mReferer mUid
formResultModal res HelpR $ \HelpForm{..} -> do
now <- liftIO getCurrentTime
hfReferer' <- traverse toTextUrl hfReferer
queueJob' JobHelpRequest
{ jHelpSender = hfUserId
, jSubject = hfSubject
, jHelpRequest = hfRequest
, jRequestTime = now
, jReferer = hfReferer'
, jError = hfError
}
whenIsJust hfError $ \error' ->
modifySessionJson SessionError $ assertM (/= error')
tell . pure =<< messageI Success MsgHelpSent
defaultLayout $ do
setTitleI MsgHelpTitle
let formWidget = wrapForm formWidget' def
{ formAction = Just $ SomeRoute HelpR
, formEncoding = formEnctype
, formAttrs = [ asyncSubmitAttr | isModal ]
}
mFaqs <- (>>= \(mWgt, truncated) -> (, truncated) <$> mWgt) <$> traverse (faqsWidget $ Just 5) (Just <$> mReferer)
$(widgetFile "help")