feat(submission): edit notifications
This commit is contained in:
parent
e87f6075d3
commit
98c0d6919e
@ -826,6 +826,21 @@ EnglishEurope: Englisch (Europa)
|
|||||||
MailSubjectSubmissionRated csh@CourseShorthand: Ihre #{csh}-Abgabe wurde korrigiert
|
MailSubjectSubmissionRated csh@CourseShorthand: Ihre #{csh}-Abgabe wurde korrigiert
|
||||||
MailSubmissionRatedIntro courseName@Text termDesc@Text: Ihre Abgabe im Kurs #{courseName} (#{termDesc}) wurde korrigiert.
|
MailSubmissionRatedIntro courseName@Text termDesc@Text: Ihre Abgabe im Kurs #{courseName} (#{termDesc}) wurde korrigiert.
|
||||||
|
|
||||||
|
MailSubjectSubmissionEdited csh@CourseShorthand shn@SheetName: Ihre Abgabe für #{shn} im Kurs #{csh} wurde verändert
|
||||||
|
MailSubmissionEditedIntro coursen@CourseName shn@SheetName termDesc@Text displayName@Text: #{displayName} hat Ihre Abgabe für #{shn} im Kurs #{coursen} (#{termDesc}) verändert.
|
||||||
|
|
||||||
|
MailSubjectSubmissionUserCreated csh@CourseShorthand shn@SheetName: Sie wurden als Mitabgebender zu einer Abgabe für #{shn} im Kurs #{csh} hinzugefügt
|
||||||
|
MailSubjectSubmissionUserCreatedOther displayName@Text csh@CourseShorthand shn@SheetName: Es wurde ein Mitabgebender zu einer Abgabe für #{shn} im Kurs #{csh} hinzugefügt
|
||||||
|
|
||||||
|
MailSubmissionUserCreatedIntro coursen@CourseName shn@SheetName termDesc@Text: Sie wurden als Mitabgebender zu einer Abgabe für #{shn} im Kurs #{coursen} (#{termDesc}) hinzugefügt.
|
||||||
|
MailSubmissionUserCreatedOtherIntro displayName@UserDisplayName coursen@CourseName shn@SheetName termDesc@Text: #{displayName} wurde als Mitabgebender zu einer Abgabe für #{shn} im Kurs #{coursen} (#{termDesc}) hinzugefügt.
|
||||||
|
|
||||||
|
MailSubjectSubmissionUserDeleted csh@CourseShorthand shn@SheetName: Sie wurden als Mitabgebender von Ihrer Abgabe für #{shn} im Kurs #{csh} entfernt
|
||||||
|
MailSubjectSubmissionUserDeletedOther displayName@Text csh@CourseShorthand shn@SheetName: Es wurde ein Mitabgebender von einer Abgabe für #{shn} im Kurs #{csh} entfernt
|
||||||
|
|
||||||
|
MailSubmissionUserDeletedIntro coursen@CourseName shn@SheetName termDesc@Text: Sie wurden als Mitabgebender von Ihrer Abgabe für #{shn} im Kurs #{coursen} (#{termDesc}) entfernt.
|
||||||
|
MailSubmissionUserDeletedOtherIntro displayName@UserDisplayName coursen@CourseName shn@SheetName termDesc@Text: #{displayName} wurde als Mitabgebender von einer Abgabe für #{shn} im Kurs #{coursen} (#{termDesc}) entfernt.
|
||||||
|
|
||||||
MailSubjectSheetActive csh@CourseShorthand sheetName@SheetName: #{sheetName} in #{csh} wurde herausgegeben
|
MailSubjectSheetActive csh@CourseShorthand sheetName@SheetName: #{sheetName} in #{csh} wurde herausgegeben
|
||||||
MailSheetActiveIntro courseName@Text termDesc@Text sheetName@SheetName: Sie können nun #{sheetName} im Kurs #{courseName} (#{termDesc}) herunterladen.
|
MailSheetActiveIntro courseName@Text termDesc@Text sheetName@SheetName: Sie können nun #{sheetName} im Kurs #{courseName} (#{termDesc}) herunterladen.
|
||||||
|
|
||||||
@ -967,6 +982,9 @@ NotificationTriggerAllocationResults: Plätze wurden für eine meiner Zentralanm
|
|||||||
NotificationTriggerExamOfficeExamResults: Ich kann neue Prüfungsergebnisse einsehen
|
NotificationTriggerExamOfficeExamResults: Ich kann neue Prüfungsergebnisse einsehen
|
||||||
NotificationTriggerExamOfficeExamResultsChanged: Prüfungsergebnisse wurden verändert
|
NotificationTriggerExamOfficeExamResultsChanged: Prüfungsergebnisse wurden verändert
|
||||||
NotificationTriggerCourseRegistered: Ein Kursverwalter hat mich zu einem Kurs angemeldet
|
NotificationTriggerCourseRegistered: Ein Kursverwalter hat mich zu einem Kurs angemeldet
|
||||||
|
NotificationTriggerSubmissionUserCreated: Ich wurde als Mitabgebender zu einer Übungsblatt-Abgabe hinzugefügt
|
||||||
|
NotificationTriggerSubmissionEdited: Eine meiner Übungsblatt-Abgaben wurde verändert
|
||||||
|
NotificationTriggerSubmissionUserDeleted: Ich wurde als Mitabgebender von einer Übungsblatt-Abgabe entfernt
|
||||||
|
|
||||||
NotificationTriggerKindAll: Für alle Benutzer
|
NotificationTriggerKindAll: Für alle Benutzer
|
||||||
NotificationTriggerKindCourseParticipant: Für Kursteilnehmer
|
NotificationTriggerKindCourseParticipant: Für Kursteilnehmer
|
||||||
@ -979,6 +997,7 @@ NotificationTriggerKindExamOffice: Für das Prüfungsamt
|
|||||||
NotificationTriggerKindEvaluation: Für Vorlesungsumfragen
|
NotificationTriggerKindEvaluation: Für Vorlesungsumfragen
|
||||||
NotificationTriggerKindAllocationStaff: Für Zentralanmeldungen (Dozenten)
|
NotificationTriggerKindAllocationStaff: Für Zentralanmeldungen (Dozenten)
|
||||||
NotificationTriggerKindAllocationParticipant: Für Zentralanmeldungen
|
NotificationTriggerKindAllocationParticipant: Für Zentralanmeldungen
|
||||||
|
NotificationTriggerKindSubmissionUser: Für Mitabgebende einer Übungsblatt-Abgabe
|
||||||
|
|
||||||
CorrCreate: Abgaben registrieren
|
CorrCreate: Abgaben registrieren
|
||||||
UnknownPseudonymWord pseudonymWord@Text: Unbekanntes Pseudonym-Wort "#{pseudonymWord}"
|
UnknownPseudonymWord pseudonymWord@Text: Unbekanntes Pseudonym-Wort "#{pseudonymWord}"
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
PrintDebugForStupid name@Text: Debug message "#{name}"
|
PrintDebugForStupid name: Debug message "#{name}"
|
||||||
|
|
||||||
Logo: Uni2work
|
Logo: Uni2work
|
||||||
|
|
||||||
@ -160,17 +160,17 @@ CourseUserNoteTooltip: Only visible to administrators of this course
|
|||||||
CourseUserNoteSaved: Successfully saved note changes
|
CourseUserNoteSaved: Successfully saved note changes
|
||||||
CourseUserNoteDeleted: Successfully deleted user note deleted
|
CourseUserNoteDeleted: Successfully deleted user note deleted
|
||||||
CourseUserDeregister: Deregister from course
|
CourseUserDeregister: Deregister from course
|
||||||
CourseUsersDeregistered count@Int64: Successfully deregistered #{show count} users from course
|
CourseUsersDeregistered count: Successfully deregistered #{show count} users from course
|
||||||
CourseUserRegisterTutorial: Register for a tutorial
|
CourseUserRegisterTutorial: Register for a tutorial
|
||||||
CourseUsersTutorialRegistered count@Int64: Successfully registered #{show count} users for tutorial
|
CourseUsersTutorialRegistered count: Successfully registered #{show count} users for tutorial
|
||||||
CourseUserSendMail: Send mail
|
CourseUserSendMail: Send mail
|
||||||
TutorialUserDeregister: Deregister from tutorial
|
TutorialUserDeregister: Deregister from tutorial
|
||||||
TutorialUserSendMail: Send mail
|
TutorialUserSendMail: Send mail
|
||||||
TutorialUsersDeregistered count@Int64: Successfully deregistered #{show count} participants from tutorial
|
TutorialUsersDeregistered count: Successfully deregistered #{show count} participants from tutorial
|
||||||
CourseAllocationParticipate: Participate in central allocation
|
CourseAllocationParticipate: Participate in central allocation
|
||||||
CourseAllocationParticipateTip: If a course participates in a central allocation, you might lose some permissions that you would normally have (e.g. registering students for the course directly, deregistering students, ...)
|
CourseAllocationParticipateTip: If a course participates in a central allocation, you might lose some permissions that you would normally have (e.g. registering students for the course directly, deregistering students, ...)
|
||||||
CourseAllocation: Central allocation
|
CourseAllocation: Central allocation
|
||||||
CourseAllocationOption term@Text name@Text: #{name} (#{term})
|
CourseAllocationOption term name: #{name} (#{term})
|
||||||
CourseAllocationMinCapacity: Minimum number of participants
|
CourseAllocationMinCapacity: Minimum number of participants
|
||||||
CourseAllocationMinCapacityTip: If fewer students than this number were to be assigned to this course, then these students would instead be assigned to other courses
|
CourseAllocationMinCapacityTip: If fewer students than this number were to be assigned to this course, then these students would instead be assigned to other courses
|
||||||
CourseAllocationMinCapacityMustBeNonNegative: Minimum number of participants must not be negative
|
CourseAllocationMinCapacityMustBeNonNegative: Minimum number of participants must not be negative
|
||||||
@ -343,6 +343,8 @@ NoOpenSubmissions: No open submissions exist
|
|||||||
SubmissionsDeleteQuestion n: Do you really want to delete the #{pluralEN n "submission" "submissions"} mentioned below?
|
SubmissionsDeleteQuestion n: Do you really want to delete the #{pluralEN n "submission" "submissions"} mentioned below?
|
||||||
SubmissionsDeleted n: #{pluralEN n "Submission" "Submissions"} deleted
|
SubmissionsDeleted n: #{pluralEN n "Submission" "Submissions"} deleted
|
||||||
|
|
||||||
|
SubmissionDeleteCosubmittorsWarning n: You are not the only participant for #{pluralEN n "the submission" "all submissions"} mentioned above. Ensure that you delete submissions only in agreement with your co-submittors or remove yourself from the #{pluralEN n "submission" "submissions"}, instead!
|
||||||
|
|
||||||
SubmissionGroupName: Group name
|
SubmissionGroupName: Group name
|
||||||
|
|
||||||
CorrectionsTitle: Assigned corrections
|
CorrectionsTitle: Assigned corrections
|
||||||
@ -676,7 +678,7 @@ FormNotifications: Notifications
|
|||||||
FormBehaviour: Behaviour
|
FormBehaviour: Behaviour
|
||||||
FormCosmetics: Interface
|
FormCosmetics: Interface
|
||||||
FormPersonalAppearance: Public data
|
FormPersonalAppearance: Public data
|
||||||
FormFieldRequiredTip: Marked fields need to be filled
|
FormFieldRequiredTip: Required fields
|
||||||
|
|
||||||
PersonalInfoExamAchievementsWip: The feature to display your exam achievements has not yet been implemented.
|
PersonalInfoExamAchievementsWip: The feature to display your exam achievements has not yet been implemented.
|
||||||
PersonalInfoOwnTutorialsWip: The feature to display tutorials you have been assigned to as tutor has not yet been implemented.
|
PersonalInfoOwnTutorialsWip: The feature to display tutorials you have been assigned to as tutor has not yet been implemented.
|
||||||
@ -821,6 +823,24 @@ EnglishEurope: English (Europe)
|
|||||||
MailSubjectSubmissionRated csh: Your #{csh}-submission was marked
|
MailSubjectSubmissionRated csh: Your #{csh}-submission was marked
|
||||||
MailSubmissionRatedIntro courseName termDesc: Your submission for #{courseName} (#{termDesc}) was marked.
|
MailSubmissionRatedIntro courseName termDesc: Your submission for #{courseName} (#{termDesc}) was marked.
|
||||||
|
|
||||||
|
MailSubjectSubmissionEdited csh shn: Your submisson for #{shn} in #{csh} was edited
|
||||||
|
MailSubmissionEditedIntro coursen shn termDesc displayName: #{displayName} edited your submission for #{shn} in #{coursen} (#{termDesc}).
|
||||||
|
|
||||||
|
|
||||||
|
MailSubjectSubmissionUserCreated csh shn: You were added to a submission for #{shn} in #{csh}
|
||||||
|
MailSubjectSubmissionUserCreatedOther displayName csh shn: An user was added to a submission for #{shn} in #{csh}
|
||||||
|
|
||||||
|
|
||||||
|
MailSubmissionUserCreatedIntro coursen shn termDesc: You were added to a submission for #{shn} in #{coursen} (#{termDesc}).
|
||||||
|
MailSubmissionUserCreatedOtherIntro displayName coursen shn termDesc: #{displayName} was added as to a submission for #{shn} in #{coursen} (#{termDesc}).
|
||||||
|
|
||||||
|
|
||||||
|
MailSubjectSubmissionUserDeleted csh shn: You were removed from your submission for #{shn} in #{csh}
|
||||||
|
MailSubjectSubmissionUserDeletedOther displayName csh shn: An user was removed from your submission for #{shn} in #{csh}
|
||||||
|
|
||||||
|
MailSubmissionUserDeletedIntro coursen shn termDesc: You were removed from your submission for #{shn} in #{coursen} (#{termDesc}).
|
||||||
|
MailSubmissionUserDeletedOtherIntro displayName coursen shn termDesc: #{displayName} was removed from your submission for #{shn} in #{coursen} (#{termDesc}).
|
||||||
|
|
||||||
MailSubjectSheetActive csh sheetName: #{sheetName} in #{csh} was released
|
MailSubjectSheetActive csh sheetName: #{sheetName} in #{csh} was released
|
||||||
MailSheetActiveIntro courseName termDesc sheetName: You may now download #{sheetName} for #{courseName} (#{termDesc}).
|
MailSheetActiveIntro courseName termDesc sheetName: You may now download #{sheetName} for #{courseName} (#{termDesc}).
|
||||||
|
|
||||||
@ -962,6 +982,9 @@ NotificationTriggerAllocationResults: Participants have been placed by one of my
|
|||||||
NotificationTriggerExamOfficeExamResults: New exam results are available
|
NotificationTriggerExamOfficeExamResults: New exam results are available
|
||||||
NotificationTriggerExamOfficeExamResultsChanged: Exam results have changed
|
NotificationTriggerExamOfficeExamResultsChanged: Exam results have changed
|
||||||
NotificationTriggerCourseRegistered: A course administrator has enrolled me in a course
|
NotificationTriggerCourseRegistered: A course administrator has enrolled me in a course
|
||||||
|
NotificationTriggerSubmissionUserCreated: I was added to an exercise sheet submission
|
||||||
|
NotificationTriggerSubmissionEdited: One of my exercise sheet submissions was changed
|
||||||
|
NotificationTriggerSubmissionUserDeleted: I was removed from one of my exercise sheet submissions
|
||||||
|
|
||||||
NotificationTriggerKindAll: For all users
|
NotificationTriggerKindAll: For all users
|
||||||
NotificationTriggerKindCourseParticipant: For course participants
|
NotificationTriggerKindCourseParticipant: For course participants
|
||||||
@ -974,6 +997,7 @@ NotificationTriggerKindExamOffice: For the exam office
|
|||||||
NotificationTriggerKindEvaluation: For course evaluations
|
NotificationTriggerKindEvaluation: For course evaluations
|
||||||
NotificationTriggerKindAllocationStaff: For central allocations (lecturers)
|
NotificationTriggerKindAllocationStaff: For central allocations (lecturers)
|
||||||
NotificationTriggerKindAllocationParticipant: For central allocations
|
NotificationTriggerKindAllocationParticipant: For central allocations
|
||||||
|
NotificationTriggerKindSubmissionUser: For participants in an exercise sheet submission
|
||||||
|
|
||||||
CorrCreate: Register submissions
|
CorrCreate: Register submissions
|
||||||
UnknownPseudonymWord pseudonymWord: Invalid pseudonym-word “#{pseudonymWord}”
|
UnknownPseudonymWord pseudonymWord: Invalid pseudonym-word “#{pseudonymWord}”
|
||||||
@ -1050,25 +1074,25 @@ MessageSuccess: Success
|
|||||||
InvalidLangFormat: Invalid language code (RFC1766)
|
InvalidLangFormat: Invalid language code (RFC1766)
|
||||||
|
|
||||||
ErrorResponseTitleNotFound: Resource not found
|
ErrorResponseTitleNotFound: Resource not found
|
||||||
ErrorResponseTitleInternalError internalError@Text: An internal error occurred
|
ErrorResponseTitleInternalError internalError: An internal error occurred
|
||||||
ErrorResponseTitleInvalidArgs invalidArgs@Texts: Request contained invalid arguments
|
ErrorResponseTitleInvalidArgs invalidArgs: Request contained invalid arguments
|
||||||
ErrorResponseTitleNotAuthenticated: Request requires authentication
|
ErrorResponseTitleNotAuthenticated: Request requires authentication
|
||||||
ErrorResponseTitlePermissionDenied permissionDenied@Text: Permission denied
|
ErrorResponseTitlePermissionDenied permissionDenied: Permission denied
|
||||||
ErrorResponseTitleBadMethod requestMethod@Method: HTTP-method not supported
|
ErrorResponseTitleBadMethod requestMethod: HTTP-method not supported
|
||||||
|
|
||||||
UnknownErrorResponse: An error has occurred that could not be further classified:
|
UnknownErrorResponse: An error has occurred that could not be further classified:
|
||||||
ErrorResponseNotFound: No page could be found under the url requested by your browser.
|
ErrorResponseNotFound: No page could be found under the url requested by your browser.
|
||||||
ErrorResponseNotAuthenticated: To be granted access to most parts of Uni2work you need to login first.
|
ErrorResponseNotAuthenticated: To be granted access to most parts of Uni2work you need to login first.
|
||||||
ErrorResponseBadMethod requestMethodText@Text: Your browser can interact in multiple ways with the resources offered by Uni2work. The requested method (#{requestMethodText}) is not supported here.
|
ErrorResponseBadMethod requestMethodText: Your browser can interact in multiple ways with the resources offered by Uni2work. The requested method (#{requestMethodText}) is not supported here.
|
||||||
|
|
||||||
ErrorResponseEncrypted: In order not to reveal sensitive information further details have been encrypted. If you send a support request, please include the encrypted data listed below.
|
ErrorResponseEncrypted: In order not to reveal sensitive information further details have been encrypted. If you send a support request, please include the encrypted data listed below.
|
||||||
ErrMsgCiphertext: Encrypted error message
|
ErrMsgCiphertext: Encrypted error message
|
||||||
EncodedSecretBoxCiphertextTooShort: Encrypted data are too short to be valid
|
EncodedSecretBoxCiphertextTooShort: Encrypted data are too short to be valid
|
||||||
EncodedSecretBoxInvalidBase64 base64Err@String: Encrypted data ar not correctly base64url-encoded: #{base64Err}
|
EncodedSecretBoxInvalidBase64 base64Err: Encrypted data ar not correctly base64url-encoded: #{base64Err}
|
||||||
EncodedSecretBoxInvalidPadding: Encrypted data are not padded correctly
|
EncodedSecretBoxInvalidPadding: Encrypted data are not padded correctly
|
||||||
EncodedSecretBoxCouldNotDecodeNonce: Could not decode secretbox-nonce
|
EncodedSecretBoxCouldNotDecodeNonce: Could not decode secretbox-nonce
|
||||||
EncodedSecretBoxCouldNotOpenSecretBox: Could not open libsodium-secretbox (Encrypted data are not authentic)
|
EncodedSecretBoxCouldNotOpenSecretBox: Could not open libsodium-secretbox (Encrypted data are not authentic)
|
||||||
EncodedSecretBoxCouldNotDecodePlaintext aesonErr@String: Could not decode json cleartext: #{aesonErr}
|
EncodedSecretBoxCouldNotDecodePlaintext aesonErr: Could not decode json cleartext: #{aesonErr}
|
||||||
ErrMsgHeading: Decrypt error message
|
ErrMsgHeading: Decrypt error message
|
||||||
|
|
||||||
InvalidRoute: Could not interpret url
|
InvalidRoute: Could not interpret url
|
||||||
@ -1136,7 +1160,7 @@ MenuCorrectionsDownload: Download corrections
|
|||||||
MenuCorrectionsCreate: Register submissions
|
MenuCorrectionsCreate: Register submissions
|
||||||
MenuCorrectionsGrade: Grade submissions
|
MenuCorrectionsGrade: Grade submissions
|
||||||
MenuCorrectionsAssign: Assign corrections
|
MenuCorrectionsAssign: Assign corrections
|
||||||
MenuCorrectionsAssignSheet name@Text: Assign corrections for #{name}
|
MenuCorrectionsAssignSheet name: Assign corrections for #{name}
|
||||||
MenuAuthPreds: Authorisation settings
|
MenuAuthPreds: Authorisation settings
|
||||||
MenuTutorialDelete: Delete tutorial
|
MenuTutorialDelete: Delete tutorial
|
||||||
MenuTutorialEdit: Edit tutorial
|
MenuTutorialEdit: Edit tutorial
|
||||||
@ -1840,6 +1864,7 @@ AllocationSchoolShort: Department
|
|||||||
Allocation: Central allocation
|
Allocation: Central allocation
|
||||||
AllocationRegisterTo: Registration until
|
AllocationRegisterTo: Registration until
|
||||||
|
|
||||||
|
|
||||||
AllocationListTitle: Central allocations
|
AllocationListTitle: Central allocations
|
||||||
|
|
||||||
CourseApplicationsListTitle: Applications
|
CourseApplicationsListTitle: Applications
|
||||||
@ -1910,16 +1935,16 @@ ExamOfficeSubscribedUsersTip: You may specify multiple matriculations; comma-sep
|
|||||||
ExamOfficeSubscribedUsersExplanation: You will be able to view all exam achievements (with no regard for the students fields of study) for all users specified here.
|
ExamOfficeSubscribedUsersExplanation: You will be able to view all exam achievements (with no regard for the students fields of study) for all users specified here.
|
||||||
ExamOfficeSubscribedFieldsExplanation: You will be able to view all exam achievements for any user that has at least one of the specified fields of study. You may additionally configure whether users should be allowed to opt out on a course by course basis.
|
ExamOfficeSubscribedFieldsExplanation: You will be able to view all exam achievements for any user that has at least one of the specified fields of study. You may additionally configure whether users should be allowed to opt out on a course by course basis.
|
||||||
|
|
||||||
UserMatriculationNotFound matriculation@Text: Es existiert kein Uni2work-Benutzer mit Matrikelnummer „#{matriculation}“
|
UserMatriculationNotFound matriculation: There is no uni2work-user with matriculation “#{matriculation}”
|
||||||
UserMatriculationAmbiguous matriculation@Text: Matrikelnummer „#{matriculation}“ ist nicht eindeutig
|
UserMatriculationAmbiguous matriculation: Matriculation “#{matriculation}” isn't unique
|
||||||
|
|
||||||
TransactionExamOfficeUsersUpdated nDeleted@Int nAdded@Int: #{nAdded} Benutzer hinzugefügt, #{nDeleted} Benutzer gelöscht
|
TransactionExamOfficeUsersUpdated nDeleted nAdded: Added #{nAdded} #{pluralEN nAdded "user" "users"}, deleted #{nDeleted}
|
||||||
|
|
||||||
TransactionExamOfficeFieldsUpdated nUpdates@Int: #{nUpdates} #{pluralDE nUpdates "Studienfach" "Studienfächer"} angepasst
|
TransactionExamOfficeFieldsUpdated nUpdates: Edited #{nUpdates} #{pluralEN nUpdates "field of study" "fields of study"}
|
||||||
ExamOfficeFieldNotSubscribed: —
|
ExamOfficeFieldNotSubscribed: —
|
||||||
ExamOfficeFieldSubscribed: Einsicht
|
ExamOfficeFieldSubscribed: Access
|
||||||
ExamOfficeFieldForced: Forcierte Einsicht
|
ExamOfficeFieldForced: Forced access
|
||||||
InvalidExamOfficeFieldMode parseErr@Text: Konnte „#{parseErr}“ nicht interpretieren
|
InvalidExamOfficeFieldMode parseErr: Could not parse “#{parseErr}”
|
||||||
|
|
||||||
LdapIdentification: Campus account
|
LdapIdentification: Campus account
|
||||||
LdapIdentificationOrEmail: Campus account/email address
|
LdapIdentificationOrEmail: Campus account/email address
|
||||||
|
|||||||
@ -904,11 +904,11 @@ postCorrectionsCreateR = do
|
|||||||
forM_ (Map.toList invalids) $ \((oPseudonyms, iPseudonym), alts) -> $(addMessageFile Error "templates/messages/ignoredInvalidPseudonym.hamlet")
|
forM_ (Map.toList invalids) $ \((oPseudonyms, iPseudonym), alts) -> $(addMessageFile Error "templates/messages/ignoredInvalidPseudonym.hamlet")
|
||||||
tell . All $ null invalids
|
tell . All $ null invalids
|
||||||
|
|
||||||
WriterT . runDB . mapReaderT runWriterT $ do
|
WriterT . runDBJobs . mapReaderT (mapWriterT $ fmap ((,) <$> ((,) <$> view (_1 . _1) <*> view _2) <*> view (_1 . _2)) . runWriterT) $ do
|
||||||
Sheet{..} <- get404 sid
|
Sheet{..} <- get404 sid :: ReaderT SqlBackend (WriterT (Set QueuedJobId) (WriterT All (HandlerFor UniWorX))) Sheet
|
||||||
(sps, unknown) <- fmap partitionEithers' . forM pss . mapM $ \p -> maybe (Left p) Right <$> getBy (UniqueSheetPseudonym sid p)
|
(sps, unknown) <- fmap partitionEithers' . forM pss . mapM $ \p -> maybe (Left p) Right <$> getBy (UniqueSheetPseudonym sid p)
|
||||||
forM_ unknown $ addMessageI Error . MsgUnknownPseudonym . review _PseudonymText
|
forM_ unknown $ addMessageI Error . MsgUnknownPseudonym . review _PseudonymText
|
||||||
tell . All $ null unknown
|
lift . lift . tell . All $ null unknown
|
||||||
now <- liftIO getCurrentTime
|
now <- liftIO getCurrentTime
|
||||||
let
|
let
|
||||||
sps' :: [[SheetPseudonym]]
|
sps' :: [[SheetPseudonym]]
|
||||||
@ -935,7 +935,7 @@ postCorrectionsCreateR = do
|
|||||||
E.&&. submission E.^. SubmissionSheet E.==. E.val sid
|
E.&&. submission E.^. SubmissionSheet E.==. E.val sid
|
||||||
return submissionUser
|
return submissionUser
|
||||||
unless (null existingSubUsers) . mapReaderT lift $ do
|
unless (null existingSubUsers) . mapReaderT lift $ do
|
||||||
(Map.toList -> subs) <- foldrM (\(Entity _ SubmissionUser{..}) mp -> Map.insertWith (<>) <$> (encrypt submissionUserSubmission :: DB CryptoFileNameSubmission) <*> pure (Set.fromList . map sheetPseudonymPseudonym . filter (\SheetPseudonym{..} -> sheetPseudonymUser == submissionUserUser) $ concat sps') <*> pure mp) Map.empty existingSubUsers
|
(Map.toList -> subs) <- foldrM (\(Entity _ SubmissionUser{..}) mp -> Map.insertWith (<>) <$> (encrypt submissionUserSubmission :: _ CryptoFileNameSubmission) <*> pure (Set.fromList . map sheetPseudonymPseudonym . filter (\SheetPseudonym{..} -> sheetPseudonymUser == submissionUserUser) $ concat sps') <*> pure mp) Map.empty existingSubUsers
|
||||||
let trigger = [whamlet|_{MsgSheetCreateExisting}|]
|
let trigger = [whamlet|_{MsgSheetCreateExisting}|]
|
||||||
content = Right $(widgetFile "messages/submissionCreateExisting")
|
content = Right $(widgetFile "messages/submissionCreateExisting")
|
||||||
addMessageModal Warning trigger content
|
addMessageModal Warning trigger content
|
||||||
@ -952,7 +952,9 @@ postCorrectionsCreateR = do
|
|||||||
{ submissionUserUser = sheetPseudonymUser
|
{ submissionUserUser = sheetPseudonymUser
|
||||||
, submissionUserSubmission = subId
|
, submissionUserSubmission = subId
|
||||||
}
|
}
|
||||||
forM_ spGroup $ \SheetPseudonym{sheetPseudonymUser} -> audit $ TransactionSubmissionUserEdit subId sheetPseudonymUser
|
forM_ spGroup $ \SheetPseudonym{sheetPseudonymUser} -> do
|
||||||
|
hoist (hoist lift) . queueDBJob . JobQueueNotification $ NotificationSubmissionUserCreated uid subId
|
||||||
|
audit $ TransactionSubmissionUserEdit subId sheetPseudonymUser
|
||||||
when (genericLength spGroup > maxSize) $
|
when (genericLength spGroup > maxSize) $
|
||||||
addMessageI Warning $ MsgSheetGroupTooLarge sheetGroupDesc
|
addMessageI Warning $ MsgSheetGroupTooLarge sheetGroupDesc
|
||||||
RegisteredGroups -> do
|
RegisteredGroups -> do
|
||||||
@ -975,14 +977,16 @@ postCorrectionsCreateR = do
|
|||||||
{ submissionUserUser = sheetUser
|
{ submissionUserUser = sheetUser
|
||||||
, submissionUserSubmission = subId
|
, submissionUserSubmission = subId
|
||||||
}
|
}
|
||||||
forM_ groupUsers $ audit . TransactionSubmissionUserEdit subId
|
forM_ groupUsers $ \subUid -> do
|
||||||
|
hoist (hoist lift) . queueDBJob . JobQueueNotification $ NotificationSubmissionUserCreated subUid subId
|
||||||
|
audit $ TransactionSubmissionUserEdit subId subUid
|
||||||
when (null groups) $
|
when (null groups) $
|
||||||
addMessageI Warning $ MsgSheetNoRegisteredGroup sheetGroupDesc
|
addMessageI Warning $ MsgSheetNoRegisteredGroup sheetGroupDesc
|
||||||
| length groups < 2
|
| length groups < 2
|
||||||
-> do
|
-> do
|
||||||
forM_ (Set.toList (Map.keysSet spGroup' `Set.difference` groupUsers)) $ \((spGroup' !) -> SheetPseudonym{sheetPseudonymPseudonym}) -> do
|
forM_ (Set.toList (Map.keysSet spGroup' `Set.difference` groupUsers)) $ \((spGroup' !) -> SheetPseudonym{sheetPseudonymPseudonym}) -> do
|
||||||
addMessageI Error $ MsgSheetNoRegisteredGroup (review _PseudonymText sheetPseudonymPseudonym)
|
addMessageI Error $ MsgSheetNoRegisteredGroup (review _PseudonymText sheetPseudonymPseudonym)
|
||||||
tell $ All False
|
lift . lift . tell $ All False
|
||||||
| otherwise ->
|
| otherwise ->
|
||||||
addMessageI Error $ MsgSheetAmbiguousRegisteredGroup sheetGroupDesc
|
addMessageI Error $ MsgSheetAmbiguousRegisteredGroup sheetGroupDesc
|
||||||
NoGroups -> do
|
NoGroups -> do
|
||||||
@ -993,7 +997,9 @@ postCorrectionsCreateR = do
|
|||||||
{ submissionUserUser = sheetPseudonymUser
|
{ submissionUserUser = sheetPseudonymUser
|
||||||
, submissionUserSubmission = subId
|
, submissionUserSubmission = subId
|
||||||
}
|
}
|
||||||
forM_ spGroup $ \SheetPseudonym{sheetPseudonymUser} -> audit $ TransactionSubmissionUserEdit subId sheetPseudonymUser
|
forM_ spGroup $ \SheetPseudonym{sheetPseudonymUser} -> do
|
||||||
|
hoist (hoist lift) . queueDBJob . JobQueueNotification $ NotificationSubmissionUserCreated uid subId
|
||||||
|
audit $ TransactionSubmissionUserEdit subId sheetPseudonymUser
|
||||||
when (length spGroup > 1) $
|
when (length spGroup > 1) $
|
||||||
addMessageI Warning $ MsgSheetNoGroupSubmission sheetGroupDesc
|
addMessageI Warning $ MsgSheetNoGroupSubmission sheetGroupDesc
|
||||||
when allDone $
|
when allDone $
|
||||||
@ -1080,10 +1086,10 @@ postCorrectionsGradeR = do
|
|||||||
| submissionRatingPoints /= mPoints || submissionRatingComment /= mComment || rated /= submissionRatingDone s
|
| submissionRatingPoints /= mPoints || submissionRatingComment /= mComment || rated /= submissionRatingDone s
|
||||||
-> do audit $ TransactionSubmissionEdit subId $ s ^. _submissionSheet
|
-> do audit $ TransactionSubmissionEdit subId $ s ^. _submissionSheet
|
||||||
Just subId <$ update subId [ SubmissionRatingPoints =. mPoints
|
Just subId <$ update subId [ SubmissionRatingPoints =. mPoints
|
||||||
, SubmissionRatingComment =. mComment
|
, SubmissionRatingComment =. mComment
|
||||||
, SubmissionRatingBy =. Just uid
|
, SubmissionRatingBy =. Just uid
|
||||||
, SubmissionRatingTime =. now <$ guard rated
|
, SubmissionRatingTime =. now <$ guard rated
|
||||||
]
|
]
|
||||||
| otherwise -> return Nothing
|
| otherwise -> return Nothing
|
||||||
subs' <- traverse (\x -> (,) <$> encrypt x <*> encrypt x) subs :: Handler [(CryptoFileNameSubmission, CryptoUUIDSubmission)]
|
subs' <- traverse (\x -> (,) <$> encrypt x <*> encrypt x) subs :: Handler [(CryptoFileNameSubmission, CryptoUUIDSubmission)]
|
||||||
let trigger = [whamlet|_{MsgCorrectionsUploaded (genericLength subs')}|]
|
let trigger = [whamlet|_{MsgCorrectionsUploaded (genericLength subs')}|]
|
||||||
|
|||||||
@ -46,7 +46,7 @@ postCEvDeleteR tid ssh csh cID = do
|
|||||||
drFormMessage :: [Entity CourseEvent] -> DB (Maybe Message)
|
drFormMessage :: [Entity CourseEvent] -> DB (Maybe Message)
|
||||||
drFormMessage _ = return Nothing
|
drFormMessage _ = return Nothing
|
||||||
|
|
||||||
drDelete :: forall a. CourseEventId -> DB a -> DB a
|
drDelete :: forall a. CourseEventId -> JobDB a -> JobDB a
|
||||||
drDelete _ = id
|
drDelete _ = id
|
||||||
|
|
||||||
deleteR DeleteRoute{..}
|
deleteR DeleteRoute{..}
|
||||||
|
|||||||
@ -41,7 +41,7 @@ postCNDeleteR tid ssh csh cID = do
|
|||||||
drFormMessage :: [Entity CourseNews] -> DB (Maybe Message)
|
drFormMessage :: [Entity CourseNews] -> DB (Maybe Message)
|
||||||
drFormMessage _ = return Nothing
|
drFormMessage _ = return Nothing
|
||||||
|
|
||||||
drDelete :: forall a. CourseNewsId -> DB a -> DB a
|
drDelete :: forall a. CourseNewsId -> JobDB a -> JobDB a
|
||||||
drDelete _ = id
|
drDelete _ = id
|
||||||
|
|
||||||
deleteR DeleteRoute{..}
|
deleteR DeleteRoute{..}
|
||||||
|
|||||||
@ -51,6 +51,7 @@ makeLenses_ ''SettingsForm
|
|||||||
data NotificationTriggerKind
|
data NotificationTriggerKind
|
||||||
= NTKAll
|
= NTKAll
|
||||||
| NTKCourseParticipant
|
| NTKCourseParticipant
|
||||||
|
| NTKSubmissionUser
|
||||||
| NTKExamParticipant
|
| NTKExamParticipant
|
||||||
| NTKCorrector
|
| NTKCorrector
|
||||||
| NTKCourseLecturer
|
| NTKCourseLecturer
|
||||||
@ -64,6 +65,7 @@ instance RenderMessage UniWorX NotificationTriggerKind where
|
|||||||
renderMessage f ls = \case
|
renderMessage f ls = \case
|
||||||
NTKAll -> mr MsgNotificationTriggerKindAll
|
NTKAll -> mr MsgNotificationTriggerKindAll
|
||||||
NTKCourseParticipant -> mr MsgNotificationTriggerKindCourseParticipant
|
NTKCourseParticipant -> mr MsgNotificationTriggerKindCourseParticipant
|
||||||
|
NTKSubmissionUser -> mr MsgNotificationTriggerKindSubmissionUser
|
||||||
NTKExamParticipant -> mr MsgNotificationTriggerKindExamParticipant
|
NTKExamParticipant -> mr MsgNotificationTriggerKindExamParticipant
|
||||||
NTKCorrector -> mr MsgNotificationTriggerKindCorrector
|
NTKCorrector -> mr MsgNotificationTriggerKindCorrector
|
||||||
NTKCourseLecturer -> mr MsgNotificationTriggerKindCourseLecturer
|
NTKCourseLecturer -> mr MsgNotificationTriggerKindCourseLecturer
|
||||||
@ -158,6 +160,10 @@ notificationForm template = wFormToAForm $ do
|
|||||||
= fmap not . E.selectExists . E.from $ \courseParticipant ->
|
= fmap not . E.selectExists . E.from $ \courseParticipant ->
|
||||||
E.where_ $ courseParticipant E.^. CourseParticipantUser E.==. E.val uid
|
E.where_ $ courseParticipant E.^. CourseParticipantUser E.==. E.val uid
|
||||||
| Just uid <- mbUid
|
| Just uid <- mbUid
|
||||||
|
, NTKSubmissionUser <- nt
|
||||||
|
= fmap not . E.selectExists . E.from $ \submissionUser ->
|
||||||
|
E.where_ $ submissionUser E.^. SubmissionUserUser E.==. E.val uid
|
||||||
|
| Just uid <- mbUid
|
||||||
, NTKExamParticipant <- nt
|
, NTKExamParticipant <- nt
|
||||||
= fmap not . E.selectExists . E.from $ \examRegistration ->
|
= fmap not . E.selectExists . E.from $ \examRegistration ->
|
||||||
E.where_ $ examRegistration E.^. ExamRegistrationUser E.==. E.val uid
|
E.where_ $ examRegistration E.^. ExamRegistrationUser E.==. E.val uid
|
||||||
@ -186,6 +192,9 @@ notificationForm template = wFormToAForm $ do
|
|||||||
ntSection = \case
|
ntSection = \case
|
||||||
NTSubmissionRatedGraded -> Just NTKCourseParticipant
|
NTSubmissionRatedGraded -> Just NTKCourseParticipant
|
||||||
NTSubmissionRated -> Just NTKCourseParticipant
|
NTSubmissionRated -> Just NTKCourseParticipant
|
||||||
|
NTSubmissionUserCreated -> Just NTKCourseParticipant
|
||||||
|
NTSubmissionUserDeleted -> Just NTKSubmissionUser
|
||||||
|
NTSubmissionEdited -> Just NTKSubmissionUser
|
||||||
NTSheetActive -> Just NTKCourseParticipant
|
NTSheetActive -> Just NTKCourseParticipant
|
||||||
NTSheetSoonInactive -> Just NTKCourseParticipant
|
NTSheetSoonInactive -> Just NTKCourseParticipant
|
||||||
NTSheetInactive -> Just NTKCourseLecturer
|
NTSheetInactive -> Just NTKCourseLecturer
|
||||||
|
|||||||
@ -503,12 +503,16 @@ submissionHelper tid ssh csh shn mcid = do
|
|||||||
-- user exists and has an id => insert as SubmissionUser and audit
|
-- user exists and has an id => insert as SubmissionUser and audit
|
||||||
insert_ $ SubmissionUser subUid smid
|
insert_ $ SubmissionUser subUid smid
|
||||||
audit $ TransactionSubmissionUserEdit smid subUid
|
audit $ TransactionSubmissionUserEdit smid subUid
|
||||||
|
unless (subUid == uid) $
|
||||||
|
queueDBJob . JobQueueNotification $ NotificationSubmissionUserCreated subUid smid
|
||||||
-- change is an old user that is not a submission user anymore => delete invitation / delete
|
-- change is an old user that is not a submission user anymore => delete invitation / delete
|
||||||
| otherwise -> case change of
|
| otherwise -> case change of
|
||||||
Left subEmail -> deleteInvitation @SubmissionUser smid subEmail
|
Left subEmail -> deleteInvitation @SubmissionUser smid subEmail
|
||||||
Right subUid -> do
|
Right subUid -> do
|
||||||
deleteBy $ UniqueSubmissionUser subUid smid
|
deleteBy $ UniqueSubmissionUser subUid smid
|
||||||
audit $ TransactionSubmissionUserDelete smid subUid
|
audit $ TransactionSubmissionUserDelete smid subUid
|
||||||
|
unless (subUid == uid) $
|
||||||
|
queueDBJob . JobQueueNotification $ NotificationSubmissionUserDeleted subUid shid smid
|
||||||
|
|
||||||
addMessageI Success $ if | Nothing <- msmid -> MsgSubmissionCreated
|
addMessageI Success $ if | Nothing <- msmid -> MsgSubmissionCreated
|
||||||
| otherwise -> MsgSubmissionUpdated
|
| otherwise -> MsgSubmissionUpdated
|
||||||
|
|||||||
@ -12,6 +12,7 @@ module Handler.Utils.Delete
|
|||||||
( DeleteRoute(..)
|
( DeleteRoute(..)
|
||||||
, deleteR
|
, deleteR
|
||||||
, postDeleteR, getDeleteR
|
, postDeleteR, getDeleteR
|
||||||
|
, JobDB
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Import
|
import Import
|
||||||
@ -28,6 +29,8 @@ import qualified Database.Esqueleto as E
|
|||||||
import qualified Database.Esqueleto.Internal.Sql as E (SqlSelect)
|
import qualified Database.Esqueleto.Internal.Sql as E (SqlSelect)
|
||||||
import qualified Database.Esqueleto.Internal.Language as E (From)
|
import qualified Database.Esqueleto.Internal.Language as E (From)
|
||||||
|
|
||||||
|
import Jobs.Queue
|
||||||
|
|
||||||
|
|
||||||
data DeleteRoute record = forall tables infoExpr info. (E.SqlSelect infoExpr info, E.From tables) => DeleteRoute
|
data DeleteRoute record = forall tables infoExpr info. (E.SqlSelect infoExpr info, E.From tables) => DeleteRoute
|
||||||
{ drRecords :: Set (Key record) -- ^ Records to be deleted
|
{ drRecords :: Set (Key record) -- ^ Records to be deleted
|
||||||
@ -40,7 +43,7 @@ data DeleteRoute record = forall tables infoExpr info. (E.SqlSelect infoExpr inf
|
|||||||
, drSuccessMessage :: SomeMessage UniWorX
|
, drSuccessMessage :: SomeMessage UniWorX
|
||||||
, drAbort
|
, drAbort
|
||||||
, drSuccess :: SomeRoute UniWorX
|
, drSuccess :: SomeRoute UniWorX
|
||||||
, drDelete :: forall a. Key record -> DB a -> DB a
|
, drDelete :: forall a. Key record -> JobDB a -> JobDB a
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmForm :: ( MonadHandler m, HandlerSite m ~ UniWorX )
|
confirmForm :: ( MonadHandler m, HandlerSite m ~ UniWorX )
|
||||||
@ -101,7 +104,7 @@ deleteR' DeleteRoute{..} = do
|
|||||||
|
|
||||||
formResult confirmRes $ \case
|
formResult confirmRes $ \case
|
||||||
True -> do
|
True -> do
|
||||||
runDB $ do
|
runDBJobs $ do
|
||||||
forM_ drRecords $ \k -> drDelete k $ deleteCascade k
|
forM_ drRecords $ \k -> drDelete k $ deleteCascade k
|
||||||
addMessageI Success drSuccessMessage
|
addMessageI Success drSuccessMessage
|
||||||
redirect drSuccess
|
redirect drSuccess
|
||||||
|
|||||||
@ -626,6 +626,12 @@ sinkSubmission userId mExists isUpdate = do
|
|||||||
| isUpdate
|
| isUpdate
|
||||||
, getAny sinkSubmissionNotifyRating
|
, getAny sinkSubmissionNotifyRating
|
||||||
-> queueDBJob . JobQueueNotification $ NotificationSubmissionRated submissionId
|
-> queueDBJob . JobQueueNotification $ NotificationSubmissionRated submissionId
|
||||||
|
| not isUpdate
|
||||||
|
, getAny sinkSubmissionTouched
|
||||||
|
, is _Right mExists
|
||||||
|
-> do
|
||||||
|
uid <- requireAuthId
|
||||||
|
queueDBJob . JobQueueNotification $ NotificationSubmissionEdited uid submissionId
|
||||||
| otherwise -> return ()
|
| otherwise -> return ()
|
||||||
|
|
||||||
|
|
||||||
@ -763,5 +769,14 @@ submissionDeleteRoute drRecords = DeleteRoute
|
|||||||
, drSuccessMessage = SomeMessage $ MsgSubmissionsDeleted 1
|
, drSuccessMessage = SomeMessage $ MsgSubmissionsDeleted 1
|
||||||
, drAbort = error "drAbort undefined"
|
, drAbort = error "drAbort undefined"
|
||||||
, drSuccess = error "drSuccess undefined"
|
, drSuccess = error "drSuccess undefined"
|
||||||
, drDelete = \subId del -> getJust subId >>= \sub -> audit (TransactionSubmissionDelete subId $ sub ^. _submissionSheet) >> del
|
, drDelete = \subId del -> do
|
||||||
|
Submission{..} <- getJust subId
|
||||||
|
subUsers <- setOf (folded . _entityVal . _submissionUserUser) <$> selectList [SubmissionUserSubmission ==. subId] []
|
||||||
|
audit $ TransactionSubmissionDelete subId submissionSheet
|
||||||
|
|
||||||
|
uid <- requireAuthId
|
||||||
|
forM_ (Set.delete uid subUsers) $ \subUid ->
|
||||||
|
queueDBJob . JobQueueNotification $ NotificationSubmissionUserDeleted subUid submissionSheet subId
|
||||||
|
|
||||||
|
del
|
||||||
}
|
}
|
||||||
|
|||||||
@ -225,6 +225,16 @@ determineNotificationCandidates notif@NotificationAllocationResults{..} = do
|
|||||||
return user
|
return user
|
||||||
determineNotificationCandidates NotificationCourseRegistered{..} =
|
determineNotificationCandidates NotificationCourseRegistered{..} =
|
||||||
maybeToList <$> getEntity nUser
|
maybeToList <$> getEntity nUser
|
||||||
|
determineNotificationCandidates NotificationSubmissionEdited{..} =
|
||||||
|
E.select . E.from $ \(user `E.InnerJoin` submissionUser) -> do
|
||||||
|
E.on $ user E.^. UserId E.==. submissionUser E.^. SubmissionUserUser
|
||||||
|
E.where_ $ submissionUser E.^. SubmissionUserSubmission E.==. E.val nSubmission
|
||||||
|
E.&&. user E.^. UserId E.!=. E.val nInitiator
|
||||||
|
return user
|
||||||
|
determineNotificationCandidates NotificationSubmissionUserCreated{..} =
|
||||||
|
maybeToList <$> getEntity nUser
|
||||||
|
determineNotificationCandidates NotificationSubmissionUserDeleted{..} =
|
||||||
|
maybeToList <$> getEntity nUser
|
||||||
|
|
||||||
|
|
||||||
classifyNotification :: Notification -> DB NotificationTrigger
|
classifyNotification :: Notification -> DB NotificationTrigger
|
||||||
@ -253,3 +263,6 @@ classifyNotification NotificationExamOfficeExamResults{} = return NTExa
|
|||||||
classifyNotification NotificationExamOfficeExamResultsChanged{} = return NTExamOfficeExamResultsChanged
|
classifyNotification NotificationExamOfficeExamResultsChanged{} = return NTExamOfficeExamResultsChanged
|
||||||
classifyNotification NotificationAllocationResults{} = return NTAllocationResults
|
classifyNotification NotificationAllocationResults{} = return NTAllocationResults
|
||||||
classifyNotification NotificationCourseRegistered{} = return NTCourseRegistered
|
classifyNotification NotificationCourseRegistered{} = return NTCourseRegistered
|
||||||
|
classifyNotification NotificationSubmissionEdited{} = return NTSubmissionEdited
|
||||||
|
classifyNotification NotificationSubmissionUserCreated{} = return NTSubmissionUserCreated
|
||||||
|
classifyNotification NotificationSubmissionUserDeleted{} = return NTSubmissionUserDeleted
|
||||||
|
|||||||
@ -19,6 +19,7 @@ import Jobs.Handler.SendNotification.ExamResult
|
|||||||
import Jobs.Handler.SendNotification.Allocation
|
import Jobs.Handler.SendNotification.Allocation
|
||||||
import Jobs.Handler.SendNotification.ExamOffice
|
import Jobs.Handler.SendNotification.ExamOffice
|
||||||
import Jobs.Handler.SendNotification.CourseRegistered
|
import Jobs.Handler.SendNotification.CourseRegistered
|
||||||
|
import Jobs.Handler.SendNotification.SubmissionEdited
|
||||||
|
|
||||||
|
|
||||||
dispatchJobSendNotification :: UserId -> Notification -> Handler ()
|
dispatchJobSendNotification :: UserId -> Notification -> Handler ()
|
||||||
|
|||||||
138
src/Jobs/Handler/SendNotification/SubmissionEdited.hs
Normal file
138
src/Jobs/Handler/SendNotification/SubmissionEdited.hs
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
{-# OPTIONS_GHC -fno-warn-unused-do-bind #-} -- ihamletFile discards do results
|
||||||
|
|
||||||
|
module Jobs.Handler.SendNotification.SubmissionEdited
|
||||||
|
( dispatchNotificationSubmissionEdited
|
||||||
|
, dispatchNotificationSubmissionUserCreated
|
||||||
|
, dispatchNotificationSubmissionUserDeleted
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Import
|
||||||
|
|
||||||
|
import Handler.Utils
|
||||||
|
import Jobs.Handler.SendNotification.Utils
|
||||||
|
|
||||||
|
import Text.Hamlet
|
||||||
|
|
||||||
|
import qualified Database.Esqueleto as E
|
||||||
|
|
||||||
|
import qualified Data.Text as Text
|
||||||
|
|
||||||
|
|
||||||
|
dispatchNotificationSubmissionEdited :: UserId -> SubmissionId -> UserId -> Handler ()
|
||||||
|
dispatchNotificationSubmissionEdited nInitiator nSubmission jRecipient = userMailT jRecipient $ do
|
||||||
|
(Course{..}, Sheet{..}, Submission{..}, initiator, coSubmittors) <- liftHandler . runDB $ do
|
||||||
|
submission <- getJust nSubmission
|
||||||
|
sheet <- belongsToJust submissionSheet submission
|
||||||
|
course <- belongsToJust sheetCourse sheet
|
||||||
|
|
||||||
|
initiator <- getJust nInitiator
|
||||||
|
|
||||||
|
coSubmittors <- E.select . E.from $ \(submissionUser `E.InnerJoin` user) -> do
|
||||||
|
E.on $ submissionUser E.^. SubmissionUserUser E.==. user E.^. UserId
|
||||||
|
E.where_ $ submissionUser E.^. SubmissionUserSubmission E.==. E.val nSubmission
|
||||||
|
E.&&. user E.^. UserId E.!=. E.val jRecipient
|
||||||
|
return user
|
||||||
|
|
||||||
|
return (course, sheet, submission, initiator, coSubmittors)
|
||||||
|
|
||||||
|
let allCoSubmittors = Text.intercalate ", " $ map (renderAddress . userAddressFrom . entityVal) coSubmittors
|
||||||
|
addMailHeader "Reply-To" allCoSubmittors
|
||||||
|
|
||||||
|
replaceMailHeader "Auto-Submitted" $ Just "auto-generated"
|
||||||
|
setSubjectI $ MsgMailSubjectSubmissionEdited courseShorthand sheetName
|
||||||
|
|
||||||
|
csid <- encrypt nSubmission
|
||||||
|
MsgRenderer mr <- getMailMsgRenderer
|
||||||
|
let termDesc = mr . ShortTermIdentifier $ unTermKey courseTerm
|
||||||
|
tid = courseTerm
|
||||||
|
ssh = courseSchool
|
||||||
|
csh = courseShorthand
|
||||||
|
shn = sheetName
|
||||||
|
|
||||||
|
editNotifications <- mkEditNotifications jRecipient
|
||||||
|
|
||||||
|
addAlternatives $
|
||||||
|
providePreferredAlternative $(ihamletFile "templates/mail/submissionEdited.hamlet")
|
||||||
|
|
||||||
|
dispatchNotificationSubmissionUserCreated :: UserId -> SubmissionId -> UserId -> Handler ()
|
||||||
|
dispatchNotificationSubmissionUserCreated nUser nSubmission jRecipient = userMailT jRecipient $ do
|
||||||
|
(User{..}, Course{..}, Sheet{..}, Submission{..}, coSubmittors) <- liftHandler . runDB $ do
|
||||||
|
submission <- getJust nSubmission
|
||||||
|
sheet <- belongsToJust submissionSheet submission
|
||||||
|
course <- belongsToJust sheetCourse sheet
|
||||||
|
|
||||||
|
coSubmittors <- E.select . E.from $ \(submissionUser `E.InnerJoin` user) -> do
|
||||||
|
E.on $ submissionUser E.^. SubmissionUserUser E.==. user E.^. UserId
|
||||||
|
E.where_ $ submissionUser E.^. SubmissionUserSubmission E.==. E.val nSubmission
|
||||||
|
E.&&. user E.^. UserId E.!=. E.val jRecipient
|
||||||
|
return user
|
||||||
|
|
||||||
|
user <- getJust nUser
|
||||||
|
|
||||||
|
return (user, course, sheet, submission, coSubmittors)
|
||||||
|
|
||||||
|
let isSelf = nUser == jRecipient
|
||||||
|
|
||||||
|
let allCoSubmittors = Text.intercalate ", " $ map (renderAddress . userAddressFrom . entityVal) coSubmittors
|
||||||
|
addMailHeader "Reply-To" allCoSubmittors
|
||||||
|
|
||||||
|
replaceMailHeader "Auto-Submitted" $ Just "auto-generated"
|
||||||
|
setSubjectI $ if
|
||||||
|
| isSelf -> MsgMailSubjectSubmissionUserCreated courseShorthand sheetName
|
||||||
|
| otherwise -> MsgMailSubjectSubmissionUserCreatedOther userDisplayName courseShorthand sheetName
|
||||||
|
|
||||||
|
csid <- encrypt nSubmission
|
||||||
|
MsgRenderer mr <- getMailMsgRenderer
|
||||||
|
let termDesc = mr . ShortTermIdentifier $ unTermKey courseTerm
|
||||||
|
tid = courseTerm
|
||||||
|
ssh = courseSchool
|
||||||
|
csh = courseShorthand
|
||||||
|
shn = sheetName
|
||||||
|
|
||||||
|
editNotifications <- mkEditNotifications jRecipient
|
||||||
|
|
||||||
|
addAlternatives $
|
||||||
|
providePreferredAlternative $(ihamletFile "templates/mail/submissionUserCreated.hamlet")
|
||||||
|
|
||||||
|
|
||||||
|
dispatchNotificationSubmissionUserDeleted :: UserId -> SheetId -> SubmissionId -> UserId -> Handler ()
|
||||||
|
dispatchNotificationSubmissionUserDeleted nUser nSheet nSubmission jRecipient = userMailT jRecipient $ do
|
||||||
|
(User{..}, Course{..}, Sheet{..}, mSubmission, coSubmittors) <- liftHandler . runDB $ do
|
||||||
|
submission <- get nSubmission
|
||||||
|
|
||||||
|
sheet <- maybe (getJust nSheet) (belongsToJust submissionSheet) submission
|
||||||
|
course <- belongsToJust sheetCourse sheet
|
||||||
|
|
||||||
|
coSubmittors <- E.select . E.from $ \(submissionUser `E.InnerJoin` user) -> do
|
||||||
|
E.on $ submissionUser E.^. SubmissionUserUser E.==. user E.^. UserId
|
||||||
|
E.where_ $ submissionUser E.^. SubmissionUserSubmission E.==. E.val nSubmission
|
||||||
|
E.&&. user E.^. UserId E.!=. E.val jRecipient
|
||||||
|
return user
|
||||||
|
|
||||||
|
user <- getJust nUser
|
||||||
|
|
||||||
|
return (user, course, sheet, submission, coSubmittors)
|
||||||
|
|
||||||
|
let isSelf = nUser == jRecipient
|
||||||
|
|
||||||
|
unless (null coSubmittors) $ do
|
||||||
|
let allCoSubmittors = Text.intercalate ", " $ map (renderAddress . userAddressFrom . entityVal) coSubmittors
|
||||||
|
addMailHeader "Reply-To" allCoSubmittors
|
||||||
|
|
||||||
|
replaceMailHeader "Auto-Submitted" $ Just "auto-generated"
|
||||||
|
setSubjectI $ if
|
||||||
|
| isSelf -> MsgMailSubjectSubmissionUserDeleted courseShorthand sheetName
|
||||||
|
| otherwise -> MsgMailSubjectSubmissionUserDeletedOther userDisplayName courseShorthand sheetName
|
||||||
|
|
||||||
|
csid <- guardOn (is _Just mSubmission) <$> encrypt nSubmission
|
||||||
|
MsgRenderer mr <- getMailMsgRenderer
|
||||||
|
let termDesc = mr . ShortTermIdentifier $ unTermKey courseTerm
|
||||||
|
tid = courseTerm
|
||||||
|
ssh = courseSchool
|
||||||
|
csh = courseShorthand
|
||||||
|
shn = sheetName
|
||||||
|
|
||||||
|
editNotifications <- mkEditNotifications jRecipient
|
||||||
|
|
||||||
|
addAlternatives $
|
||||||
|
providePreferredAlternative $(ihamletFile "templates/mail/submissionUserDeleted.hamlet")
|
||||||
@ -2,7 +2,7 @@ module Jobs.Queue
|
|||||||
( writeJobCtl, writeJobCtlBlock
|
( writeJobCtl, writeJobCtlBlock
|
||||||
, writeJobCtl', writeJobCtlBlock'
|
, writeJobCtl', writeJobCtlBlock'
|
||||||
, queueJob, queueJob'
|
, queueJob, queueJob'
|
||||||
, YesodJobDB
|
, YesodJobDB, JobDB
|
||||||
, runDBJobs, queueDBJob, sinkDBJobs
|
, runDBJobs, queueDBJob, sinkDBJobs
|
||||||
, runDBJobs'
|
, runDBJobs'
|
||||||
, queueDBJobCron
|
, queueDBJobCron
|
||||||
@ -113,6 +113,9 @@ queueJob' job = do
|
|||||||
-- | Slightly modified Version of `YesodDB` for `runDBJobs`
|
-- | Slightly modified Version of `YesodDB` for `runDBJobs`
|
||||||
type YesodJobDB site = ReaderT (YesodPersistBackend site) (WriterT (Set QueuedJobId) (HandlerFor site))
|
type YesodJobDB site = ReaderT (YesodPersistBackend site) (WriterT (Set QueuedJobId) (HandlerFor site))
|
||||||
|
|
||||||
|
-- | Slightly modified Version of `DB` for `runDBJobs`
|
||||||
|
type JobDB = YesodJobDB UniWorX
|
||||||
|
|
||||||
queueDBJob, queueDBJobCron :: Job -> YesodJobDB UniWorX ()
|
queueDBJob, queueDBJobCron :: Job -> YesodJobDB UniWorX ()
|
||||||
-- | Queue a job as part of a database transaction and execute it after the transaction succeeds
|
-- | Queue a job as part of a database transaction and execute it after the transaction succeeds
|
||||||
queueDBJob job = mapReaderT lift (queueJobUnsafe False job) >>= tell . Set.singleton
|
queueDBJob job = mapReaderT lift (queueJobUnsafe False job) >>= tell . Set.singleton
|
||||||
|
|||||||
@ -91,6 +91,9 @@ data Notification = NotificationSubmissionRated { nSubmission :: SubmissionId }
|
|||||||
| NotificationExamOfficeExamResultsChanged { nExamResults :: Set ExamResultId }
|
| NotificationExamOfficeExamResultsChanged { nExamResults :: Set ExamResultId }
|
||||||
| NotificationAllocationResults { nAllocation :: AllocationId }
|
| NotificationAllocationResults { nAllocation :: AllocationId }
|
||||||
| NotificationCourseRegistered { nUser :: UserId, nCourse :: CourseId }
|
| NotificationCourseRegistered { nUser :: UserId, nCourse :: CourseId }
|
||||||
|
| NotificationSubmissionEdited { nInitiator :: UserId, nSubmission :: SubmissionId }
|
||||||
|
| NotificationSubmissionUserCreated { nUser :: UserId, nSubmission :: SubmissionId }
|
||||||
|
| NotificationSubmissionUserDeleted { nUser :: UserId, nSheet :: SheetId, nSubmission :: SubmissionId }
|
||||||
deriving (Eq, Ord, Show, Read, Generic, Typeable)
|
deriving (Eq, Ord, Show, Read, Generic, Typeable)
|
||||||
|
|
||||||
instance Hashable Job
|
instance Hashable Job
|
||||||
|
|||||||
@ -24,6 +24,9 @@ import qualified Data.HashMap.Strict as HashMap
|
|||||||
data NotificationTrigger
|
data NotificationTrigger
|
||||||
= NTSubmissionRatedGraded
|
= NTSubmissionRatedGraded
|
||||||
| NTSubmissionRated
|
| NTSubmissionRated
|
||||||
|
| NTSubmissionEdited
|
||||||
|
| NTSubmissionUserCreated
|
||||||
|
| NTSubmissionUserDeleted
|
||||||
| NTSheetActive
|
| NTSheetActive
|
||||||
| NTSheetSoonInactive
|
| NTSheetSoonInactive
|
||||||
| NTSheetInactive
|
| NTSheetInactive
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
$newline never
|
$newline never
|
||||||
<dl .deflist>
|
<dl .deflist>
|
||||||
|
<dt .deflist__dt>
|
||||||
|
^{formatGregorianW 2019 12 05}
|
||||||
|
<dd .deflist__dd>
|
||||||
|
<ul>
|
||||||
|
<li>Benachrichtigungen bei Änderungen an Übungsblatt-Abgaben
|
||||||
|
|
||||||
<dt .deflist__dt>
|
<dt .deflist__dt>
|
||||||
^{formatGregorianW 2019 11 28}
|
^{formatGregorianW 2019 11 28}
|
||||||
<dd .deflist__dd>
|
<dd .deflist__dd>
|
||||||
|
|||||||
@ -1,5 +1,11 @@
|
|||||||
$newline never
|
$newline never
|
||||||
<dl .deflist>
|
<dl .deflist>
|
||||||
|
<dt .deflist__dt>
|
||||||
|
^{formatGregorianW 2019 12 05}
|
||||||
|
<dd .deflist__dd>
|
||||||
|
<ul>
|
||||||
|
<li>Notifications when exercise sheet submissions are changed
|
||||||
|
|
||||||
<dt .deflist__dt>
|
<dt .deflist__dt>
|
||||||
^{formatGregorianW 2019 11 28}
|
^{formatGregorianW 2019 11 28}
|
||||||
<dd .deflist__dd>
|
<dd .deflist__dd>
|
||||||
|
|||||||
20
templates/mail/submissionEdited.hamlet
Normal file
20
templates/mail/submissionEdited.hamlet
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
$newline never
|
||||||
|
\<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<style>
|
||||||
|
h1 {
|
||||||
|
font-size: 1.25em;
|
||||||
|
font-variant: small-caps;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
<body>
|
||||||
|
<h1>
|
||||||
|
_{MsgMailSubmissionEditedIntro courseName sheetName termDesc (userDisplayName initiator)}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href=@{CSubmissionR tid ssh csh shn csid SubShowR}>
|
||||||
|
#{toPathPiece csid}
|
||||||
|
|
||||||
|
^{editNotifications}
|
||||||
23
templates/mail/submissionUserCreated.hamlet
Normal file
23
templates/mail/submissionUserCreated.hamlet
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
$newline never
|
||||||
|
\<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<style>
|
||||||
|
h1 {
|
||||||
|
font-size: 1.25em;
|
||||||
|
font-variant: small-caps;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
<body>
|
||||||
|
<h1>
|
||||||
|
$if isSelf
|
||||||
|
_{MsgMailSubmissionUserCreatedIntro courseName sheetName termDesc}
|
||||||
|
$else
|
||||||
|
_{MsgMailSubmissionUserCreatedOtherIntro userDisplayName courseName sheetName termDesc}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<a href=@{CSubmissionR tid ssh csh shn csid SubShowR}>
|
||||||
|
#{toPathPiece csid}
|
||||||
|
|
||||||
|
^{editNotifications}
|
||||||
24
templates/mail/submissionUserDeleted.hamlet
Normal file
24
templates/mail/submissionUserDeleted.hamlet
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
$newline never
|
||||||
|
\<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<style>
|
||||||
|
h1 {
|
||||||
|
font-size: 1.25em;
|
||||||
|
font-variant: small-caps;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
<body>
|
||||||
|
<h1>
|
||||||
|
$if isSelf
|
||||||
|
_{MsgMailSubmissionUserDeletedIntro courseName sheetName termDesc}
|
||||||
|
$else
|
||||||
|
_{MsgMailSubmissionUserDeletedOtherIntro userDisplayName courseName sheetName termDesc}
|
||||||
|
|
||||||
|
$maybe csid' <- csid
|
||||||
|
<p>
|
||||||
|
<a href=@{CSubmissionR tid ssh csh shn csid' SubShowR}>
|
||||||
|
#{toPathPiece csid'}
|
||||||
|
|
||||||
|
^{editNotifications}
|
||||||
Loading…
Reference in New Issue
Block a user