fix(corrections-overview): behavioural fixes
This commit is contained in:
parent
1c66f6320a
commit
e10cfe9c58
@ -1223,7 +1223,7 @@ a.breadcrumbs__home
|
||||
font-size: 14px
|
||||
font-family: monospace
|
||||
|
||||
.func-field__wrapper, .allocation-missing-prios, .allocation-users__accept
|
||||
.func-field__wrapper, .allocation-missing-prios, .allocation-users__accept, .corrections-overview__section
|
||||
max-height: 75vh
|
||||
overflow: auto
|
||||
|
||||
|
||||
@ -107,9 +107,10 @@
|
||||
text-align: right
|
||||
position: absolute
|
||||
left: 0px
|
||||
top: 0
|
||||
bottom: 0
|
||||
width: 50px
|
||||
height: 100%
|
||||
max-height: 100vh
|
||||
z-index: 40
|
||||
|
||||
&::before
|
||||
@ -130,9 +131,10 @@
|
||||
text-align: right
|
||||
position: absolute
|
||||
right: 0px
|
||||
top: 0
|
||||
bottom: 0
|
||||
width: 60px
|
||||
height: 100%
|
||||
max-height: 100vh
|
||||
transition: all .3s ease
|
||||
z-index: 40
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@ BtnLecInvDecline: Ablehnen
|
||||
BtnCorrInvAccept: Annehmen
|
||||
BtnCorrInvDecline: Ablehnen
|
||||
BtnSubmissionsAssign: Abgaben automatisch zuteilen
|
||||
BtnSubmissionsAssignAll: Abgaben automatisch zuteilen
|
||||
BtnAllocationCompute: Vergabe berechnen
|
||||
BtnAllocationAccept: Vergabe akzeptieren
|
||||
BtnSystemMessageHide: Verstecken
|
||||
@ -633,6 +634,7 @@ NrSubmissionsNotCorrected: Unkorrigiert
|
||||
NrSubmissionsNotCorrectedShort: Unkg.
|
||||
CorrectionTime: Korrekturdauer
|
||||
AssignSubmissionsRandomWarning: Die Zuteilungsvorschau kann von der tatsächlichen Zuteilung abweichen, wenn mehrere Blätter auf einmal zugeteilt werden, da beim Ausgleich der Kontigente nur bereits zugeteilte Abgaben berücksichtigt werden. Da es ein randomisierte Prozess ist, kann es auch bei einzelnen Blättern gerinfgügige Abweichungen geben.
|
||||
AssignSubmissionsAssignableSheets: Korrekturen verteilen für:
|
||||
|
||||
CorrectionsUploaded num@Int64: #{num} Korrekturen wurden gespeichert:
|
||||
NoCorrectionsUploaded: In der hochgeladenen Datei wurden keine Korrekturen gefunden.
|
||||
|
||||
@ -32,6 +32,7 @@ BtnLecInvDecline: Decline
|
||||
BtnCorrInvAccept: Accept
|
||||
BtnCorrInvDecline: Decline
|
||||
BtnSubmissionsAssign: Assign submissions automatically
|
||||
BtnSubmissionsAssignAll: Automatically distribute corrections
|
||||
BtnAllocationCompute: Compute allocation
|
||||
BtnAllocationAccept: Accept allocation
|
||||
BtnSystemMessageHide: Hide
|
||||
@ -631,6 +632,7 @@ NrSubmissionsNotCorrected: Not corrected
|
||||
NrSubmissionsNotCorrectedShort: N.corr.
|
||||
CorrectionTime: Correction time
|
||||
AssignSubmissionsRandomWarning: The assignment preview might be different from the actual assignment if multiple sheets are being distributed. This is due to the fact that only assigned submissions are considered when handling corrector-deficits. Due to this being a randomised process small differences are also possible for a single sheet.
|
||||
AssignSubmissionsAssignableSheets: Distribute corrections for:
|
||||
|
||||
CorrectionsUploaded num: Successfully saved #{num} #{pluralEN num "correction" "corrections"}:
|
||||
NoCorrectionsUploaded: No corrections could be found within the uploaded file.
|
||||
|
||||
@ -4,7 +4,7 @@ module Handler.Submission.Assign
|
||||
, getSAssignR, postSAssignR
|
||||
) where
|
||||
|
||||
import Import hiding (link)
|
||||
import Import hiding (link, unzip)
|
||||
|
||||
import Handler.Utils hiding (colSchool)
|
||||
import Handler.Utils.Corrections
|
||||
@ -12,7 +12,7 @@ import Handler.Utils.Submission
|
||||
|
||||
import Data.List as List (foldl, foldr)
|
||||
import qualified Data.Set as Set
|
||||
import Data.Map.Strict ((!))
|
||||
import Data.Map.Strict ((!), (!?))
|
||||
import qualified Data.Map.Strict as Map
|
||||
|
||||
import qualified Data.Text as Text
|
||||
@ -20,6 +20,8 @@ import qualified Data.CaseInsensitive as CI
|
||||
|
||||
import qualified Database.Esqueleto as E
|
||||
|
||||
import Data.List.NonEmpty (unzip)
|
||||
|
||||
|
||||
getSubAssignR, postSubAssignR :: TermId -> SchoolId -> CourseShorthand -> SheetName -> CryptoFileNameSubmission -> Handler Html
|
||||
getSubAssignR = postSubAssignR
|
||||
@ -56,15 +58,6 @@ postSubAssignR tid ssh csh shn cID = do
|
||||
$(widgetFile "submission-assign")
|
||||
|
||||
|
||||
data ButtonSubmissionsAssign = BtnSubmissionsAssign
|
||||
deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable)
|
||||
instance Universe ButtonSubmissionsAssign
|
||||
instance Finite ButtonSubmissionsAssign
|
||||
nullaryPathPiece ''ButtonSubmissionsAssign camelToPathPiece
|
||||
embedRenderMessage ''UniWorX ''ButtonSubmissionsAssign id
|
||||
instance Button UniWorX ButtonSubmissionsAssign where
|
||||
btnClasses BtnSubmissionsAssign = [BCIsButton, BCPrimary]
|
||||
|
||||
getCAssignR, postCAssignR :: TermId -> SchoolId -> CourseShorthand -> Handler Html
|
||||
getCAssignR = postCAssignR
|
||||
postCAssignR tid ssh csh = do
|
||||
@ -77,35 +70,22 @@ postSAssignR tid ssh csh shn = do
|
||||
(shid,cid) <- runDB $ fetchSheetIdCourseId tid ssh csh shn
|
||||
assignHandler tid ssh csh cid [shid]
|
||||
|
||||
{- TODO: Feature:
|
||||
make distivt buttons for each sheet, so that users see which sheet will be assigned.
|
||||
Currently this information is available within the page heading!
|
||||
|
||||
Stub:
|
||||
data ButtonCorrectionsAssign = BtnCorrectionsAssignAll | BtnCorrectionsAssignSheet SheetName
|
||||
deriving (Enum, Eq, Ord, Bounded, Read, Show, Generic, Typeable)
|
||||
instance Button UniWorX ButtonCorrectionsAssign
|
||||
-- Are those needed any more?
|
||||
instance Universe ButtonCorrectionsAssign
|
||||
instance Finite ButtonCorrectionsAssign
|
||||
nullaryPathPiece ''ButtonCorrectionsAssign camelToPathPiece
|
||||
embedRenderMessage ''UniWorX ''ButtonCorrectionsAssign id
|
||||
instance Button UniWorX ButtonCorrectionsAssign where
|
||||
btnClasses BtnCorrectionsAssign = [BCIsButton, BCPrimary]
|
||||
-- use runButtonForm' instead later on
|
||||
-}
|
||||
|
||||
assignHandler :: TermId -> SchoolId -> CourseShorthand -> CourseId -> [SheetId] -> Handler Html
|
||||
assignHandler tid ssh csh cid assignSids = do
|
||||
-- evaluate form first, since it affects DB action
|
||||
(btnWdgt, btnResult) <- runButtonForm FIDAssignSubmissions
|
||||
|
||||
currentRoute <- fromMaybe (error "assignHandler called from 404-handler") <$> liftHandler getCurrentRoute
|
||||
|
||||
-- gather data
|
||||
(orderedSheetNames, assignSheetNames, nrParticipants, groupsPossible, infoMap, correctorMap, assignment) <- runDB $ do
|
||||
(orderedSheetNames, assignSheetNames, nrParticipants, groupsPossible, infoMap, correctorMap, assignment, ((btnViews, btnCsrf), btnEncoding)) <- runDB $ do
|
||||
-- cid <- getKeyBy404 $ TermSchoolCourseShort tid ssh csh
|
||||
nrParticipants <- count [CourseParticipantCourse ==. cid, CourseParticipantState ==. CourseParticipantActive ]
|
||||
|
||||
sheetList <- selectList [SheetCourse ==. cid] [Desc SheetActiveTo, Desc SheetActiveFrom]
|
||||
assignSids' <- if
|
||||
| null assignSids -> -- assignAll; we distinguish assignSids' here avoid useless Alerts
|
||||
selectKeysList [SheetCourse ==. cid] [Asc SheetActiveTo]
|
||||
| otherwise -> return $ filter (`elem` map entityKey sheetList) assignSids
|
||||
|
||||
let orderedSheetNames = fmap (\(Entity _ Sheet{sheetName}) -> sheetName) sheetList
|
||||
sheets = entities2map sheetList
|
||||
sheetIds = Map.keys sheets
|
||||
@ -114,6 +94,12 @@ assignHandler tid ssh csh cid assignSids = do
|
||||
let foldFun (Entity _ Sheet{sheetGrouping=sgr}) acc = acc || sgr /= NoGroups
|
||||
in List.foldr foldFun False sheetList
|
||||
assignSheetNames = fmap sheetName $ mapMaybe (\sid -> Map.lookup sid sheets) assignSids
|
||||
assignSheetNames' = fmap sheetName $ mapMaybe (\sid -> Map.lookup sid sheets) assignSids'
|
||||
|
||||
assignButtons = Map.fromSet (maybe BtnSubmissionsAssignAll BtnSubmissionsAssign) $ Set.fromList . bool (Nothing :) id (null sheetList) $ map Just assignSheetNames'
|
||||
|
||||
((btnResult, btnViews'), btnEncoding) <- runFormPost . identifyForm FIDAssignSubmissions $ \csrf ->
|
||||
fmap (over _1 (asum . fmap (hoistMaybe =<<)) . over _2 (, csrf) . unzip) . for assignButtons $ \btn -> mopt (buttonField btn) "" Nothing
|
||||
|
||||
-- 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))
|
||||
@ -128,24 +114,29 @@ assignHandler tid ssh csh cid assignSids = do
|
||||
ignoreExceptions (SubmissionsNotFound _sids_not_found) = return mempty -- cannot happen, since last argument to planSubmissions is Nothing
|
||||
(plan,deficit) <- lift $ handle ignoreExceptions $ planSubmissions sid Nothing
|
||||
guard $ not $ null plan -- only proceed if there is a plan for this sheet
|
||||
-- implement assignment plan
|
||||
status <- lift $ case btnResult of
|
||||
Nothing -> return (Set.empty, Set.empty)
|
||||
(Just BtnSubmissionsAssign) -> do
|
||||
status@(sub_ok,sub_fail) <- writeSubmissionPlan plan
|
||||
let nr_ok = olength sub_ok
|
||||
nr_fail = olength sub_fail
|
||||
alert_ok = toMaybe (nr_ok > 0) $ SomeMessage $ MsgUpdatedSheetCorrectorsAutoAssigned nr_ok
|
||||
alert_fail = toMaybe (nr_fail > 0) $ SomeMessage $ MsgUpdatedSheetCorrectorsAutoFailed nr_fail
|
||||
msg_status = bool Success Error $ nr_fail > 0
|
||||
msg_header = SomeMessage $ shn <> ":"
|
||||
when (nr_ok > 0 || nr_fail > 0) $
|
||||
addMessageI msg_status $ UniWorXMessages $ msg_header : catMaybes [alert_ok, alert_fail]
|
||||
return status
|
||||
return $ Map.insert shn (status, countMapElems plan, deficit) acc
|
||||
assignSids' <- if null assignSids -- assignAll; we distinguish assignSids' here avoid useless Alerts
|
||||
then selectKeysList [SheetCourse ==. cid] [Asc SheetActiveTo]
|
||||
else return assignSids
|
||||
status@(sub_ok, sub_fail) <- fmap fold . formResultMaybe btnResult $ \btn -> lift . maybeT (return Nothing) $ do
|
||||
guard $ case btn of
|
||||
BtnSubmissionsAssignAll -> True
|
||||
BtnSubmissionsAssign shn' -> shn' == shn
|
||||
|
||||
status@(sub_ok,sub_fail) <- lift $ writeSubmissionPlan plan
|
||||
let nr_ok = olength sub_ok
|
||||
nr_fail = olength sub_fail
|
||||
alert_ok = toMaybe (nr_ok > 0) $ SomeMessage $ MsgUpdatedSheetCorrectorsAutoAssigned nr_ok
|
||||
alert_fail = toMaybe (nr_fail > 0) $ SomeMessage $ MsgUpdatedSheetCorrectorsAutoFailed nr_fail
|
||||
msg_status = bool Success Error $ nr_fail > 0
|
||||
msg_header = SomeMessage $ shn <> ":"
|
||||
if | nr_ok > 0 || nr_fail > 0 -> do
|
||||
addMessageI msg_status $ UniWorXMessages $ msg_header : catMaybes [alert_ok, alert_fail]
|
||||
return $ Just status
|
||||
| otherwise -> do
|
||||
addMessageI Error $ MsgSheetsUnassignable $ CI.original shn
|
||||
return Nothing
|
||||
if | null sub_ok && null sub_fail ->
|
||||
return $ Map.insert shn (status, countMapElems plan, deficit) acc
|
||||
| otherwise -> do
|
||||
(plan', deficit') <- lift $ handle ignoreExceptions $ planSubmissions sid Nothing
|
||||
return $ Map.insert shn (status, countMapElems plan', deficit') acc
|
||||
assignment <- foldM buildA Map.empty assignSids'
|
||||
|
||||
correctors <- E.select . E.from $ \(corrector `E.InnerJoin` user) -> do
|
||||
@ -202,7 +193,7 @@ assignHandler tid ssh csh cid assignSids = do
|
||||
}
|
||||
in Map.insertWith (Map.unionWith (<>)) shnm cinf m
|
||||
|
||||
return (orderedSheetNames, assignSheetNames, nrParticipants, groupsPossible, infoMap, correctorMap, assignment)
|
||||
return (orderedSheetNames, assignSheetNames, nrParticipants, groupsPossible, infoMap, correctorMap, assignment, (btnViews', btnEncoding))
|
||||
|
||||
let -- infoMap :: Map SheetName (Map (Maybe UserId) CorrectionInfo) -- repeated here for easier reference
|
||||
-- create aggregate maps
|
||||
@ -268,14 +259,39 @@ assignHandler tid ssh csh cid assignSids = do
|
||||
showAvgsDays :: Maybe NominalDiffTime -> Integer -> Text
|
||||
showAvgsDays Nothing _ = mempty
|
||||
showAvgsDays (Just dt) n = formatDiffDays $ dt / fromIntegral n
|
||||
let headingShort
|
||||
| 0 < Map.size assignment = MsgMenuCorrectionsAssignSheet $ Text.intercalate ", " $ fmap CI.original $ Map.keys assignment
|
||||
| otherwise = MsgMenuCorrectionsAssign
|
||||
headingLong = prependCourseTitle tid ssh csh MsgMenuCorrectionsAssign
|
||||
let headingShort = 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
|
||||
setTitleI headingLong
|
||||
$(widgetFile "corrections-overview")
|
||||
|
||||
let doWrap wdgt
|
||||
| null btnViews = wdgt
|
||||
| otherwise = wrapForm (toWidget btnCsrf <> wdgt) def
|
||||
{ formAction = Just . SomeRoute $ currentRoute
|
||||
, formEncoding = btnEncoding
|
||||
, formSubmit = FormNoSubmit
|
||||
}
|
||||
sheetBtnViews = Map.fromList [ (shn, btn) | (Just shn, btn) <- Map.toList btnViews, shn `elem` assignSheetNames' ]
|
||||
assignSheetNames' = Map.keys $ Map.filter (\(_, new, _) -> any (> 0) $ Map.delete Nothing new) assignment
|
||||
|
||||
doWrap $(widgetFile "corrections-overview")
|
||||
|
||||
|
||||
data ButtonSubmissionsAssign
|
||||
= BtnSubmissionsAssign SheetName
|
||||
| BtnSubmissionsAssignAll
|
||||
deriving (Eq, Ord, Read, Show, Generic, Typeable)
|
||||
derivePathPiece ''ButtonSubmissionsAssign (camelToPathPiece' 2) "--"
|
||||
|
||||
instance RenderMessage UniWorX ButtonSubmissionsAssign where
|
||||
renderMessage f ls = \case
|
||||
BtnSubmissionsAssign _ -> mr MsgBtnSubmissionsAssign
|
||||
BtnSubmissionsAssignAll -> mr MsgBtnSubmissionsAssignAll
|
||||
where mr = renderMessage f ls
|
||||
|
||||
instance Button UniWorX ButtonSubmissionsAssign where
|
||||
btnClasses _ = [BCIsButton, BCPrimary]
|
||||
|
||||
@ -2,146 +2,176 @@ $newline never
|
||||
<section>
|
||||
<h2>_{MsgCorrectionSheets}
|
||||
|
||||
_{MsgCourseParticipants nrParticipants}
|
||||
<table .table .table--striped .table--hover>
|
||||
<tr .table__row .table__row--head>
|
||||
<th .table__th rowspan=2>_{MsgSheet}
|
||||
$if groupsPossible
|
||||
<th .table__th rowspan=2>_{MsgNrSubmittorsTotal}
|
||||
<th .table__th rowspan=2>_{MsgNrSubmissionsTotal}
|
||||
<th .table__th colspan=2>_{MsgNrSubmissionsNotAssigned}
|
||||
<th .table__th rowspan=2>_{MsgNrSubmissionsNotCorrected}
|
||||
<th .table__th colspan=3>_{MsgCorrectionTime}
|
||||
<tr .table__row .table__row--head>
|
||||
<th .table__th>
|
||||
<th .table__th>_{MsgGenericNumChange}
|
||||
<th .table__th>_{MsgGenericMin}
|
||||
<th .table__th>_{MsgGenericAvg}
|
||||
<th .table__th>_{MsgGenericMax}
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall sheetName <- reverse orderedSheetNames
|
||||
$maybe CorrectionInfo{ciSubmittors, ciSubmissions, ciAssigned, ciCorrected, ciMin, ciTot, ciMax} <- Map.lookup sheetName sheetMap
|
||||
<tr .table__row>
|
||||
<td .table__td>^{simpleLink (toWidget sheetName) (CSheetR tid ssh csh sheetName SSubsR)}
|
||||
$if groupsPossible
|
||||
<td .table__td>#{ciSubmittors}
|
||||
<td .table__td>#{ciSubmissions}
|
||||
$maybe ((splus,sfailed),_,_) <- Map.lookup sheetName assignment
|
||||
$if 0 < Set.size sfailed
|
||||
<td .table__td>#{ciSubmissions - ciAssigned}
|
||||
<td .table__td .alert-danger>(-#{show (Set.size splus)}, failed: #{show (Set.size sfailed)})
|
||||
$elseif 0 < Set.size splus
|
||||
<td .table__td>#{ciSubmissions - ciAssigned}
|
||||
<td .table__td .alert-info>(-#{show (Set.size splus)})
|
||||
$else
|
||||
<p>
|
||||
_{MsgCourseParticipants nrParticipants}
|
||||
|
||||
<div .scrolltable .scrolltable--bordered .corrections-overview__section>
|
||||
<table .table .table--striped .table--hover>
|
||||
<tr .table__row .table__row--head>
|
||||
<th .table__th rowspan=2>_{MsgSheet}
|
||||
$if groupsPossible
|
||||
<th .table__th rowspan=2>_{MsgNrSubmittorsTotal}
|
||||
<th .table__th rowspan=2>_{MsgNrSubmissionsTotal}
|
||||
<th .table__th colspan=2>_{MsgNrSubmissionsNotAssigned}
|
||||
<th .table__th rowspan=2>_{MsgNrSubmissionsNotCorrected}
|
||||
<th .table__th colspan=3>_{MsgCorrectionTime}
|
||||
<tr .table__row .table__row--head>
|
||||
<th .table__th>
|
||||
<th .table__th>_{MsgGenericNumChange}
|
||||
<th .table__th>_{MsgGenericMin}
|
||||
<th .table__th>_{MsgGenericAvg}
|
||||
<th .table__th>_{MsgGenericMax}
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall sheetName <- reverse orderedSheetNames
|
||||
$maybe CorrectionInfo{ciSubmittors, ciSubmissions, ciAssigned, ciCorrected, ciMin, ciTot, ciMax} <- Map.lookup sheetName sheetMap
|
||||
<tr .table__row>
|
||||
<td .table__td>^{simpleLink (toWidget sheetName) (CSheetR tid ssh csh sheetName SSubsR)}
|
||||
$if groupsPossible
|
||||
<td .table__td>#{ciSubmittors}
|
||||
<td .table__td>#{ciSubmissions}
|
||||
$maybe ((splus,sfailed),_,_) <- Map.lookup sheetName assignment
|
||||
$if 0 < Set.size sfailed
|
||||
<td .table__td>#{ciSubmissions - ciAssigned}
|
||||
<td .table__td .alert-danger>(-#{show (Set.size splus)}, failed: #{show (Set.size sfailed)})
|
||||
$elseif 0 < Set.size splus
|
||||
<td .table__td>#{ciSubmissions - ciAssigned}
|
||||
<td .table__td .alert-info>(-#{show (Set.size splus)})
|
||||
$else
|
||||
<td .table__td>#{ciSubmissions - ciAssigned}
|
||||
<td .table__td>
|
||||
$nothing
|
||||
<td .table__td>#{ciSubmissions - ciAssigned}
|
||||
<td .table__td>
|
||||
$nothing
|
||||
<td .table__td>#{ciSubmissions - ciAssigned}
|
||||
<td .table__td>
|
||||
<td .table__td>#{ciSubmissions - ciCorrected}
|
||||
<td .table__td>#{showDiffDays ciMin}
|
||||
<td .table__td>#{showAvgsDays ciTot ciCorrected}
|
||||
<td .table__td>#{showDiffDays ciMax}
|
||||
<td .table__td>#{ciSubmissions - ciCorrected}
|
||||
<td .table__td>#{showDiffDays ciMin}
|
||||
<td .table__td>#{showAvgsDays ciTot ciCorrected}
|
||||
<td .table__td>#{showDiffDays ciMax}
|
||||
|
||||
<section>
|
||||
<h2>_{MsgCorrectionCorrectors}
|
||||
|
||||
<table .table .table--striped .table--hover>
|
||||
<tr .table__row .table__row--head>
|
||||
<th .table__th rowspan=2>_{MsgCorrector}
|
||||
<th .table__th colspan=2>_{MsgGenericAll}
|
||||
<th .table__th rowspan=2>_{MsgCorDeficitProportion}
|
||||
<th .table__th colspan=3>_{MsgCorrectionTime}
|
||||
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall shn <- orderedSheetNames
|
||||
<th .table__th colspan=5>
|
||||
^{simpleLink (toWidget shn) (CSheetR tid ssh csh shn SShowR)}
|
||||
<tr .table__row .table__row--head>
|
||||
<th .table__th>_{MsgNrSubmissionsTotal}
|
||||
<th .table__th>_{MsgNrSubmissionsNotCorrected}
|
||||
<th .table__th>_{MsgGenericMin}
|
||||
<th .table__th>_{MsgGenericAvg}
|
||||
<th .table__th>_{MsgGenericMax}
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall _shn <- orderedSheetNames
|
||||
<th .table__th>_{MsgCorProportion}
|
||||
<th .table__th>_{MsgNrSubmissionsTotalShort}
|
||||
<th .table__th>_{MsgGenericNumChange}
|
||||
<th .table__th>_{MsgNrSubmissionsNotCorrectedShort}
|
||||
<th .table__th>_{MsgGenericAvg}
|
||||
$forall (CorrectionInfo{ciCorrector, ciSubmissions=ciSubmissionsNr, ciCorrected, ciMin, ciTot, ciMax}) <- corrInfos
|
||||
$with (nameW,loadM, name) <- getCorrector ciCorrector
|
||||
$# TODO: User proper Tooltips instead of title attribute here, once Tooltips work with tables
|
||||
<tr .table__row title="#{name}">
|
||||
<td .table__td>^{nameW}
|
||||
<td .table__td>#{ciSubmissionsNr}
|
||||
$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>
|
||||
$maybe deficit <- getCorrDeficit ciCorrector
|
||||
#{rationalToFixed3 deficit}
|
||||
<td .table__td>#{showDiffDays ciMin}
|
||||
<td .table__td>#{showAvgsDays ciTot ciCorrected}
|
||||
<td .table__td>#{showDiffDays ciMax}
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall shn <- orderedSheetNames
|
||||
$maybe CorrectionInfo{ciSubmissions=sheetSubmissionsNr} <- Map.lookup shn sheetMap
|
||||
<td .table__td>
|
||||
$maybe SheetCorrector{sheetCorrectorLoad, sheetCorrectorState} <- Map.lookup shn loadM
|
||||
#{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
|
||||
<td .table__td>#{ciSubmissions}
|
||||
$if sheetSubmissionsNr > 0
|
||||
\ (#{textPercent' True 0 ciSubmissions sheetSubmissionsNr})
|
||||
$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 .alert-info>(+#{nrNew})
|
||||
$nothing
|
||||
<td .table__td>
|
||||
<td .table__td .heated style="--hotness: #{heat ciSubmissions ciCorrected}">#{ciSubmissions - ciCorrected}
|
||||
<td .table__td>#{showAvgsDays ciTot ciCorrected}
|
||||
$nothing
|
||||
<td .table__td>
|
||||
<td .table__td>
|
||||
<td .table__td>
|
||||
<td .table__td>
|
||||
$if not (null orderedSheetNames)
|
||||
<tr .table__row>
|
||||
<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)}
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall shn <- orderedSheetNames
|
||||
$maybe CorrectionInfo{ciSubmissions} <- Map.lookup shn sheetMap
|
||||
<td .table__th>#{getLoadSum shn}
|
||||
<td .table__th>#{ciSubmissions}
|
||||
<td .table__td colspan=3>^{simpleLinkI (SomeMessage MsgMenuCorrectorsChange) (CSheetR tid ssh csh shn SEditR)}
|
||||
|
||||
<div .scrolltable .scrolltable--bordered>
|
||||
<table .table .table--striped .table--hover>
|
||||
<tr .table__row .table__row--head>
|
||||
<th>
|
||||
<th colspan=2>
|
||||
<th>
|
||||
<th colspan=3>
|
||||
<th .table__th rowspan=2>_{MsgCorrector}
|
||||
<th .table__th colspan=2>_{MsgGenericAll}
|
||||
<th .table__th rowspan=2>_{MsgCorDeficitProportion}
|
||||
<th .table__th colspan=3>_{MsgCorrectionTime}
|
||||
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall shn <- orderedSheetNames
|
||||
<th .table__th colspan=5>
|
||||
^{simpleLink (toWidget shn) (CSheetR tid ssh csh shn SShowR)}
|
||||
<tr .table__row .table__row--head>
|
||||
<th .table__th>_{MsgNrSubmissionsTotal}
|
||||
<th .table__th>_{MsgNrSubmissionsNotCorrected}
|
||||
<th .table__th>_{MsgGenericMin}
|
||||
<th .table__th>_{MsgGenericAvg}
|
||||
<th .table__th>_{MsgGenericMax}
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall _shn <- orderedSheetNames
|
||||
<th .table__th>_{MsgCorProportion}
|
||||
<th .table__th>_{MsgNrSubmissionsTotalShort}
|
||||
<th .table__th>_{MsgGenericNumChange}
|
||||
<th .table__th>_{MsgNrSubmissionsNotCorrectedShort}
|
||||
<th .table__th>_{MsgGenericAvg}
|
||||
$forall (CorrectionInfo{ciCorrector, ciSubmissions=ciSubmissionsNr, ciCorrected, ciMin, ciTot, ciMax}) <- corrInfos
|
||||
$with (nameW,loadM, name) <- getCorrector ciCorrector
|
||||
$# TODO: User proper Tooltips instead of title attribute here, once Tooltips work with tables
|
||||
<tr .table__row title="#{name}">
|
||||
<td .table__td>^{nameW}
|
||||
<td .table__td>#{ciSubmissionsNr}
|
||||
$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>
|
||||
$maybe deficit <- getCorrDeficit ciCorrector
|
||||
#{rationalToFixed3 deficit}
|
||||
<td .table__td>#{showDiffDays ciMin}
|
||||
<td .table__td>#{showAvgsDays ciTot ciCorrected}
|
||||
<td .table__td>#{showDiffDays ciMax}
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall shn <- orderedSheetNames
|
||||
$maybe CorrectionInfo{ciSubmissions=sheetSubmissionsNr} <- Map.lookup shn sheetMap
|
||||
<td .table__td>
|
||||
$maybe SheetCorrector{sheetCorrectorLoad, sheetCorrectorState} <- Map.lookup shn loadM
|
||||
#{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
|
||||
<td .table__td>#{ciSubmissions}
|
||||
$if sheetSubmissionsNr > 0
|
||||
\ (#{textPercent' True 0 ciSubmissions sheetSubmissionsNr})
|
||||
$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 .alert-info>(+#{nrNew})
|
||||
$nothing
|
||||
<td .table__td>
|
||||
<td .table__td .heated style="--hotness: #{heat ciSubmissions ciCorrected}">#{ciSubmissions - ciCorrected}
|
||||
<td .table__td>#{showAvgsDays ciTot ciCorrected}
|
||||
$nothing
|
||||
<td .table__td>
|
||||
<td .table__td>
|
||||
<td .table__td>
|
||||
<td .table__td>
|
||||
$if not (null orderedSheetNames)
|
||||
<tr .table__row>
|
||||
<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)}
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall shn <- orderedSheetNames
|
||||
$maybe CorrectionInfo{ciSubmissions} <- Map.lookup shn sheetMap
|
||||
<td .table__th>#{getLoadSum shn}
|
||||
<td .table__th>#{ciSubmissions}
|
||||
<td .table__td colspan=3>^{simpleLinkI (SomeMessage MsgMenuCorrectorsChange) (CSheetR tid ssh csh shn SEditR)}
|
||||
|
||||
^{btnWdgt}
|
||||
$if not (null assignment)
|
||||
<tr .table__row>
|
||||
<td>
|
||||
<td colspan=2>
|
||||
<td>
|
||||
<td colspan=3>
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall shn <- orderedSheetNames
|
||||
<td .table__td colspan=5>
|
||||
$maybe btnView <- sheetBtnViews !? shn
|
||||
$if has (ix shn) assignment
|
||||
^{fvWidget btnView}
|
||||
|
||||
<tr .table__row .table__row--head>
|
||||
<td>
|
||||
<td colspan=2>
|
||||
<td>
|
||||
<td colspan=3>
|
||||
$# Always iterate over orderedSheetNames for consistent sorting! Newest first, except in this table
|
||||
$forall shn <- orderedSheetNames
|
||||
<td .table__th colspan=5>
|
||||
^{simpleLink (toWidget shn) (CSheetR tid ssh csh shn SShowR)}
|
||||
|
||||
<p .explanation>
|
||||
_{MsgAssignSubmissionsRandomWarning}
|
||||
|
||||
$if not (null assignment)
|
||||
$maybe btnView <- btnViews !? Nothing
|
||||
<section>
|
||||
<p>
|
||||
_{MsgAssignSubmissionsAssignableSheets}
|
||||
<div .corrections-overview__section>
|
||||
<ul>
|
||||
$forall shn <- assignSheetNames'
|
||||
<li>
|
||||
<a href=@{CSheetR tid ssh csh shn SShowR}>
|
||||
#{shn}
|
||||
<p>
|
||||
^{fvWidget btnView}
|
||||
|
||||
<section>
|
||||
<p>_{MsgAssignSubmissionsRandomWarning}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user