Merge branch 'master' into 205-klausuren
Fix tests
This commit is contained in:
commit
b63d77ec7b
@ -1,5 +1,5 @@
|
|||||||
[Dolphin]
|
[Dolphin]
|
||||||
Timestamp=2018,3,14,10,57,55
|
Timestamp=2019,6,26,19,32,25
|
||||||
Version=4
|
Version=4
|
||||||
|
|
||||||
[Settings]
|
[Settings]
|
||||||
|
|||||||
@ -203,6 +203,7 @@ SheetErrHintEarly: Hinweise dürfen erst nach Beginn des Abgabezeitraums herausg
|
|||||||
SheetErrSolutionEarly: Lösungen dürfen erst nach Ende der Abgabezeitraums herausgegeben werden
|
SheetErrSolutionEarly: Lösungen dürfen erst nach Ende der Abgabezeitraums herausgegeben werden
|
||||||
SheetNoCurrent: Es gibt momentan kein aktives Übungsblatt.
|
SheetNoCurrent: Es gibt momentan kein aktives Übungsblatt.
|
||||||
SheetNoOldUnassigned: Alle Abgaben inaktiver Blätter sind bereits einen Korrektor zugeteilt.
|
SheetNoOldUnassigned: Alle Abgaben inaktiver Blätter sind bereits einen Korrektor zugeteilt.
|
||||||
|
SheetsUnassignable name@Text: Momentan keine Abgaben zuteilbar für #{name}
|
||||||
|
|
||||||
Deadline: Abgabe
|
Deadline: Abgabe
|
||||||
Done: Eingereicht
|
Done: Eingereicht
|
||||||
@ -323,7 +324,7 @@ Correctors: Korrektoren
|
|||||||
CorState: Status
|
CorState: Status
|
||||||
CorByTut: Zuteilung nach Tutorium
|
CorByTut: Zuteilung nach Tutorium
|
||||||
CorProportion: Anteil
|
CorProportion: Anteil
|
||||||
CorDeficit: Defizit
|
CorDeficitProportion: Defizit Anteile
|
||||||
CorByProportionOnly proportion@Rational: #{display proportion} Anteile
|
CorByProportionOnly proportion@Rational: #{display proportion} Anteile
|
||||||
CorByProportionIncludingTutorial proportion@Rational: #{display proportion} Anteile - Tutorium
|
CorByProportionIncludingTutorial proportion@Rational: #{display proportion} Anteile - Tutorium
|
||||||
CorByProportionExcludingTutorial proportion@Rational: #{display proportion} Anteile + Tutorium
|
CorByProportionExcludingTutorial proportion@Rational: #{display proportion} Anteile + Tutorium
|
||||||
@ -404,6 +405,7 @@ UpdatedSheetCorrectorsAutoFailed n@Int: #{display n} #{pluralDE n "Abgabe konnte
|
|||||||
CouldNotAssignCorrectorsAuto num@Int64: #{display num} Abgaben konnten nicht automatisch zugewiesen werden:
|
CouldNotAssignCorrectorsAuto num@Int64: #{display num} Abgaben konnten nicht automatisch zugewiesen werden:
|
||||||
SelfCorrectors num@Int64: #{display num} Abgaben wurden Abgebenden als eigenem Korrektor zugeteilt!
|
SelfCorrectors num@Int64: #{display num} Abgaben wurden Abgebenden als eigenem Korrektor zugeteilt!
|
||||||
|
|
||||||
|
|
||||||
CorrectionSheets: Übersicht Korrekturen nach Blättern
|
CorrectionSheets: Übersicht Korrekturen nach Blättern
|
||||||
CorrectionCorrectors: Übersicht Korrekturen nach Korrektoren
|
CorrectionCorrectors: Übersicht Korrekturen nach Korrektoren
|
||||||
AssignSubmissionExceptionNoCorrectors: Es sind keine Korrektoren eingestellt
|
AssignSubmissionExceptionNoCorrectors: Es sind keine Korrektoren eingestellt
|
||||||
|
|||||||
@ -160,6 +160,7 @@ deriving instance Generic SheetR
|
|||||||
deriving instance Generic SubmissionR
|
deriving instance Generic SubmissionR
|
||||||
deriving instance Generic MaterialR
|
deriving instance Generic MaterialR
|
||||||
deriving instance Generic TutorialR
|
deriving instance Generic TutorialR
|
||||||
|
deriving instance Generic ExamR
|
||||||
deriving instance Generic (Route UniWorX)
|
deriving instance Generic (Route UniWorX)
|
||||||
|
|
||||||
-- | Convenient Type Synonyms:
|
-- | Convenient Type Synonyms:
|
||||||
@ -1494,7 +1495,7 @@ instance YesodBreadcrumbs UniWorX where
|
|||||||
breadcrumb (CourseR tid ssh csh CInviteR) = return ("Einladung", Just $ CourseR tid ssh csh CShowR)
|
breadcrumb (CourseR tid ssh csh CInviteR) = return ("Einladung", Just $ CourseR tid ssh csh CShowR)
|
||||||
breadcrumb (CourseR tid ssh csh (CUserR _)) = return ("Teilnehmer" , Just $ CourseR tid ssh csh CUsersR)
|
breadcrumb (CourseR tid ssh csh (CUserR _)) = return ("Teilnehmer" , Just $ CourseR tid ssh csh CUsersR)
|
||||||
breadcrumb (CourseR tid ssh csh CCorrectionsR) = return ("Abgaben" , Just $ CourseR tid ssh csh CShowR)
|
breadcrumb (CourseR tid ssh csh CCorrectionsR) = return ("Abgaben" , Just $ CourseR tid ssh csh CShowR)
|
||||||
breadcrumb (CourseR tid ssh csh CAssignR) = return ("Zuteilung" , Just $ CourseR tid ssh csh CCorrectionsR)
|
breadcrumb (CourseR tid ssh csh CAssignR) = return ("Zuteilung Korrekturen" , Just $ CourseR tid ssh csh CCorrectionsR)
|
||||||
breadcrumb (CourseR tid ssh csh SheetListR) = return ("Übungen" , Just $ CourseR tid ssh csh CShowR)
|
breadcrumb (CourseR tid ssh csh SheetListR) = return ("Übungen" , Just $ CourseR tid ssh csh CShowR)
|
||||||
breadcrumb (CourseR tid ssh csh SheetNewR ) = return ("Neu", Just $ CourseR tid ssh csh SheetListR)
|
breadcrumb (CourseR tid ssh csh SheetNewR ) = return ("Neu", Just $ CourseR tid ssh csh SheetListR)
|
||||||
breadcrumb (CourseR tid ssh csh SheetCurrentR) = return ("Aktuelles Blatt", Just $ CourseR tid ssh csh SheetListR)
|
breadcrumb (CourseR tid ssh csh SheetCurrentR) = return ("Aktuelles Blatt", Just $ CourseR tid ssh csh SheetListR)
|
||||||
@ -1518,7 +1519,7 @@ instance YesodBreadcrumbs UniWorX where
|
|||||||
breadcrumb (CSheetR tid ssh csh shn SEditR) = return ("Bearbeiten" , Just $ CSheetR tid ssh csh shn SShowR)
|
breadcrumb (CSheetR tid ssh csh shn SEditR) = return ("Bearbeiten" , Just $ CSheetR tid ssh csh shn SShowR)
|
||||||
breadcrumb (CSheetR tid ssh csh shn SDelR ) = return ("Löschen" , Just $ CSheetR tid ssh csh shn SShowR)
|
breadcrumb (CSheetR tid ssh csh shn SDelR ) = return ("Löschen" , Just $ CSheetR tid ssh csh shn SShowR)
|
||||||
breadcrumb (CSheetR tid ssh csh shn SSubsR) = return ("Abgaben" , Just $ CSheetR tid ssh csh shn SShowR)
|
breadcrumb (CSheetR tid ssh csh shn SSubsR) = return ("Abgaben" , Just $ CSheetR tid ssh csh shn SShowR)
|
||||||
breadcrumb (CSheetR tid ssh csh shn SAssignR) = return ("Zuteilen" , Just $ CSheetR tid ssh csh shn SSubsR)
|
breadcrumb (CSheetR tid ssh csh shn SAssignR) = return ("Zuteilung Korrekturen" , Just $ CSheetR tid ssh csh shn SSubsR)
|
||||||
breadcrumb (CSheetR tid ssh csh shn SubmissionNewR) = return ("Abgabe", Just $ CSheetR tid ssh csh shn SShowR)
|
breadcrumb (CSheetR tid ssh csh shn SubmissionNewR) = return ("Abgabe", Just $ CSheetR tid ssh csh shn SShowR)
|
||||||
breadcrumb (CSheetR tid ssh csh shn SubmissionOwnR) = return ("Abgabe", Just $ CSheetR tid ssh csh shn SShowR)
|
breadcrumb (CSheetR tid ssh csh shn SubmissionOwnR) = return ("Abgabe", Just $ CSheetR tid ssh csh shn SShowR)
|
||||||
breadcrumb (CSubmissionR tid ssh csh shn _ SubShowR) = return ("Abgabe", Just $ CSheetR tid ssh csh shn SShowR)
|
breadcrumb (CSubmissionR tid ssh csh shn _ SubShowR) = return ("Abgabe", Just $ CSheetR tid ssh csh shn SShowR)
|
||||||
|
|||||||
@ -165,7 +165,7 @@ postAdminTestR = do
|
|||||||
|
|
||||||
-- | Make a form for adding a point/line/plane/hyperplane/... (in this case: cell)
|
-- | Make a form for adding a point/line/plane/hyperplane/... (in this case: cell)
|
||||||
--
|
--
|
||||||
-- This /needs/ to replace all occurences of @mreq@ with @mpreq@ (no fields should be /actually/ required)
|
-- This /needs/ to replace all occurrences of @mreq@ with @mpreq@ (no fields should be /actually/ required)
|
||||||
mkAddForm :: ListPosition -- ^ Approximate position of the add-widget
|
mkAddForm :: ListPosition -- ^ Approximate position of the add-widget
|
||||||
-> Natural -- ^ Dimension Index, outermost dimension ist 0 i.e. if dimension is 3 hyperplane-adders get passed 0, planes get passed 1, lines get 2, and points get 3
|
-> Natural -- ^ Dimension Index, outermost dimension ist 0 i.e. if dimension is 3 hyperplane-adders get passed 0, planes get passed 1, lines get 2, and points get 3
|
||||||
-> (Text -> Text) -- ^ Nudge deterministic field ids so they're unique
|
-> (Text -> Text) -- ^ Nudge deterministic field ids so they're unique
|
||||||
|
|||||||
@ -1052,11 +1052,8 @@ data SubAssignInfo = SubAssignInfo { saiName :: SheetName, saiSubmissionNr, saiC
|
|||||||
getCAssignR, postCAssignR :: TermId -> SchoolId -> CourseShorthand -> Handler Html
|
getCAssignR, postCAssignR :: TermId -> SchoolId -> CourseShorthand -> Handler Html
|
||||||
getCAssignR = postCAssignR
|
getCAssignR = postCAssignR
|
||||||
postCAssignR tid ssh csh = do
|
postCAssignR tid ssh csh = do
|
||||||
(shids,cid) <- runDB $ do
|
cid <- runDB $ getKeyBy404 $ TermSchoolCourseShort tid ssh csh
|
||||||
cid <- getKeyBy404 $ TermSchoolCourseShort tid ssh csh
|
assignHandler tid ssh csh cid []
|
||||||
shids <- selectKeysList [SheetCourse ==. cid] [Asc SheetActiveTo]
|
|
||||||
return (shids,cid)
|
|
||||||
assignHandler tid ssh csh cid shids
|
|
||||||
|
|
||||||
getSAssignR, postSAssignR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler Html
|
getSAssignR, postSAssignR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> Handler Html
|
||||||
getSAssignR = postSAssignR
|
getSAssignR = postSAssignR
|
||||||
@ -1064,51 +1061,13 @@ postSAssignR tid ssh csh shn = do
|
|||||||
(shid,cid) <- runDB $ fetchSheetIdCourseId tid ssh csh shn
|
(shid,cid) <- runDB $ fetchSheetIdCourseId tid ssh csh shn
|
||||||
assignHandler tid ssh csh cid [shid]
|
assignHandler tid ssh csh cid [shid]
|
||||||
|
|
||||||
-- DEPRECATED assignHandler', delete me soonish
|
{- TODO: Feature:
|
||||||
assignHandler' :: TermId -> SchoolId -> CourseShorthand -> CourseId -> [SheetId] -> Handler Html
|
make distivt buttons for each sheet, so that users see which sheet will be assigned.
|
||||||
assignHandler' tid ssh csh _cid rawSids = do
|
Currently this information is available within the page heading!
|
||||||
-- gather data
|
|
||||||
openSubs <- runDB $ (\f -> foldM f Map.empty rawSids) $
|
|
||||||
\acc sid -> maybeT (return acc) $ do
|
|
||||||
Just Sheet{sheetName=saiName} <- lift $ get sid
|
|
||||||
guardM $ lift $ hasWriteAccessTo $ CSheetR tid ssh csh saiName SAssignR -- we must check, whether the submission is already closed and thus assignable
|
|
||||||
saiUnassignedNr <- lift $ count [SubmissionSheet ==. sid, SubmissionRatingBy ==. Nothing]
|
|
||||||
guard $ 0 < saiUnassignedNr -- only consider sheets with unassigned submissions
|
|
||||||
saiSubmissionNr <- lift $ count [SubmissionSheet ==. sid]
|
|
||||||
saiCorrectorNr <- lift $ count [SheetCorrectorSheet ==. sid, SheetCorrectorState ==. CorrectorNormal]
|
|
||||||
-- guard $ saiCorrectorNr > 0 -- COMMENTED OUT BECAUSE we should show sheets without possible correctors to inform the user about these problematic sheets
|
|
||||||
return $ Map.insert sid SubAssignInfo{..} acc
|
|
||||||
let sids = Map.keys openSubs
|
|
||||||
linkBack <- simpleLinkI (SomeMessage MsgGenericBack) <$> case sids of
|
|
||||||
[sid] -> do Sheet{sheetName} <- runDB $ getJust sid
|
|
||||||
return $ CSheetR tid ssh csh sheetName SSubsR
|
|
||||||
_ -> return $ CourseR tid ssh csh CCorrectionsR
|
|
||||||
-- process form
|
|
||||||
currentRoute <- getCurrentRoute
|
|
||||||
((btnResult, btnWdgt), btnEnctype) <- runFormPost $ identifyForm FIDAssignSubmissions buttonForm
|
|
||||||
assignmentStatus <- fmap (fromMaybe Map.empty) . formResultMaybe btnResult $ \BtnSubmissionsAssign ->
|
|
||||||
-- Assign submissions
|
|
||||||
fmap Just . runDB $ (\f -> foldM f Map.empty sids) $
|
|
||||||
\acc sid -> flip (Map.insert sid) acc <$> assignSubmissions sid Nothing
|
|
||||||
-- Too much important information for an alert message. Display proper info page instead
|
|
||||||
let btnForm = wrapForm btnWdgt def
|
|
||||||
{ formAction = SomeRoute <$> currentRoute
|
|
||||||
, formEncoding = btnEnctype
|
|
||||||
, formSubmit = FormNoSubmit
|
|
||||||
}
|
|
||||||
headingShort = MsgMenuCorrectionsAssign
|
|
||||||
headingLong = prependCourseTitle tid ssh csh MsgMenuCorrectionsAssign
|
|
||||||
siteLayoutMsg headingShort $ do
|
|
||||||
setTitleI headingLong
|
|
||||||
$(widgetFile "corrections-assign")
|
|
||||||
if null sids || not (null assignmentStatus)
|
|
||||||
then linkBack -- TODO: convenience link might be unnecessary: either via breadcrumb or closing model. Remove, if modal works fine. Otherwise change to PrimaryAction?
|
|
||||||
else btnForm
|
|
||||||
|
|
||||||
|
Stub:
|
||||||
{- TODO: make buttons for each sheet, so that users see which sheet is assigned
|
|
||||||
data ButtonCorrectionsAssign = BtnCorrectionsAssignAll | BtnCorrectionsAssignSheet SheetName
|
data ButtonCorrectionsAssign = BtnCorrectionsAssignAll | BtnCorrectionsAssignSheet SheetName
|
||||||
deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable)
|
deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable)
|
||||||
instance Button UniWorX ButtonCorrectionsAssign
|
instance Button UniWorX ButtonCorrectionsAssign
|
||||||
-- Are those needed any more?
|
-- Are those needed any more?
|
||||||
instance Universe ButtonCorrectionsAssign
|
instance Universe ButtonCorrectionsAssign
|
||||||
@ -1126,7 +1085,7 @@ assignHandler tid ssh csh cid assignSids = do
|
|||||||
(btnWdgt, btnResult) <- runButtonForm FIDAssignSubmissions
|
(btnWdgt, btnResult) <- runButtonForm FIDAssignSubmissions
|
||||||
|
|
||||||
-- gather data
|
-- gather data
|
||||||
(nrParticipants, groupsPossible, infoMap, correctorMap, assignment) <- runDB $ do
|
(assignSheetNames, nrParticipants, groupsPossible, infoMap, correctorMap, assignment) <- runDB $ do
|
||||||
-- cid <- getKeyBy404 $ TermSchoolCourseShort tid ssh csh
|
-- cid <- getKeyBy404 $ TermSchoolCourseShort tid ssh csh
|
||||||
nrParticipants <- count [CourseParticipantCourse ==. cid]
|
nrParticipants <- count [CourseParticipantCourse ==. cid]
|
||||||
|
|
||||||
@ -1137,6 +1096,7 @@ assignHandler tid ssh csh cid assignSids = do
|
|||||||
groupsPossible =
|
groupsPossible =
|
||||||
let foldFun (Entity _ Sheet{sheetGrouping=sgr}) acc = acc || sgr /= NoGroups
|
let foldFun (Entity _ Sheet{sheetGrouping=sgr}) acc = acc || sgr /= NoGroups
|
||||||
in List.foldr foldFun False sheetList
|
in List.foldr foldFun False sheetList
|
||||||
|
assignSheetNames = fmap sheetName $ mapMaybe (\sid -> Map.lookup sid sheets) assignSids
|
||||||
|
|
||||||
-- plan or assign unassigned submissions for given sheets
|
-- plan or assign unassigned submissions for given sheets
|
||||||
let buildA :: (Map SheetName ((Set SubmissionId, Set SubmissionId), Map (Maybe UserId) Int, Map UserId Rational)) -> SheetId -> DB (Map SheetName ((Set SubmissionId, Set SubmissionId), Map (Maybe UserId) Int, Map UserId Rational))
|
let buildA :: (Map SheetName ((Set SubmissionId, Set SubmissionId), Map (Maybe UserId) Int, Map UserId Rational)) -> SheetId -> DB (Map SheetName ((Set SubmissionId, Set SubmissionId), Map (Maybe UserId) Int, Map UserId Rational))
|
||||||
@ -1166,7 +1126,10 @@ assignHandler tid ssh csh cid assignSids = do
|
|||||||
addMessageI msg_status $ UniWorXMessages $ msg_header : catMaybes [alert_ok, alert_fail]
|
addMessageI msg_status $ UniWorXMessages $ msg_header : catMaybes [alert_ok, alert_fail]
|
||||||
return status
|
return status
|
||||||
return $ Map.insert shn (status, countMapElems plan, deficit) acc
|
return $ Map.insert shn (status, countMapElems plan, deficit) acc
|
||||||
assignment <- foldM buildA Map.empty assignSids
|
assignSids' <- if null assignSids -- assignAll; we distinguish assignSids' here avoid useless Alerts
|
||||||
|
then selectKeysList [SheetCourse ==. cid] [Asc SheetActiveTo]
|
||||||
|
else return assignSids
|
||||||
|
assignment <- foldM buildA Map.empty assignSids'
|
||||||
|
|
||||||
correctors <- E.select . E.from $ \(corrector `E.InnerJoin` user) -> do
|
correctors <- E.select . E.from $ \(corrector `E.InnerJoin` user) -> do
|
||||||
E.on $ corrector E.^. SheetCorrectorUser E.==. user E.^. UserId
|
E.on $ corrector E.^. SheetCorrectorUser E.==. user E.^. UserId
|
||||||
@ -1210,10 +1173,13 @@ assignHandler tid ssh csh cid assignSids = do
|
|||||||
}
|
}
|
||||||
in Map.insertWith (Map.unionWith (<>)) shnm cinf m
|
in Map.insertWith (Map.unionWith (<>)) shnm cinf m
|
||||||
|
|
||||||
return (nrParticipants, groupsPossible, infoMap, correctorMap, assignment)
|
return (assignSheetNames, nrParticipants, groupsPossible, infoMap, correctorMap, assignment)
|
||||||
|
|
||||||
let -- infoMap :: Map SheetName (Map (Maybe UserId) CorrectionInfo) -- repeated here for easier reference
|
let -- infoMap :: Map SheetName (Map (Maybe UserId) CorrectionInfo) -- repeated here for easier reference
|
||||||
-- create aggregate maps
|
-- create aggregate maps
|
||||||
|
sheetNames :: [SheetName]
|
||||||
|
sheetNames = Map.keys infoMap
|
||||||
|
|
||||||
sheetMap :: Map SheetName CorrectionInfo
|
sheetMap :: Map SheetName CorrectionInfo
|
||||||
sheetMap = Map.map fold infoMap
|
sheetMap = Map.map fold infoMap
|
||||||
|
|
||||||
@ -1230,7 +1196,10 @@ assignHandler tid ssh csh cid assignSids = do
|
|||||||
|
|
||||||
corrMap :: Map (Maybe UserId) CorrectionInfo
|
corrMap :: Map (Maybe UserId) CorrectionInfo
|
||||||
corrMap = Map.unionsWith (<>) $ Map.elems infoMap
|
corrMap = Map.unionsWith (<>) $ Map.elems infoMap
|
||||||
sheetNames = Map.keys infoMap
|
|
||||||
|
corrMapSum :: CorrectionInfo
|
||||||
|
corrMapSum = fold corrMap
|
||||||
|
|
||||||
let -- whamlet convenience functions
|
let -- whamlet convenience functions
|
||||||
-- avoid nestes hamlet $maybe with duplicated $nothing
|
-- avoid nestes hamlet $maybe with duplicated $nothing
|
||||||
getCorrector :: Maybe UserId -> (Widget,Map SheetName SheetCorrector)
|
getCorrector :: Maybe UserId -> (Widget,Map SheetName SheetCorrector)
|
||||||
@ -1256,10 +1225,9 @@ assignHandler tid ssh csh cid assignSids = do
|
|||||||
getCorrDeficit _ = Nothing
|
getCorrDeficit _ = Nothing
|
||||||
|
|
||||||
getLoadSum :: SheetName -> Text
|
getLoadSum :: SheetName -> Text
|
||||||
getLoadSum shn
|
getLoadSum shn | (Just load) <- Map.lookup shn sheetLoad
|
||||||
| (Just load) <- Map.lookup shn sheetLoad
|
= showCompactCorrectorLoad load CorrectorNormal
|
||||||
= "Σ" <> showCompactCorrectorLoad load CorrectorNormal
|
getLoadSum _ = mempty
|
||||||
getLoadSum _ = mempty
|
|
||||||
|
|
||||||
showDiffDays :: Maybe NominalDiffTime -> Text
|
showDiffDays :: Maybe NominalDiffTime -> Text
|
||||||
showDiffDays = foldMap formatDiffDays
|
showDiffDays = foldMap formatDiffDays
|
||||||
@ -1272,6 +1240,10 @@ assignHandler tid ssh csh cid assignSids = do
|
|||||||
| 0 < Map.size assignment = MsgMenuCorrectionsAssignSheet $ Text.intercalate ", " $ fmap CI.original $ Map.keys assignment
|
| 0 < Map.size assignment = MsgMenuCorrectionsAssignSheet $ Text.intercalate ", " $ fmap CI.original $ Map.keys assignment
|
||||||
| otherwise = MsgMenuCorrectionsAssign
|
| otherwise = MsgMenuCorrectionsAssign
|
||||||
headingLong = prependCourseTitle tid ssh csh MsgMenuCorrectionsAssign
|
headingLong = prependCourseTitle tid ssh csh MsgMenuCorrectionsAssign
|
||||||
|
|
||||||
|
unassignableSheets = filter (\shn -> Map.notMember shn assignment) assignSheetNames
|
||||||
|
unless (null unassignableSheets) $ addMessageI Warning $ MsgSheetsUnassignable $ Text.intercalate ", " $ fmap CI.original unassignableSheets
|
||||||
|
|
||||||
siteLayoutMsg headingShort $ do
|
siteLayoutMsg headingShort $ do
|
||||||
setTitleI headingLong
|
setTitleI headingLong
|
||||||
$(widgetFile "corrections-overview")
|
$(widgetFile "corrections-overview")
|
||||||
|
|||||||
@ -63,7 +63,7 @@ getHealthR = do
|
|||||||
<dd .deflist__dd>#{boolSymbol passed}
|
<dd .deflist__dd>#{boolSymbol passed}
|
||||||
$of HealthLDAPAdmins (Just found)
|
$of HealthLDAPAdmins (Just found)
|
||||||
<dt .deflist__dt>_{MsgHealthLDAPAdmins}
|
<dt .deflist__dt>_{MsgHealthLDAPAdmins}
|
||||||
<dd .deflist__dd>#{textPercent found}
|
<dd .deflist__dd>#{textPercent found 1}
|
||||||
$of HealthSMTPConnect (Just passed)
|
$of HealthSMTPConnect (Just passed)
|
||||||
<dt .deflist__dt>_{MsgHealthSMTPConnect}
|
<dt .deflist__dt>_{MsgHealthSMTPConnect}
|
||||||
<dd .deflist__dd>#{boolSymbol passed}
|
<dd .deflist__dd>#{boolSymbol passed}
|
||||||
@ -80,7 +80,7 @@ getInstanceR = do
|
|||||||
instanceInfo@(clusterId, instanceId) <- getsYesod $ (,) <$> appClusterID <*> appInstanceID
|
instanceInfo@(clusterId, instanceId) <- getsYesod $ (,) <$> appClusterID <*> appInstanceID
|
||||||
|
|
||||||
setWeakEtagHashable (clusterId, instanceId)
|
setWeakEtagHashable (clusterId, instanceId)
|
||||||
|
|
||||||
selectRep $ do
|
selectRep $ do
|
||||||
provideRep $
|
provideRep $
|
||||||
siteLayoutMsg MsgInstanceIdentification $ do
|
siteLayoutMsg MsgInstanceIdentification $ do
|
||||||
|
|||||||
@ -66,6 +66,6 @@ postHelpR = do
|
|||||||
let formWidget = wrapForm formWidget' def
|
let formWidget = wrapForm formWidget' def
|
||||||
{ formAction = Just $ SomeRoute HelpR
|
{ formAction = Just $ SomeRoute HelpR
|
||||||
, formEncoding = formEnctype
|
, formEncoding = formEnctype
|
||||||
, formAttrs = [ ("data-ajax-submit", "") | isModal ]
|
, formAttrs = [ asyncSubmitAttr | isModal ]
|
||||||
}
|
}
|
||||||
$(widgetFile "help")
|
$(widgetFile "help")
|
||||||
|
|||||||
@ -147,7 +147,7 @@ postProfileR = do
|
|||||||
|
|
||||||
siteLayout [whamlet|_{MsgProfileFor} ^{nameWidget userDisplayName userSurname}|] $ do
|
siteLayout [whamlet|_{MsgProfileFor} ^{nameWidget userDisplayName userSurname}|] $ do
|
||||||
setTitle . toHtml $ "Profil " <> userIdent
|
setTitle . toHtml $ "Profil " <> userIdent
|
||||||
let settingsForm =
|
let settingsForm =
|
||||||
wrapForm formWidget FormSettings
|
wrapForm formWidget FormSettings
|
||||||
{ formMethod = POST
|
{ formMethod = POST
|
||||||
, formAction = Just . SomeRoute $ ProfileR :#: ProfileSettings
|
, formAction = Just . SomeRoute $ ProfileR :#: ProfileSettings
|
||||||
@ -593,7 +593,7 @@ postUserNotificationR cID = do
|
|||||||
let formWidget = wrapForm nsInnerWdgt def
|
let formWidget = wrapForm nsInnerWdgt def
|
||||||
{ formAction = Just . SomeRoute $ UserNotificationR cID
|
{ formAction = Just . SomeRoute $ UserNotificationR cID
|
||||||
, formEncoding = nsEnc
|
, formEncoding = nsEnc
|
||||||
, formAttrs = [ ("data-ajax-submit", "") | isModal ]
|
, formAttrs = [ asyncSubmitAttr | isModal ]
|
||||||
}
|
}
|
||||||
|
|
||||||
formResultModal nsRes (UserNotificationR cID, [ (toPathPiece GetBearer, toPathPiece jwt) | Just jwt <- pure mJwt ]) $ \ns -> do
|
formResultModal nsRes (UserNotificationR cID, [ (toPathPiece GetBearer, toPathPiece jwt) | Just jwt <- pure mJwt ]) $ \ns -> do
|
||||||
|
|||||||
@ -257,9 +257,7 @@ getSheetListR tid ssh csh = do
|
|||||||
(Just (Entity _ Submission{submissionRatingPoints=Just sPoints})) ->
|
(Just (Entity _ Submission{submissionRatingPoints=Just sPoints})) ->
|
||||||
case preview (_grading . _maxPoints) sType of
|
case preview (_grading . _maxPoints) sType of
|
||||||
Just maxPoints
|
Just maxPoints
|
||||||
| maxPoints /= 0 ->
|
| maxPoints /= 0 -> textCell $ textPercent sPoints maxPoints
|
||||||
let percent = sPoints / maxPoints
|
|
||||||
in textCell $ textPercent $ realToFrac percent
|
|
||||||
_other -> mempty
|
_other -> mempty
|
||||||
_other -> mempty
|
_other -> mempty
|
||||||
]
|
]
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import qualified Data.Map as Map
|
|||||||
|
|
||||||
import Utils.Lens
|
import Utils.Lens
|
||||||
|
|
||||||
|
|
||||||
data OccurrenceScheduleKind = ScheduleKindWeekly
|
data OccurrenceScheduleKind = ScheduleKindWeekly
|
||||||
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
|
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
|
||||||
|
|
||||||
@ -36,7 +36,7 @@ embedRenderMessage ''UniWorX ''OccurrenceExceptionKind id
|
|||||||
occurrencesAForm :: PathPiece ident => ident -> Maybe Occurrences -> AForm Handler Occurrences
|
occurrencesAForm :: PathPiece ident => ident -> Maybe Occurrences -> AForm Handler Occurrences
|
||||||
occurrencesAForm (toPathPiece -> miIdent') mPrev = wFormToAForm $ do
|
occurrencesAForm (toPathPiece -> miIdent') mPrev = wFormToAForm $ do
|
||||||
Just cRoute <- getCurrentRoute
|
Just cRoute <- getCurrentRoute
|
||||||
|
|
||||||
let
|
let
|
||||||
scheduled :: AForm Handler (Set OccurrenceSchedule)
|
scheduled :: AForm Handler (Set OccurrenceSchedule)
|
||||||
scheduled = Set.fromList <$> massInputAccumA
|
scheduled = Set.fromList <$> massInputAccumA
|
||||||
@ -89,13 +89,13 @@ occurrencesAForm (toPathPiece -> miIdent') mPrev = wFormToAForm $ do
|
|||||||
miAdd' nudge submitView = over (mapped . mapped . _2) (\addWidget -> $(widgetFile "widgets/occurrence/form/except-add")) . renderAForm FormStandard . wFormToAForm $ do
|
miAdd' nudge submitView = over (mapped . mapped . _2) (\addWidget -> $(widgetFile "widgets/occurrence/form/except-add")) . renderAForm FormStandard . wFormToAForm $ do
|
||||||
newExc <- multiActionW
|
newExc <- multiActionW
|
||||||
(Map.fromList [ ( ExceptionKindOccur
|
(Map.fromList [ ( ExceptionKindOccur
|
||||||
, ExceptOccurr
|
, ExceptOccur
|
||||||
<$> apreq dayField (fslI MsgDay & addName (nudge "occur-day")) Nothing
|
<$> apreq dayField (fslI MsgDay & addName (nudge "occur-day")) Nothing
|
||||||
<*> apreq timeFieldTypeTime (fslI MsgOccurrenceStart & addName (nudge "occur-start")) Nothing
|
<*> apreq timeFieldTypeTime (fslI MsgOccurrenceStart & addName (nudge "occur-start")) Nothing
|
||||||
<*> apreq timeFieldTypeTime (fslI MsgOccurrenceEnd & addName (nudge "occur-end")) Nothing
|
<*> apreq timeFieldTypeTime (fslI MsgOccurrenceEnd & addName (nudge "occur-end")) Nothing
|
||||||
)
|
)
|
||||||
, ( ExceptionKindNoOccur
|
, ( ExceptionKindNoOccur
|
||||||
, ExceptNoOccurr
|
, ExceptNoOccur
|
||||||
<$> apreq localTimeField (fslI MsgExceptionNoOccurAt & addName (nudge "no-occur-time")) Nothing
|
<$> apreq localTimeField (fslI MsgExceptionNoOccurAt & addName (nudge "no-occur-time")) Nothing
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -104,14 +104,14 @@ occurrencesAForm (toPathPiece -> miIdent') mPrev = wFormToAForm $ do
|
|||||||
return $ newExc <&> \newExc' oldExcs -> if
|
return $ newExc <&> \newExc' oldExcs -> if
|
||||||
| newExc' `elem` oldExcs -> FormFailure [mr MsgExceptionExists]
|
| newExc' `elem` oldExcs -> FormFailure [mr MsgExceptionExists]
|
||||||
| otherwise -> FormSuccess $ pure newExc'
|
| otherwise -> FormSuccess $ pure newExc'
|
||||||
|
|
||||||
|
|
||||||
miCell' :: OccurrenceException -> Widget
|
miCell' :: OccurrenceException -> Widget
|
||||||
miCell' ExceptOccurr{..} = do
|
miCell' ExceptOccur{..} = do
|
||||||
exceptStart' <- formatTime SelFormatDateTime (LocalTime exceptDay exceptStart)
|
exceptStart' <- formatTime SelFormatDateTime (LocalTime exceptDay exceptStart)
|
||||||
exceptEnd' <- formatTime SelFormatTime exceptEnd
|
exceptEnd' <- formatTime SelFormatTime exceptEnd
|
||||||
$(widgetFile "widgets/occurrence/form/except-occur")
|
$(widgetFile "widgets/occurrence/form/except-occur")
|
||||||
miCell' ExceptNoOccurr{..} = do
|
miCell' ExceptNoOccur{..} = do
|
||||||
exceptTime' <- formatTime SelFormatDateTime exceptTime
|
exceptTime' <- formatTime SelFormatDateTime exceptTime
|
||||||
$(widgetFile "widgets/occurrence/form/except-no-occur")
|
$(widgetFile "widgets/occurrence/form/except-no-occur")
|
||||||
|
|
||||||
|
|||||||
@ -256,11 +256,11 @@ occurrencesCell (normalizeOccurrences -> Occurrences{..}) = cell $ do
|
|||||||
scheduleEnd' <- formatTime SelFormatTime scheduleEnd
|
scheduleEnd' <- formatTime SelFormatTime scheduleEnd
|
||||||
$(widgetFile "widgets/occurrence/cell/weekly")
|
$(widgetFile "widgets/occurrence/cell/weekly")
|
||||||
occurrencesExceptions' = flip map (Set.toList occurrencesExceptions) $ \case
|
occurrencesExceptions' = flip map (Set.toList occurrencesExceptions) $ \case
|
||||||
ExceptOccurr{..} -> do
|
ExceptOccur{..} -> do
|
||||||
exceptStart' <- formatTime SelFormatDateTime (LocalTime exceptDay exceptStart)
|
exceptStart' <- formatTime SelFormatDateTime (LocalTime exceptDay exceptStart)
|
||||||
exceptEnd' <- formatTime SelFormatTime exceptStart
|
exceptEnd' <- formatTime SelFormatTime exceptStart
|
||||||
$(widgetFile "widgets/occurrence/cell/except-occurr")
|
$(widgetFile "widgets/occurrence/cell/except-occur")
|
||||||
ExceptNoOccurr{..} -> do
|
ExceptNoOccur{..} -> do
|
||||||
exceptTime' <- formatTime SelFormatDateTime exceptTime
|
exceptTime' <- formatTime SelFormatDateTime exceptTime
|
||||||
$(widgetFile "widgets/occurrence/cell/except-no-occurr")
|
$(widgetFile "widgets/occurrence/cell/except-no-occur")
|
||||||
$(widgetFile "widgets/occurrence/cell")
|
$(widgetFile "widgets/occurrence/cell")
|
||||||
|
|||||||
@ -166,14 +166,14 @@ deriveJSON defaultOptions
|
|||||||
, sumEncoding = TaggedObject "repeat" "schedule"
|
, sumEncoding = TaggedObject "repeat" "schedule"
|
||||||
} ''OccurrenceSchedule
|
} ''OccurrenceSchedule
|
||||||
|
|
||||||
data OccurrenceException = ExceptOccurr
|
data OccurrenceException = ExceptOccur
|
||||||
{ exceptDay :: Day
|
{ exceptDay :: Day
|
||||||
, exceptStart :: TimeOfDay
|
, exceptStart :: TimeOfDay
|
||||||
, exceptEnd :: TimeOfDay
|
, exceptEnd :: TimeOfDay
|
||||||
}
|
}
|
||||||
| ExceptNoOccurr
|
| ExceptNoOccur
|
||||||
{ exceptTime :: LocalTime
|
{ exceptTime :: LocalTime
|
||||||
}
|
}
|
||||||
deriving (Eq, Ord, Read, Show, Generic, Typeable)
|
deriving (Eq, Ord, Read, Show, Generic, Typeable)
|
||||||
|
|
||||||
deriveJSON defaultOptions
|
deriveJSON defaultOptions
|
||||||
|
|||||||
34
src/Utils.hs
34
src/Utils.hs
@ -2,12 +2,13 @@ module Utils
|
|||||||
( module Utils
|
( module Utils
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import ClassyPrelude.Yesod hiding (foldlM)
|
import ClassyPrelude.Yesod hiding (foldlM, Proxy)
|
||||||
|
|
||||||
-- import Data.Double.Conversion.Text -- faster implementation for textPercent?
|
-- import Data.Double.Conversion.Text -- faster implementation for textPercent?
|
||||||
import qualified Data.Foldable as Fold
|
import qualified Data.Foldable as Fold
|
||||||
import Data.Foldable as Utils (foldlM, foldrM)
|
import Data.Foldable as Utils (foldlM, foldrM)
|
||||||
import Data.Monoid (Sum(..))
|
import Data.Monoid (Sum(..))
|
||||||
|
import Data.Proxy
|
||||||
|
|
||||||
import Data.CaseInsensitive (CI)
|
import Data.CaseInsensitive (CI)
|
||||||
import qualified Data.CaseInsensitive as CI
|
import qualified Data.CaseInsensitive as CI
|
||||||
@ -67,7 +68,7 @@ import qualified Crypto.Saltine.Class as Saltine
|
|||||||
import qualified Crypto.Data.PKCS7 as PKCS7
|
import qualified Crypto.Data.PKCS7 as PKCS7
|
||||||
|
|
||||||
import Data.Fixed
|
import Data.Fixed
|
||||||
import Data.Ratio ((%))
|
-- import Data.Ratio ((%))
|
||||||
|
|
||||||
import Data.Binary (Binary)
|
import Data.Binary (Binary)
|
||||||
import qualified Data.Binary as Binary
|
import qualified Data.Binary as Binary
|
||||||
@ -309,15 +310,28 @@ instance {-# OVERLAPPABLE #-} Show a => DisplayAble a where -- The easy way out
|
|||||||
display = pack . show
|
display = pack . show
|
||||||
-}
|
-}
|
||||||
|
|
||||||
textPercent :: Real a => a -> Text -- slow, maybe use Data.Double.Conversion.Text.toFixed instead?
|
-- | Convert `part` and `whole` into percentage including symbol
|
||||||
textPercent x = lz <> pack (show rx) <> "%"
|
-- showing trailing zeroes and to decimal digits
|
||||||
where
|
textPercent :: Real a => a -> a -> Text
|
||||||
rx :: Centi
|
textPercent = textPercent' False 2
|
||||||
rx = realToFrac (x * 100)
|
|
||||||
lz = if rx < 10.0 then "0" else ""
|
-- | Convert `part` and `whole` into percentage including symbol
|
||||||
|
-- `trailZero` shows trailing Zeros, `precision` is number of decimal digits
|
||||||
|
textPercent' :: Real a => Bool -> Int -> a -> a -> Text
|
||||||
|
textPercent' trailZero precision part whole
|
||||||
|
| precision == 0 = showPercent (frac :: Uni)
|
||||||
|
| precision == 1 = showPercent (frac :: Deci)
|
||||||
|
| precision == 2 = showPercent (frac :: Centi)
|
||||||
|
| precision == 3 = showPercent (frac :: Milli)
|
||||||
|
| precision == 4 = showPercent (frac :: Micro)
|
||||||
|
| otherwise = showPercent (frac :: Pico)
|
||||||
|
where
|
||||||
|
frac :: forall a . HasResolution a => Fixed a
|
||||||
|
frac = MkFixed $ round $ (* (fromInteger $ resolution (Proxy :: Proxy a))) $ (100*) $ toRational part / toRational whole
|
||||||
|
|
||||||
|
showPercent :: HasResolution a => Fixed a -> Text
|
||||||
|
showPercent f = pack $ showFixed trailZero f <> "%"
|
||||||
|
|
||||||
textPercentInt :: Integral a => a -> a -> Text -- slow, maybe use Data.Double.Conversion.Text.toFixed instead?
|
|
||||||
textPercentInt part whole = textPercent $ fromIntegral part % fromIntegral whole
|
|
||||||
|
|
||||||
-- | Convert number of bytes to human readable format
|
-- | Convert number of bytes to human readable format
|
||||||
textBytes :: Integral a => a -> Text
|
textBytes :: Integral a => a -> Text
|
||||||
|
|||||||
@ -168,6 +168,11 @@ inputReadonly = addAttr "readonly" ""
|
|||||||
addAutosubmit :: FieldSettings site -> FieldSettings site
|
addAutosubmit :: FieldSettings site -> FieldSettings site
|
||||||
addAutosubmit = addAttr "uw-auto-submit-input" ""
|
addAutosubmit = addAttr "uw-auto-submit-input" ""
|
||||||
|
|
||||||
|
-- | Asynchronous Submit, e.g. use with forms in modals
|
||||||
|
asyncSubmitAttr :: (Text,Text)
|
||||||
|
asyncSubmitAttr = ("uw-async-form", "")
|
||||||
|
|
||||||
|
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
-- Unique Form Identifiers to avoid accidents --
|
-- Unique Form Identifiers to avoid accidents --
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|||||||
@ -137,6 +137,6 @@ makeLenses_ ''UTCTime
|
|||||||
|
|
||||||
class HasInstanceID s a | s -> a where
|
class HasInstanceID s a | s -> a where
|
||||||
instanceID :: Lens' s a
|
instanceID :: Lens' s a
|
||||||
|
|
||||||
class HasJSONWebKeySet s a | s -> a where
|
class HasJSONWebKeySet s a | s -> a where
|
||||||
jsonWebKeySet :: Lens' s a
|
jsonWebKeySet :: Lens' s a
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import Data.Time.Calendar.WeekDate
|
|||||||
|
|
||||||
|
|
||||||
normalizeOccurrences :: Occurrences -> Occurrences
|
normalizeOccurrences :: Occurrences -> Occurrences
|
||||||
-- ^
|
-- ^
|
||||||
--
|
--
|
||||||
-- - Removes unnecessary exceptions
|
-- - Removes unnecessary exceptions
|
||||||
-- - Merges overlapping schedules
|
-- - Merges overlapping schedules
|
||||||
@ -57,7 +57,7 @@ normalizeOccurrences initial
|
|||||||
|
|
||||||
exceptions <- view _occurrencesExceptions
|
exceptions <- view _occurrencesExceptions
|
||||||
forM_ exceptions $ \case
|
forM_ exceptions $ \case
|
||||||
needle@ExceptNoOccurr{..} -> do
|
needle@ExceptNoOccur{..} -> do
|
||||||
let LocalTime{..} = exceptTime
|
let LocalTime{..} = exceptTime
|
||||||
(_, _, toEnum . (`mod` 7) -> localWeekDay) = toWeekDate localDay
|
(_, _, toEnum . (`mod` 7) -> localWeekDay) = toWeekDate localDay
|
||||||
needed <- views _occurrencesScheduled . any $ \case
|
needed <- views _occurrencesScheduled . any $ \case
|
||||||
@ -68,10 +68,10 @@ normalizeOccurrences initial
|
|||||||
]
|
]
|
||||||
unless needed $
|
unless needed $
|
||||||
throwE =<< asks (over _occurrencesExceptions $ Set.delete needle)
|
throwE =<< asks (over _occurrencesExceptions $ Set.delete needle)
|
||||||
needle@ExceptOccurr{..} -> do
|
needle@ExceptOccur{..} -> do
|
||||||
let (_, _, toEnum . (`mod` 7) -> localWeekDay) = toWeekDate exceptDay
|
let (_, _, toEnum . (`mod` 7) -> localWeekDay) = toWeekDate exceptDay
|
||||||
-- | Does this ExceptNoOccur target within needle?
|
-- | Does this ExceptNoOccur target within needle?
|
||||||
withinNeedle ExceptNoOccurr{..} = LocalTime exceptDay exceptStart <= exceptTime
|
withinNeedle ExceptNoOccur{..} = LocalTime exceptDay exceptStart <= exceptTime
|
||||||
&& exceptTime <= LocalTime exceptDay exceptEnd
|
&& exceptTime <= LocalTime exceptDay exceptEnd
|
||||||
withinNeedle _ = False
|
withinNeedle _ = False
|
||||||
needed <- views _occurrencesScheduled . none $ \case
|
needed <- views _occurrencesScheduled . none $ \case
|
||||||
|
|||||||
@ -48,4 +48,6 @@ extra-deps:
|
|||||||
|
|
||||||
- filepath-1.4.2
|
- filepath-1.4.2
|
||||||
|
|
||||||
|
- haskell-src-exts-util-0.2.1.2
|
||||||
|
|
||||||
resolver: lts-10.5
|
resolver: lts-10.5
|
||||||
|
|||||||
@ -45,7 +45,7 @@
|
|||||||
<tr .table__row .table__row--head>
|
<tr .table__row .table__row--head>
|
||||||
<th .table__th rowspan=2>_{MsgCorrector}
|
<th .table__th rowspan=2>_{MsgCorrector}
|
||||||
<th .table__th colspan=2>_{MsgGenericAll}
|
<th .table__th colspan=2>_{MsgGenericAll}
|
||||||
<th .table__th>_{MsgCorProportion}
|
<th .table__th rowspan=2>_{MsgCorDeficitProportion}
|
||||||
<th .table__th colspan=3>_{MsgCorrectionTime}
|
<th .table__th colspan=3>_{MsgCorrectionTime}
|
||||||
$forall shn <- sheetNames
|
$forall shn <- sheetNames
|
||||||
<th .table__th colspan=5>#{shn}
|
<th .table__th colspan=5>#{shn}
|
||||||
@ -53,7 +53,6 @@
|
|||||||
<tr .table__row .table__row--head>
|
<tr .table__row .table__row--head>
|
||||||
<th .table__th>_{MsgNrSubmissionsTotal}
|
<th .table__th>_{MsgNrSubmissionsTotal}
|
||||||
<th .table__th>_{MsgNrSubmissionsNotCorrected}
|
<th .table__th>_{MsgNrSubmissionsNotCorrected}
|
||||||
<th .table__th>_{MsgCorDeficit}
|
|
||||||
<th .table__th>_{MsgGenericMin}
|
<th .table__th>_{MsgGenericMin}
|
||||||
<th .table__th>_{MsgGenericAvg}
|
<th .table__th>_{MsgGenericAvg}
|
||||||
<th .table__th>_{MsgGenericMax}
|
<th .table__th>_{MsgGenericMax}
|
||||||
@ -63,24 +62,33 @@
|
|||||||
<th .table__th>_{MsgGenericNumChange}
|
<th .table__th>_{MsgGenericNumChange}
|
||||||
<th .table__th>_{MsgNrSubmissionsNotCorrectedShort}
|
<th .table__th>_{MsgNrSubmissionsNotCorrectedShort}
|
||||||
<th .table__th>_{MsgGenericAvg}
|
<th .table__th>_{MsgGenericAvg}
|
||||||
$forall (CorrectionInfo{ciCorrector, ciSubmissions, ciCorrected, ciMin, ciTot, ciMax}) <- Map.elems corrMap
|
$forall (CorrectionInfo{ciCorrector, ciSubmissions=ciSubmissionsNr, ciCorrected, ciMin, ciTot, ciMax}) <- Map.elems corrMap
|
||||||
$with (nameW,loadM) <- getCorrector ciCorrector
|
$with (nameW,loadM) <- getCorrector ciCorrector
|
||||||
<tr .table__row>
|
<tr .table__row>
|
||||||
<td .table__td>^{nameW}
|
<td .table__td>^{nameW}
|
||||||
<td .table__td>#{ciSubmissions}
|
<td .table__td>#{ciSubmissionsNr}
|
||||||
<td .table__td .heated style="--hotness: #{heat ciSubmissions ciCorrected}">#{ciSubmissions - ciCorrected}
|
$with total <- ciSubmissions corrMapSum
|
||||||
|
$if total > 0
|
||||||
|
\ (#{textPercent' True 0 ciSubmissionsNr total})
|
||||||
|
<td .table__td .heated style="--hotness: #{heat ciSubmissionsNr ciCorrected}">#{ciSubmissionsNr - ciCorrected}
|
||||||
<td .table__td>
|
<td .table__td>
|
||||||
$maybe deficit <- getCorrDeficit ciCorrector
|
$maybe deficit <- getCorrDeficit ciCorrector
|
||||||
#{display deficit}
|
#{display deficit}
|
||||||
<td .table__td>#{showDiffDays ciMin}
|
<td .table__td>#{showDiffDays ciMin}
|
||||||
<td .table__td>#{showAvgsDays ciTot ciCorrected}
|
<td .table__td>#{showAvgsDays ciTot ciCorrected}
|
||||||
<td .table__td>#{showDiffDays ciMax}
|
<td .table__td>#{showDiffDays ciMax}
|
||||||
$forall shn <- sheetNames
|
$forall (shn, CorrectionInfo{ciSubmissions=sheetSubmissionsNr}) <- Map.toList sheetMap
|
||||||
<td .table__td>
|
<td .table__td>
|
||||||
$maybe SheetCorrector{sheetCorrectorLoad, sheetCorrectorState} <- Map.lookup shn loadM
|
$maybe SheetCorrector{sheetCorrectorLoad, sheetCorrectorState} <- Map.lookup shn loadM
|
||||||
#{showCompactCorrectorLoad sheetCorrectorLoad sheetCorrectorState}
|
#{showCompactCorrectorLoad sheetCorrectorLoad sheetCorrectorState}
|
||||||
|
$if sheetCorrectorState == CorrectorNormal
|
||||||
|
$maybe Load{byProportion=total} <- Map.lookup shn sheetLoad
|
||||||
|
$if total > 0
|
||||||
|
\ (#{textPercent' True 0 (byProportion sheetCorrectorLoad) total})
|
||||||
$maybe CorrectionInfo{ciSubmissions,ciCorrected,ciTot} <- getCorrSheetStatus ciCorrector shn
|
$maybe CorrectionInfo{ciSubmissions,ciCorrected,ciTot} <- getCorrSheetStatus ciCorrector shn
|
||||||
<td .table__td>#{ciSubmissions}
|
<td .table__td>#{ciSubmissions}
|
||||||
|
$if sheetSubmissionsNr > 0
|
||||||
|
\ (#{textPercent' True 0 ciSubmissions sheetSubmissionsNr})
|
||||||
$maybe nrNew <- getCorrNewAssignment ciCorrector shn
|
$maybe nrNew <- getCorrNewAssignment ciCorrector shn
|
||||||
$# <td .table__td>#{ciAssigned} `ciSubmissions` is here always identical to `ciAssigned` and also works for `ciCorrector == Nothing`. ciAssigned only useful in aggregate maps like `sheetMap`
|
$# <td .table__td>#{ciAssigned} `ciSubmissions` is here always identical to `ciAssigned` and also works for `ciCorrector == Nothing`. ciAssigned only useful in aggregate maps like `sheetMap`
|
||||||
<td .table__td .alert-info>(+#{nrNew})
|
<td .table__td .alert-info>(+#{nrNew})
|
||||||
@ -95,9 +103,17 @@
|
|||||||
<td .table__td>
|
<td .table__td>
|
||||||
$if 0 < length sheetNames
|
$if 0 < length sheetNames
|
||||||
<tr .table__row>
|
<tr .table__row>
|
||||||
<td colspan=6>
|
<td .table__th>Σ
|
||||||
|
$with ciSubmissionsNr <- ciSubmissions corrMapSum
|
||||||
|
$with ciCorrectedNr <- ciCorrected corrMapSum
|
||||||
|
<td .table__th>#{ciSubmissionsNr}
|
||||||
|
<td .table__td .heated style="--hotness: #{heat ciSubmissionsNr ciCorrectedNr}">#{ciSubmissionsNr - ciCorrectedNr}
|
||||||
|
<td .table__th>#{ciCorrected corrMapSum}
|
||||||
|
<td .table__th>#{showDiffDays (ciMin corrMapSum)}
|
||||||
|
<td .table__th>#{showAvgsDays (ciTot corrMapSum) (ciCorrected corrMapSum)}
|
||||||
|
<td .table__th>#{showDiffDays (ciMax corrMapSum)}
|
||||||
$forall shn <- sheetNames
|
$forall shn <- sheetNames
|
||||||
<td .table__td>#{getLoadSum shn}
|
<td .table__th>#{getLoadSum shn}
|
||||||
<td .table__td colspan=4>^{simpleLinkI (SomeMessage MsgMenuCorrectorsChange) (CSheetR tid ssh csh shn SCorrR)}
|
<td .table__td colspan=4>^{simpleLinkI (SomeMessage MsgMenuCorrectorsChange) (CSheetR tid ssh csh shn SCorrR)}
|
||||||
^{btnWdgt}
|
^{btnWdgt}
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@ -19,7 +19,7 @@ $#
|
|||||||
$with Sum pacv <- summary ^. _achievedPasses
|
$with Sum pacv <- summary ^. _achievedPasses
|
||||||
<td .table__td>
|
<td .table__td>
|
||||||
$if pmax > 0
|
$if pmax > 0
|
||||||
#{textPercentInt pacv pmax}
|
#{textPercent pacv pmax}
|
||||||
<td .table__td>
|
<td .table__td>
|
||||||
#{display pacv} / #{display pmax}
|
#{display pacv} / #{display pmax}
|
||||||
$else
|
$else
|
||||||
@ -35,7 +35,7 @@ $#
|
|||||||
$with Sum pacv <- summary ^. _achievedPoints
|
$with Sum pacv <- summary ^. _achievedPoints
|
||||||
<td .table__td>
|
<td .table__td>
|
||||||
$if pmax > 0
|
$if pmax > 0
|
||||||
#{textPercent $ realToFrac $ pacv / pmax}
|
#{textPercent pacv pmax}
|
||||||
<td .table__td>
|
<td .table__td>
|
||||||
#{display pacv} / #{display pmax}
|
#{display pacv} / #{display pmax}
|
||||||
$if ((summary ^. _numMarkedPoints) /= (summary ^. _numSheets))
|
$if ((summary ^. _numMarkedPoints) /= (summary ^. _numSheets))
|
||||||
|
|||||||
@ -1,11 +0,0 @@
|
|||||||
$newline never
|
|
||||||
<table>
|
|
||||||
<tbody>
|
|
||||||
$forall coord <- review liveCoords lLength
|
|
||||||
<tr .massinput__cell>
|
|
||||||
^{cellWdgts ! coord}
|
|
||||||
<td>
|
|
||||||
^{fvInput (delButtons ! coord)}
|
|
||||||
<tfoot>
|
|
||||||
<tr .massinput__cell.massinput__cell--add>
|
|
||||||
^{addWdgts ! (0, 0)}
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
$newline never
|
|
||||||
<td colspan=2>
|
|
||||||
^{addWidget}
|
|
||||||
<td>
|
|
||||||
^{fvInput submitView}
|
|
||||||
2
templates/widgets/occurrence/cell/except-no-occur.hamlet
Normal file
2
templates/widgets/occurrence/cell/except-no-occur.hamlet
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
$newline never
|
||||||
|
_{MsgExceptionKindNoOccur}: #{exceptTime'}
|
||||||
2
templates/widgets/occurrence/cell/except-occur.hamlet
Normal file
2
templates/widgets/occurrence/cell/except-occur.hamlet
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
$newline never
|
||||||
|
_{MsgExceptionKindOccur}: #{exceptStart'}–#{exceptEnd'}
|
||||||
@ -605,7 +605,7 @@ fillDb = do
|
|||||||
, tutorialCapacity = Just 30
|
, tutorialCapacity = Just 30
|
||||||
, tutorialRoom = "Hilbert-Raum"
|
, tutorialRoom = "Hilbert-Raum"
|
||||||
, tutorialTime = Occurrences
|
, tutorialTime = Occurrences
|
||||||
{ occurrencesScheduled = Set.singleton $ ScheduleWeekly Tuesday (TimeOfDay 10 15 00) (TimeOfDay 12 00 00)
|
{ occurrencesScheduled = Set.singleton $ ScheduleWeekly Tuesday (TimeOfDay 10 15 00) (TimeOfDay 12 00 00)
|
||||||
, occurrencesExceptions = Set.empty
|
, occurrencesExceptions = Set.empty
|
||||||
}
|
}
|
||||||
, tutorialRegGroup = Just "tutorium"
|
, tutorialRegGroup = Just "tutorium"
|
||||||
|
|||||||
@ -38,6 +38,10 @@ instance Arbitrary TutorialR where
|
|||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|
||||||
|
instance Arbitrary ExamR where
|
||||||
|
arbitrary = genericArbitrary
|
||||||
|
shrink = genericShrink
|
||||||
|
|
||||||
instance Arbitrary (Route UniWorX) where
|
instance Arbitrary (Route UniWorX) where
|
||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|||||||
@ -26,7 +26,7 @@ import Time.Types (WeekDay(..))
|
|||||||
|
|
||||||
instance (Arbitrary a, MonoFoldable a) => Arbitrary (NonNull a) where
|
instance (Arbitrary a, MonoFoldable a) => Arbitrary (NonNull a) where
|
||||||
arbitrary = arbitrary `suchThatMap` fromNullable
|
arbitrary = arbitrary `suchThatMap` fromNullable
|
||||||
|
|
||||||
instance Arbitrary Season where
|
instance Arbitrary Season where
|
||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
@ -71,7 +71,7 @@ instance Arbitrary SheetGradeSummary where
|
|||||||
instance Arbitrary SheetGroup where
|
instance Arbitrary SheetGroup where
|
||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|
||||||
instance Arbitrary SheetTypeSummary where
|
instance Arbitrary SheetTypeSummary where
|
||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
@ -79,7 +79,7 @@ instance Arbitrary SheetTypeSummary where
|
|||||||
instance Arbitrary SheetFileType where
|
instance Arbitrary SheetFileType where
|
||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|
||||||
instance Arbitrary SubmissionFileType where
|
instance Arbitrary SubmissionFileType where
|
||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
@ -147,7 +147,7 @@ instance Arbitrary AuthTag where
|
|||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
instance CoArbitrary AuthTag where
|
instance CoArbitrary AuthTag where
|
||||||
coarbitrary = genericCoarbitrary
|
coarbitrary = genericCoarbitrary
|
||||||
|
|
||||||
instance Arbitrary AuthTagActive where
|
instance Arbitrary AuthTagActive where
|
||||||
arbitrary = AuthTagActive <$> arbitrary
|
arbitrary = AuthTagActive <$> arbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
@ -176,7 +176,7 @@ instance Arbitrary AuthenticationMode where
|
|||||||
authPWHash = unsafePerformIO . fmap decodeUtf8 $ makePasswordWith pwHashAlgorithm pw (pwHashStrength `div` 2)
|
authPWHash = unsafePerformIO . fmap decodeUtf8 $ makePasswordWith pwHashAlgorithm pw (pwHashStrength `div` 2)
|
||||||
return $ AuthPWHash{..}
|
return $ AuthPWHash{..}
|
||||||
]
|
]
|
||||||
|
|
||||||
shrink AuthLDAP = []
|
shrink AuthLDAP = []
|
||||||
shrink (AuthPWHash _) = [AuthLDAP]
|
shrink (AuthPWHash _) = [AuthLDAP]
|
||||||
|
|
||||||
@ -195,18 +195,18 @@ instance Arbitrary Html where
|
|||||||
instance Arbitrary WeekDay where
|
instance Arbitrary WeekDay where
|
||||||
arbitrary = oneof $ map pure [minBound..maxBound]
|
arbitrary = oneof $ map pure [minBound..maxBound]
|
||||||
|
|
||||||
instance Arbitrary OccurenceSchedule where
|
instance Arbitrary OccurrenceSchedule where
|
||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|
||||||
instance Arbitrary OccurenceException where
|
instance Arbitrary OccurrenceException where
|
||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|
||||||
instance Arbitrary Occurences where
|
instance Arbitrary Occurrences where
|
||||||
arbitrary = genericArbitrary
|
arbitrary = genericArbitrary
|
||||||
shrink = genericShrink
|
shrink = genericShrink
|
||||||
|
|
||||||
|
|
||||||
spec :: Spec
|
spec :: Spec
|
||||||
spec = do
|
spec = do
|
||||||
|
|||||||
Reference in New Issue
Block a user