diff --git a/messages/uniworx/categories/courses/exam/exam/de-de-formal.msg b/messages/uniworx/categories/courses/exam/exam/de-de-formal.msg
index f0799fcf7..7fc318be8 100644
--- a/messages/uniworx/categories/courses/exam/exam/de-de-formal.msg
+++ b/messages/uniworx/categories/courses/exam/exam/de-de-formal.msg
@@ -64,14 +64,14 @@ ExamAutomaticGradingTip: Sollen die Gesamtleistungen der Teilnehmer:innen automa
ExamBonus: Bonuspunkte-System
ExamGradingMode: Bewertungsmodus
ExamGradingModeTip: In welcher Form werden Prüfungsleistungen für diese Prüfung eingetragen?
-ExamStaff: Prüfer:innen
-ExamStaffTip: Geben Sie bitte in jedem Fall einen Namen an, der Prüfer:in/Veranstalter:in/Hochschullehrer:in eindeutig identifiziert! Sollte der Name des Prüfers/der Prüferin allein womöglich nicht eindeutig sein, so geben Sie bitte eindeutig identifizierende Zusatzinfos, wie beispielsweise den Lehrstuhl bzw. die LFE o.Ä., an.
+ExamStaff: Hauptverantworliche:r
+ExamStaffTip: Hauptverantwortliche:r Prüfer:in, Textfeld zur reinen Information der Teilnehmenden.
ExamExamOfficeSchools: Zusätzliche Bereiche
ExamExamOfficeSchoolsTip: Prüfungsbeauftragte von Bereichen, die Sie hier angeben, erhalten im System (zusätzlich zum primären Bereich der zugehörigen Kursart) volle Einsicht in sämtliche für diese Prüfung hinterlegten Leistungen, unabhängig von den Studiendaten der Teilnehmer:innen.
ExamCorrectorEmail: E-Mail
-ExamCorrectors: Korrektor:innen
-ExamCorrectorsTip: Hier eingetragene Korrektor:innen können zwischen Beginn der Prüfung und "Bewertung abgeschlossen ab" Ergebnisse für alle Teilprüfungen und alle Teilnehmer:innen im System hinterlegen.
-ExamCorrectorAlreadyAdded: Ein Korrektor/eine Korrektorin mit dieser E-Mail ist bereits für diese Prüfung eingetragen
+ExamCorrectors: Prüfer:innen
+ExamCorrectorsTip: Hier eingetragene Prüfer:innen können zwischen Beginn der Prüfung und "Bewertung abgeschlossen ab" Ergebnisse für alle Teilprüfungen und alle Teilnehmer:innen im System hinterlegen.
+ExamCorrectorAlreadyAdded: Ein Prüfer:innen mit dieser E-Mail ist bereits für diese Prüfung eingetragen
ExamRoom: Raum
ExamRoomManual': Keine automatische bzw. selbstständige Zuteilung
ExamRoomSurname': Nach Nachname
@@ -266,7 +266,7 @@ ExamAutoOccurrenceExceptionRoomTooSmall: Automatische Verteilung gescheitert. Ei
ExamBonusInfoPoints: Zur Berechnung von Bonuspunkten werden nur jene Blätter herangezogen, deren Aktivitätszeitraum vor Start des jeweiligen Termin/Prüfung begonnen hat
ExamUserCsvSheetName tid@TermId ssh@SchoolId csh@CourseShorthand examn@ExamName: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-#{foldedCase examn} Teilnehmer
-ExamRoomExaminerTip: Nur bereits eingetragene Korrektor:innen sind hier erlaubt
+ExamRoomExaminerTip: Nur bereits eingetragene Prüfer:innen sind hier erlaubt
ExamRoomCapacityTip: Maximale Anzahl an Prüfungsteilnehmern für diesen Termin/Raum; leer lassen für unbeschränkte Teilnehmeranzahl
ExamRoomMappingRandom: Verteilung
ExamFinishHeading: Prüfungsergebnisse sichtbar schalten
diff --git a/messages/uniworx/categories/courses/exam/exam/en-eu.msg b/messages/uniworx/categories/courses/exam/exam/en-eu.msg
index acea135a1..db97592de 100644
--- a/messages/uniworx/categories/courses/exam/exam/en-eu.msg
+++ b/messages/uniworx/categories/courses/exam/exam/en-eu.msg
@@ -64,14 +64,14 @@ ExamAutomaticGradingTip: Should the exam achievement be automatically computed f
ExamBonus: Bonus point system
ExamGradingMode: Grading mode
ExamGradingModeTip: In which format should grades for this exam be entered?
-ExamStaff: Examiner
-ExamStaffTip: Please always specify a name that uniquely identifies the examiner/organiser/repsonsible university teacher! If there is a possibility that the name alone is ambiguous please also specify some additional information e.g. the professorial chair or the educational and research unit.
+ExamStaff: Chief examiner
+ExamStaffTip: Primary responsible examiner, arbirary text field for pure informational purposes.
ExamExamOfficeSchools: Additional departments
ExamExamOfficeSchoolsTip: Exam offices of departments you specify here will also have full access to all results for this exam disregarding the individual participants' features of study.
ExamCorrectorEmail: Email
-ExamCorrectors: Correctors
-ExamCorrectorsTip: Correctors configured here may, after the start of the exam and until "Results visible from", enter exam part results for all exam parts and participants.
-ExamCorrectorAlreadyAdded: A corrector with this email address already exists
+ExamCorrectors: Examiner
+ExamCorrectorsTip: Examiners configured here may, after the start of the exam and until "Results visible from", enter exam part results for all exam parts and participants.
+ExamCorrectorAlreadyAdded: An examiner with this email address already exists
ExamRoom: Room
ExamRoomManual': No automatic or autonomous assignment
ExamRoomSurname': By surname
@@ -265,7 +265,7 @@ ExamAutoOccurrenceExceptionRoomTooSmall: Automatic distribution failed. A differ
ExamBonusInfoPoints: When calculating an exam bonus only those sheets will be considered, for which the submission period started before the start of the relevant occurrence/room
ExamUserCsvSheetName tid ssh csh examn: #{foldCase (termToText (unTermKey tid))}-#{foldedCase (unSchoolKey ssh)}-#{foldedCase csh}-#{foldedCase examn} Participants
-ExamRoomExaminerTip: Only correctors allowed here, add beforehand
+ExamRoomExaminerTip: Only examiners allowed here, add beforehand
ExamRoomCapacityTip: Maximum number of participants for this occurrence/room; leave empty for unlimited capacity
ExamRoomMappingRandom: Distribution
ExamFinishHeading: Make results visible
diff --git a/src/Handler/Course/Edit.hs b/src/Handler/Course/Edit.hs
index 17fe34a67..2837f1d84 100644
--- a/src/Handler/Course/Edit.hs
+++ b/src/Handler/Course/Edit.hs
@@ -452,7 +452,7 @@ courseEditHandler miButtonAction mbCourseForm = do
sinkInvitationsF lecturerInvitationConfig $ map (\(lEmail, mLty) -> (lEmail, cid, (InvDBDataLecturer mLty, InvTokenDataLecturer))) invites
void $ upsertCourseQualifications aid cid $ cfQualis res
insert_ $ CourseEdit aid now cid
- memcachedFlushClass MemcachedKeyClassTutorialOccurrences
+ memcachedInvalidateClass MemcachedKeyClassTutorialOccurrences
memcachedByInvalidate AuthCacheLecturerList $ Proxy @(Set UserId)
addMessageI Success $ MsgCourseEditOk tid ssh csh
return True
diff --git a/src/Handler/Course/Users.hs b/src/Handler/Course/Users.hs
index f2742212f..6e3aac1da 100644
--- a/src/Handler/Course/Users.hs
+++ b/src/Handler/Course/Users.hs
@@ -516,7 +516,7 @@ makeCourseUserTable cid acts restrict colChoices psValidator csvColumns = do
-- , ("course-user-note", error "TODO") -- TODO
, single ("submission-group", FilterColumn $ E.mkContainsFilter $ querySubmissionGroup >>> (E.?. SubmissionGroupName))
, single ("active", FilterColumn $ E.mkExactFilter $ queryParticipant >>> (E.==. E.val CourseParticipantActive) . (E.^. CourseParticipantState))
- , single ("has-personalised-sheet-files", FilterColumn $ \t (Last criterion) -> flip (maybe E.true) criterion $ \shn
+ , single ("has-personalised-sheet-files", FilterColumn $ \t (Last criterion) -> ifNothing criterion E.true $ \shn
-> E.exists . E.from $ \(psFile `E.InnerJoin` sheet) -> do
E.on $ psFile E.^. PersonalisedSheetFileSheet E.==. sheet E.^. SheetId
E.where_ $ psFile E.^. PersonalisedSheetFileUser E.==. queryParticipant t E.^. CourseParticipantUser
diff --git a/src/Handler/Term.hs b/src/Handler/Term.hs
index 7273e8757..db52a96e1 100644
--- a/src/Handler/Term.hs
+++ b/src/Handler/Term.hs
@@ -201,7 +201,7 @@ termEditHandler mtid template = do
, termActiveFor = tafFor
}
lift . audit $ TransactionTermEdit tid
- memcachedFlushClass MemcachedKeyClassTutorialOccurrences
+ memcachedInvalidateClass MemcachedKeyClassTutorialOccurrences
addMessageI Success $ MsgTermEdited tid
redirect TermShowR
FormMissing -> return ()
diff --git a/src/Handler/Tutorial/Edit.hs b/src/Handler/Tutorial/Edit.hs
index cf6938ec6..7e8ed7d13 100644
--- a/src/Handler/Tutorial/Edit.hs
+++ b/src/Handler/Tutorial/Edit.hs
@@ -86,7 +86,7 @@ postTEditR tid ssh csh tutn = do
case insertRes of
Just _ -> addMessageI Error $ MsgTutorialNameTaken tfName
Nothing -> do
- memcachedFlushClass MemcachedKeyClassTutorialOccurrences
+ memcachedInvalidateClass MemcachedKeyClassTutorialOccurrences
addMessageI Success $ MsgTutorialEdited tfName
redirect $ CourseR tid ssh csh CTutorialListR
diff --git a/src/Handler/Utils/Delete.hs b/src/Handler/Utils/Delete.hs
index 418972395..2ebf4df4f 100644
--- a/src/Handler/Utils/Delete.hs
+++ b/src/Handler/Utils/Delete.hs
@@ -114,7 +114,7 @@ deleteR' DeleteRoute{..} = do
True -> do
runDBJobs $ do
forM_ drRecords $ \k -> drDelete k $ delete k
- memcachedFlushClass MemcachedKeyClassTutorialOccurrences
+ memcachedInvalidateClass MemcachedKeyClassTutorialOccurrences
addMessageI Success drSuccessMessage
redirect drSuccess
False ->
diff --git a/src/Handler/Utils/Form.hs b/src/Handler/Utils/Form.hs
index 73568b24e..0a2616255 100644
--- a/src/Handler/Utils/Form.hs
+++ b/src/Handler/Utils/Form.hs
@@ -1739,6 +1739,8 @@ multiUserInvitationField mode
_{MsgMultiUserFieldInvitationExplanation}
|]
+
+-- | Field for entering multiple users by email, matriculation or personnel number. Unknown valid emails are also accepted, e.g. for sending invitations
multiUserField :: forall m.
( MonadHandler m
, HandlerSite m ~ UniWorX
@@ -1746,90 +1748,21 @@ multiUserField :: forall m.
=> Bool -- ^ Only resolve suggested users?
-> Maybe (E.SqlQuery (E.SqlExpr (Entity User))) -- ^ Suggested users
-> Field m (Set (Either UserEmail UserId))
-multiUserField onlySuggested suggestions = Field{..}
+multiUserField = userFieldAux procEmails wrapUid mergeRes
where
- lookupExpr
- | onlySuggested = suggestions
- | otherwise = Just $ E.from return
+ procEmails :: (UserId -> WidgetFor UniWorX Text) -> Set (Either UserEmail UserId) -> WidgetFor UniWorX Text
+ procEmails f vs = Text.intercalate ", " <$> forM (Set.toList vs) (procEmail f)
- fieldEnctype = UrlEncoded
- fieldView theId name attrs val isReq = do
- val' <- case val of
- Left t -> return t
- Right vs -> Text.intercalate ", " . map CI.original <$> do
- let (emails, uids) = partitionEithers $ Set.toList vs
- rEmails <- case lookupExpr of
- Nothing -> return []
- Just lookupExpr' -> fmap concat . forM uids $ \uid -> do
- dbRes <- liftHandler . runDB . E.select $ do
- user <- lookupExpr'
- E.where_ $ user E.^. UserId E.==. E.val uid
- return $ user E.^. UserEmail
- case dbRes of
- [E.Value email] -> return [email]
- _other -> return []
- return $ emails ++ rEmails
+ procEmail _ (Left email) = return $ CI.original email
+ procEmail f (Right uid ) = f uid
- datalistId <- maybe (return $ error "Not to be used") (const newIdent) suggestions
+ wrapUid (Right uid) = return $ Just $ Right uid
+ wrapUid (Left email) = return $ Just $ Left email
- [whamlet|
- $newline never
-
- |]
-
- whenIsJust suggestions $ \suggestions' -> do
- suggestedEmails <- fmap (Map.assocs . Map.fromListWith min . map (over _2 E.unValue . over _1 E.unValue)) . liftHandler . runDB . E.select $ do
- user <- suggestions'
- return ( E.case_
- [ E.when_ (unique UserDisplayEmail user)
- E.then_ (user E.^. UserDisplayEmail)
- , E.when_ (unique UserEmail user)
- E.then_ (user E.^. UserEmail)
- ]
- ( E.else_ $ user E.^. UserIdent)
- , user E.^. UserDisplayName
- )
- [whamlet|
- $newline never
-