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 - - $forall (email, dName) <- suggestedEmails -