Merge branch '184-replace-displayable-by-rendermessage' into 'master'

Resolve "Replace DisplayAble by RenderMessage"

Closes #184

See merge request !257
This commit is contained in:
Sarah Vaupel 2019-07-03 11:37:49 +02:00
commit aae9fbc3a9
33 changed files with 316 additions and 296 deletions

1
.gitignore vendored
View File

@ -34,3 +34,4 @@ src/Handler/Course.SnapCustom.hs
.directory .directory
tags tags
test.log test.log
*.dump-splices

View File

@ -41,18 +41,18 @@ GenericAvg: Avg
GenericMax: Max GenericMax: Max
GenericAll: Insgesamt GenericAll: Insgesamt
SummerTerm year@Integer: Sommersemester #{display year} SummerTerm year@Integer: Sommersemester #{year}
WinterTerm year@Integer: Wintersemester #{display year}/#{display $ succ year} WinterTerm year@Integer: Wintersemester #{year}/#{succ year}
SummerTermShort year@Integer: SoSe #{display year} SummerTermShort year@Integer: SoSe #{year}
WinterTermShort year@Integer: WiSe #{display year}/#{display $ mod (succ year) 100} WinterTermShort year@Integer: WiSe #{year}/#{mod (succ year) 100}
PSLimitNonPositive: “pagesize” muss größer als null sein PSLimitNonPositive: “pagesize” muss größer als null sein
Page num@Int64: #{display num} Page num@Int64: #{num}
TermsHeading: Semesterübersicht TermsHeading: Semesterübersicht
TermCurrent: Aktuelles Semester TermCurrent: Aktuelles Semester
TermEditHeading: Semester editieren/anlegen TermEditHeading: Semester editieren/anlegen
TermEditTid tid@TermId: Semester #{display tid} editieren TermEditTid tid@TermId: Semester #{tid} editieren
TermEdited tid@TermId: Semester #{display tid} erfolgreich editiert. TermEdited tid@TermId: Semester #{tid} erfolgreich editiert.
TermNewTitle: Semester editieren/anlegen. TermNewTitle: Semester editieren/anlegen.
InvalidInput: Eingaben bitte korrigieren. InvalidInput: Eingaben bitte korrigieren.
Term: Semester Term: Semester
@ -91,23 +91,23 @@ CourseTutorial: Tutorium
CourseStudyFeatureTooltip: Korrekte Angabe kann Notenweiterleitungen beschleunigen CourseStudyFeatureTooltip: Korrekte Angabe kann Notenweiterleitungen beschleunigen
CourseSecretWrong: Falsches Kennwort CourseSecretWrong: Falsches Kennwort
CourseSecret: Zugangspasswort CourseSecret: Zugangspasswort
CourseEditOk tid@TermId ssh@SchoolId csh@CourseShorthand: Kurs #{display tid}-#{display ssh}-#{csh} wurde erfolgreich geändert. CourseEditOk tid@TermId ssh@SchoolId csh@CourseShorthand: Kurs #{tid}-#{ssh}-#{csh} wurde erfolgreich geändert.
CourseNewDupShort tid@TermId ssh@SchoolId csh@CourseShorthand: Kurs #{display tid}-#{display ssh}-#{csh} konnte nicht erstellt werden: Es gibt bereits einen anderen Kurs mit dem Kürzel #{csh} in diesem Semester. CourseNewDupShort tid@TermId ssh@SchoolId csh@CourseShorthand: Kurs #{tid}-#{ssh}-#{csh} konnte nicht erstellt werden: Es gibt bereits einen anderen Kurs mit dem Kürzel #{csh} in diesem Semester.
CourseEditDupShort tid@TermId ssh@SchoolId csh@CourseShorthand: Kurs #{display tid}-#{display ssh}-#{csh} konnte nicht geändert werden: Es gibt bereits einen anderen Kurs mit dem Kürzel #{csh} in diesem Semester. CourseEditDupShort tid@TermId ssh@SchoolId csh@CourseShorthand: Kurs #{tid}-#{ssh}-#{csh} konnte nicht geändert werden: Es gibt bereits einen anderen Kurs mit dem Kürzel #{csh} in diesem Semester.
FFSheetName: Name FFSheetName: Name
TermCourseListHeading tid@TermId: Kursübersicht #{display tid} TermCourseListHeading tid@TermId: Kursübersicht #{tid}
TermSchoolCourseListHeading tid@TermId school@SchoolName: Kursübersicht #{display tid} für #{school} TermSchoolCourseListHeading tid@TermId school@SchoolName: Kursübersicht #{tid} für #{school}
CourseListTitle: Alle Kurse CourseListTitle: Alle Kurse
TermCourseListTitle tid@TermId: Kurse #{display tid} TermCourseListTitle tid@TermId: Kurse #{tid}
TermSchoolCourseListTitle tid@TermId school@SchoolName: Kurse #{display tid} für #{school} TermSchoolCourseListTitle tid@TermId school@SchoolName: Kurse #{tid} für #{school}
CourseNewHeading: Neuen Kurs anlegen CourseNewHeading: Neuen Kurs anlegen
CourseEditHeading tid@TermId ssh@SchoolId csh@CourseShorthand: Kurs #{display tid}-#{display ssh}-#{csh} editieren CourseEditHeading tid@TermId ssh@SchoolId csh@CourseShorthand: Kurs #{tid}-#{ssh}-#{csh} editieren
CourseEditTitle: Kurs editieren/anlegen CourseEditTitle: Kurs editieren/anlegen
CourseMembers: Teilnehmer CourseMembers: Teilnehmer
CourseMemberOf: Teilnehmer CourseMemberOf: Teilnehmer
CourseMembersCount n@Int: #{display n} CourseMembersCount n@Int: #{n}
CourseMembersCountLimited n@Int max@Int: #{display n}/#{display max} CourseMembersCountLimited n@Int max@Int: #{n}/#{max}
CourseMembersCountOf n@Int mbNum@IntMaybe: #{display n} Anmeldungen #{maybeDisplay " von " mbNum " möglichen"} CourseMembersCountOf n@Int mbNum@IntMaybe: #{n} Anmeldungen #{maybeToMessage " von " mbNum " möglichen"}
CourseName: Name CourseName: Name
CourseDescription: Beschreibung CourseDescription: Beschreibung
CourseDescriptionTip: Beliebiges HTML-Markup ist gestattet CourseDescriptionTip: Beliebiges HTML-Markup ist gestattet
@ -147,23 +147,23 @@ CourseDeregistrationEndMustBeAfterStart: Ende des Abmeldezeitraums muss nach dem
CourseUserMustBeLecturer: Aktueller Benutzer muss als Kursverwalter eingetragen sein CourseUserMustBeLecturer: Aktueller Benutzer muss als Kursverwalter eingetragen sein
CourseLecturerRightsIdentical: Alle Sorten von Kursverwalter haben identische Rechte. CourseLecturerRightsIdentical: Alle Sorten von Kursverwalter haben identische Rechte.
NoSuchTerm tid@TermId: Semester #{display tid} gibt es nicht. NoSuchTerm tid@TermId: Semester #{tid} gibt es nicht.
NoSuchSchool ssh@SchoolId: Institut #{display ssh} gibt es nicht. NoSuchSchool ssh@SchoolId: Institut #{ssh} gibt es nicht.
NoSuchCourseShorthand csh@CourseShorthand: Kein Kurs mit Kürzel #{csh} bekannt. NoSuchCourseShorthand csh@CourseShorthand: Kein Kurs mit Kürzel #{csh} bekannt.
NoSuchCourse: Keinen passenden Kurs gefunden. NoSuchCourse: Keinen passenden Kurs gefunden.
Sheet: Blatt Sheet: Blatt
SheetList tid@TermId ssh@SchoolId csh@CourseShorthand: #{display tid}-#{display ssh}-#{csh} Übersicht Übungsblätter SheetList tid@TermId ssh@SchoolId csh@CourseShorthand: #{tid}-#{ssh}-#{csh} Übersicht Übungsblätter
SheetNewHeading tid@TermId ssh@SchoolId csh@CourseShorthand: #{display tid}-#{display ssh}-#{csh} Neues Übungsblatt anlegen SheetNewHeading tid@TermId ssh@SchoolId csh@CourseShorthand: #{tid}-#{ssh}-#{csh} Neues Übungsblatt anlegen
SheetNewOk tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{sheetName} wurde als neues Übungsblatt im Kurs #{display tid}-#{display ssh}-#{csh} erfolgreich erstellt. SheetNewOk tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{sheetName} wurde als neues Übungsblatt im Kurs #{tid}-#{ssh}-#{csh} erfolgreich erstellt.
SheetTitle tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{display tid}-#{display ssh}-#{csh} #{sheetName} SheetTitle tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{tid}-#{ssh}-#{csh} #{sheetName}
SheetTitleNew tid@TermId ssh@SchoolId csh@CourseShorthand : #{display tid}-#{display ssh}-#{csh}: Neues Übungsblatt SheetTitleNew tid@TermId ssh@SchoolId csh@CourseShorthand : #{tid}-#{ssh}-#{csh}: Neues Übungsblatt
SheetEditHead tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{display tid}-#{display ssh}-#{csh} #{sheetName} editieren SheetEditHead tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{tid}-#{ssh}-#{csh} #{sheetName} editieren
SheetEditOk tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: Übungsblatt #{sheetName} wurde gespeichert in Kurs #{display tid}-#{display ssh}-#{csh} SheetEditOk tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: Übungsblatt #{sheetName} wurde gespeichert in Kurs #{tid}-#{ssh}-#{csh}
SheetNameDup tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: Es gibt bereits ein Übungsblatt #{sheetName} in diesem Kurs #{display tid}-#{display ssh}-#{csh} SheetNameDup tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: Es gibt bereits ein Übungsblatt #{sheetName} in diesem Kurs #{tid}-#{ssh}-#{csh}
SheetDelHead tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{sheetName} wirklich aus Kurs #{display tid}-#{display ssh}-#{csh} herauslöschen? Alle assoziierten Abgaben und Korrekturen gehen ebenfalls verloren! SheetDelHead tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{sheetName} wirklich aus Kurs #{tid}-#{ssh}-#{csh} herauslöschen? Alle assoziierten Abgaben und Korrekturen gehen ebenfalls verloren!
SheetDelOk tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{display tid}-#{display ssh}-#{csh}: #{sheetName} gelöscht. SheetDelOk tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{tid}-#{ssh}-#{csh}: #{sheetName} gelöscht.
SheetDelHasSubmissions objs@Int: Inkl. #{tshow objs} #{pluralDE objs "Abgabe" "Abgaben"}! SheetDelHasSubmissions objs@Int: Inkl. #{objs} #{pluralDE objs "Abgabe" "Abgaben"}!
SheetDeleteQuestion: Wollen Sie das unten aufgeführte Übungsblatt und alle zugehörigen Abgaben wirklich löschen? SheetDeleteQuestion: Wollen Sie das unten aufgeführte Übungsblatt und alle zugehörigen Abgaben wirklich löschen?
SheetDeleted: Übungsblatt gelöscht SheetDeleted: Übungsblatt gelöscht
@ -209,12 +209,12 @@ Deadline: Abgabe
Done: Eingereicht Done: Eingereicht
Submission: Abgabenummer Submission: Abgabenummer
SubmissionsCourse tid@TermId ssh@SchoolId csh@CourseShorthand: Alle Abgaben Kurs #{display tid}-#{display ssh}-#{csh} SubmissionsCourse tid@TermId ssh@SchoolId csh@CourseShorthand: Alle Abgaben Kurs #{tid}-#{ssh}-#{csh}
SubmissionsSheet sheetName@SheetName: Abgaben für #{sheetName} SubmissionsSheet sheetName@SheetName: Abgaben für #{sheetName}
SubmissionWrongSheet: Abgabenummer gehört nicht zum angegebenen Übungsblatt. SubmissionWrongSheet: Abgabenummer gehört nicht zum angegebenen Übungsblatt.
SubmissionAlreadyExists: Sie haben bereits eine Abgabe zu diesem Übungsblatt. SubmissionAlreadyExists: Sie haben bereits eine Abgabe zu diesem Übungsblatt.
SubmissionEditHead tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{display tid}-#{display ssh}-#{csh} #{sheetName}: Abgabe editieren/anlegen SubmissionEditHead tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{tid}-#{ssh}-#{csh} #{sheetName}: Abgabe editieren/anlegen
CorrectionHead tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName cid@CryptoFileNameSubmission: #{display tid}-#{display ssh}-#{csh} #{sheetName}: Korrektur CorrectionHead tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName cid@CryptoFileNameSubmission: #{tid}-#{ssh}-#{csh} #{sheetName}: Korrektur
SubmissionMembers: Abgebende SubmissionMembers: Abgebende
SubmissionMember: Abgebende(r) SubmissionMember: Abgebende(r)
SubmissionArchive: Zip-Archiv der Abgabedatei(en) SubmissionArchive: Zip-Archiv der Abgabedatei(en)
@ -253,10 +253,10 @@ MaterialNewHeading: Neues Material veröffentlichen
MaterialNewTitle: Neues Material MaterialNewTitle: Neues Material
MaterialEditHeading materialName@MaterialName: Material "#{materialName}" editieren MaterialEditHeading materialName@MaterialName: Material "#{materialName}" editieren
MaterialEditTitle materialName@MaterialName: Material "#{materialName}" editieren MaterialEditTitle materialName@MaterialName: Material "#{materialName}" editieren
MaterialSaveOk tid@TermId ssh@SchoolId csh@CourseShorthand materialName@MaterialName: Material "#{materialName}" erfolgreich gespeichert in Kurs #{display tid}-#{display ssh}-#{csh} MaterialSaveOk tid@TermId ssh@SchoolId csh@CourseShorthand materialName@MaterialName: Material "#{materialName}" erfolgreich gespeichert in Kurs #{tid}-#{ssh}-#{csh}
MaterialNameDup tid@TermId ssh@SchoolId csh@CourseShorthand materialName@MaterialName: Es gibt bereits Material mit Namen "#{materialName}" in diesem Kurs #{display tid}-#{display ssh}-#{csh} MaterialNameDup tid@TermId ssh@SchoolId csh@CourseShorthand materialName@MaterialName: Es gibt bereits Material mit Namen "#{materialName}" in diesem Kurs #{tid}-#{ssh}-#{csh}
MaterialDeleteCaption: Wollen Sie das unten aufgeführte Material wirklich löschen? MaterialDeleteCaption: Wollen Sie das unten aufgeführte Material wirklich löschen?
MaterialDelHasFiles count@Int64: inklusive #{tshow count} #{pluralDE count "Datei" "Dateien"} MaterialDelHasFiles count@Int64: inklusive #{count} #{pluralDE count "Datei" "Dateien"}
MaterialIsVisible: Achtung, dieses Material wurde bereits veröffentlicht. MaterialIsVisible: Achtung, dieses Material wurde bereits veröffentlicht.
MaterialDeleted materialName@MaterialName: Material "#{materialName}" gelöscht MaterialDeleted materialName@MaterialName: Material "#{materialName}" gelöscht
@ -310,12 +310,12 @@ UnauthorizedTutorialRegisterGroup: Sie sind bereits in einem Tutorium mit dersel
EMail: E-Mail EMail: E-Mail
EMailUnknown email@UserEmail: E-Mail #{email} gehört zu keinem bekannten Benutzer. EMailUnknown email@UserEmail: E-Mail #{email} gehört zu keinem bekannten Benutzer.
NotAParticipant email@UserEmail tid@TermId csh@CourseShorthand: #{email} ist nicht im Kurs #{display tid}-#{csh} angemeldet. NotAParticipant email@UserEmail tid@TermId csh@CourseShorthand: #{email} ist nicht im Kurs #{tid}-#{csh} angemeldet.
TooManyParticipants: Es wurden zu viele Mitabgebende angegeben TooManyParticipants: Es wurden zu viele Mitabgebende angegeben
AddCorrector: Zusätzlicher Korrektor AddCorrector: Zusätzlicher Korrektor
CorrectorExists: Nutzer ist bereits als Korrektor eingetragen CorrectorExists: Nutzer ist bereits als Korrektor eingetragen
SheetCorrectorsTitle tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: Korrektoren für #{display tid}-#{display ssh}-#{csh} #{sheetName} SheetCorrectorsTitle tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: Korrektoren für #{tid}-#{ssh}-#{csh} #{sheetName}
CountTutProp: Tutorien zählen gegen Proportion CountTutProp: Tutorien zählen gegen Proportion
CountTutPropTip: Wenn Abgaben nach Tutorium zugeteilt werden, zählen diese Zuteilungen in Bezug auf den jeweiligen Anteil? CountTutPropTip: Wenn Abgaben nach Tutorium zugeteilt werden, zählen diese Zuteilungen in Bezug auf den jeweiligen Anteil?
AutoAssignCorrs: Korrekturen nach Ablauf des Abgabezeitraums automatisch zuteilen AutoAssignCorrs: Korrekturen nach Ablauf des Abgabezeitraums automatisch zuteilen
@ -325,11 +325,11 @@ CorState: Status
CorByTut: Zuteilung nach Tutorium CorByTut: Zuteilung nach Tutorium
CorProportion: Anteil CorProportion: Anteil
CorDeficitProportion: Defizit Anteile CorDeficitProportion: Defizit Anteile
CorByProportionOnly proportion@Rational: #{display proportion} Anteile CorByProportionOnly proportion@Rational: #{rationalToFixed3 proportion} Anteile
CorByProportionIncludingTutorial proportion@Rational: #{display proportion} Anteile - Tutorium CorByProportionIncludingTutorial proportion@Rational: #{rationalToFixed3 proportion} Anteile - Tutorium
CorByProportionExcludingTutorial proportion@Rational: #{display proportion} Anteile + Tutorium CorByProportionExcludingTutorial proportion@Rational: #{rationalToFixed3 proportion} Anteile + Tutorium
RowCount count@Int64: #{display count} #{pluralDE count "passender Eintrag" "passende Einträge"} insgesamt RowCount count@Int64: #{count} #{pluralDE count "passender Eintrag" "passende Einträge"} insgesamt
DeleteRow: Entfernen DeleteRow: Entfernen
ProportionNegative: Anteile dürfen nicht negativ sein ProportionNegative: Anteile dürfen nicht negativ sein
CorrectorUpdated: Korrektor erfolgreich aktualisiert CorrectorUpdated: Korrektor erfolgreich aktualisiert
@ -357,7 +357,7 @@ TokensResetSuccess: Authorisierungs-Tokens invalidiert
HomeOpenCourses: Kurse mit offener Registrierung HomeOpenCourses: Kurse mit offener Registrierung
HomeUpcomingSheets: Anstehende Übungsblätter HomeUpcomingSheets: Anstehende Übungsblätter
NumCourses num@Int64: #{display num} Kurse NumCourses num@Int64: #{num} Kurse
CloseAlert: Schliessen CloseAlert: Schliessen
Name: Name Name: Name
@ -394,23 +394,23 @@ NatField name@Text: #{name} muss eine natürliche Zahl sein!
JSONFieldDecodeFailure aesonFailure@String: Konnte JSON nicht parsen: #{aesonFailure} JSONFieldDecodeFailure aesonFailure@String: Konnte JSON nicht parsen: #{aesonFailure}
SecretJSONFieldDecryptFailure: Konnte versteckte vertrauliche Daten nicht entschlüsseln SecretJSONFieldDecryptFailure: Konnte versteckte vertrauliche Daten nicht entschlüsseln
SubmissionsAlreadyAssigned num@Int64: #{display num} Abgaben waren bereits einem Korrektor zugeteilt und wurden nicht verändert: SubmissionsAlreadyAssigned num@Int64: #{num} Abgaben waren bereits einem Korrektor zugeteilt und wurden nicht verändert:
SubmissionsAssignUnauthorized num@Int64: #{display num} Abgaben können momentan nicht einem Korrektor zugeteilt werden (z.B. weil die Abgabe noch offen ist): SubmissionsAssignUnauthorized num@Int64: #{num} Abgaben können momentan nicht einem Korrektor zugeteilt werden (z.B. weil die Abgabe noch offen ist):
UpdatedAssignedCorrectorSingle num@Int64: #{display num} Abgaben wurden dem neuen Korrektor zugeteilt. UpdatedAssignedCorrectorSingle num@Int64: #{num} Abgaben wurden dem neuen Korrektor zugeteilt.
NoCorrector: Kein Korrektor NoCorrector: Kein Korrektor
RemovedCorrections num@Int64: Korrektur-Daten wurden von #{display num} Abgaben entfernt. RemovedCorrections num@Int64: Korrektur-Daten wurden von #{num} Abgaben entfernt.
UpdatedAssignedCorrectorsAuto num@Int64: #{display num} Abgaben wurden unter den Korrektoren aufgeteilt. UpdatedAssignedCorrectorsAuto num@Int64: #{num} Abgaben wurden unter den Korrektoren aufgeteilt.
UpdatedSheetCorrectorsAutoAssigned n@Int: #{display n} #{pluralDE n "Abgabe wurde einem Korrektor" "Abgaben wurden Korrektoren"} zugteilt. UpdatedSheetCorrectorsAutoAssigned n@Int: #{n} #{pluralDE n "Abgabe wurde einem Korrektor" "Abgaben wurden Korrektoren"} zugteilt.
UpdatedSheetCorrectorsAutoFailed n@Int: #{display n} #{pluralDE n "Abgabe konnte" "Abgaben konnten"} nicht automatisch zugewiesen werden. UpdatedSheetCorrectorsAutoFailed n@Int: #{n} #{pluralDE n "Abgabe konnte" "Abgaben konnten"} nicht automatisch zugewiesen werden.
CouldNotAssignCorrectorsAuto num@Int64: #{display num} Abgaben konnten nicht automatisch zugewiesen werden: CouldNotAssignCorrectorsAuto num@Int64: #{num} Abgaben konnten nicht automatisch zugewiesen werden:
SelfCorrectors num@Int64: #{display num} Abgaben wurden Abgebenden als eigenem Korrektor zugeteilt! SelfCorrectors num@Int64: #{num} Abgaben wurden Abgebenden als eigenem Korrektor zugeteilt!
CorrectionSheets: Übersicht Korrekturen nach Blättern CorrectionSheets: Übersicht Korrekturen nach Blättern
CorrectionCorrectors: Übersicht Korrekturen nach Korrektoren CorrectionCorrectors: Übersicht Korrekturen nach Korrektoren
AssignSubmissionExceptionNoCorrectors: Es sind keine Korrektoren eingestellt AssignSubmissionExceptionNoCorrectors: Es sind keine Korrektoren eingestellt
AssignSubmissionExceptionNoCorrectorsByProportion: Es sind keine Korrektoren mit Anteil ungleich Null eingestellt AssignSubmissionExceptionNoCorrectorsByProportion: Es sind keine Korrektoren mit Anteil ungleich Null eingestellt
AssignSubmissionExceptionSubmissionsNotFound n@Int: #{tshow n} Abgaben konnten nicht gefunden werden AssignSubmissionExceptionSubmissionsNotFound n@Int: #{n} Abgaben konnten nicht gefunden werden
NrSubmittorsTotal: Abgebende NrSubmittorsTotal: Abgebende
NrSubmissionsTotal: Abgaben NrSubmissionsTotal: Abgaben
NrSubmissionsTotalShort: Abg. NrSubmissionsTotalShort: Abg.
@ -424,7 +424,7 @@ NrSubmissionsNotCorrectedShort: Unkg.
CorrectionTime: Korrekturdauer 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. 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.
CorrectionsUploaded num@Int64: #{display num} Korrekturen wurden gespeichert: CorrectionsUploaded num@Int64: #{num} Korrekturen wurden gespeichert:
NoCorrectionsUploaded: In der hochgeladenen Datei wurden keine Korrekturen gefunden. NoCorrectionsUploaded: In der hochgeladenen Datei wurden keine Korrekturen gefunden.
RatingBy: Korrigiert von RatingBy: Korrigiert von
@ -433,8 +433,8 @@ AssignedTime: Zuteilung
AchievedBonusPoints: Erreichte Bonuspunkte AchievedBonusPoints: Erreichte Bonuspunkte
AchievedNormalPoints: Erreichte Punkte AchievedNormalPoints: Erreichte Punkte
AchievedPassPoints: Erreichte Punkte AchievedPassPoints: Erreichte Punkte
AchievedOf achieved@Points possible@Points: #{display achieved} von #{display possible} AchievedOf achieved@Points possible@Points: #{achieved} von #{possible}
PassAchievedOf points@Points passingPoints@Points maxPoints@Points: #{display points} von #{display maxPoints} (Bestanden ab #{display passingPoints}) PassAchievedOf points@Points passingPoints@Points maxPoints@Points: #{points} von #{maxPoints} (Bestanden ab #{passingPoints})
PassedResult: Ergebnis PassedResult: Ergebnis
Passed: Bestanden Passed: Bestanden
NotPassed: Nicht bestanden NotPassed: Nicht bestanden
@ -447,7 +447,7 @@ RatingDone: Bewertung sichtbar
RatingPercent: Erreicht RatingPercent: Erreicht
RatingFiles: Korrigierte Dateien RatingFiles: Korrigierte Dateien
PointsNotPositive: Punktzahl darf nicht negativ sein PointsNotPositive: Punktzahl darf nicht negativ sein
PointsTooHigh maxPoints@Points: Punktzahl darf nicht höher als #{tshow maxPoints} sein PointsTooHigh maxPoints@Points: Punktzahl darf nicht höher als #{maxPoints} sein
RatingPointsDone: Abgabe zählt als korrigiert, gdw. Punktezahl gesetzt ist RatingPointsDone: Abgabe zählt als korrigiert, gdw. Punktezahl gesetzt ist
ColumnRatingPoints: Punktzahl ColumnRatingPoints: Punktzahl
Pseudonyms: Pseudonyme Pseudonyms: Pseudonyme
@ -527,7 +527,7 @@ LastEdit: Letzte Änderung
LastEditByUser: Ihre letzte Bearbeitung LastEditByUser: Ihre letzte Bearbeitung
NoEditByUser: Nicht von Ihnen bearbeitet NoEditByUser: Nicht von Ihnen bearbeitet
SubmissionFilesIgnored n@Int: Es #{pluralDE n "wurde" "wurden"} #{tshow n} #{pluralDE n "Datei" "Dateien"} in der hochgeladenen Abgabe ignoriert SubmissionFilesIgnored n@Int: Es #{pluralDE n "wurde" "wurden"} #{n} #{pluralDE n "Datei" "Dateien"} in der hochgeladenen Abgabe ignoriert
SubmissionDoesNotExist smid@CryptoFileNameSubmission: Es existiert keine Abgabe mit Nummer #{toPathPiece smid}. SubmissionDoesNotExist smid@CryptoFileNameSubmission: Es existiert keine Abgabe mit Nummer #{toPathPiece smid}.
LDAPLoginTitle: Campus-Login LDAPLoginTitle: Campus-Login
@ -542,8 +542,8 @@ CorrectorExcused: Entschuldigt
CorrectorStateTip: Abwesende Korrektoren bekommen bei späteren Übungsblättern mehr Korrekturen zum Ausgleich zugewiesen. Entschuldigte Korrektoren müssen nicht nacharbeiten. CorrectorStateTip: Abwesende Korrektoren bekommen bei späteren Übungsblättern mehr Korrekturen zum Ausgleich zugewiesen. Entschuldigte Korrektoren müssen nicht nacharbeiten.
DayIsAHoliday tid@TermId name@Text date@Text: "#{name}" (#{date}) ist ein Feiertag DayIsAHoliday tid@TermId name@Text date@Text: "#{name}" (#{date}) ist ein Feiertag
DayIsOutOfLecture tid@TermId name@Text date@Text: "#{name}" (#{date}) ist außerhalb der Vorlesungszeit des #{display tid} DayIsOutOfLecture tid@TermId name@Text date@Text: "#{name}" (#{date}) ist außerhalb der Vorlesungszeit des #{tid}
DayIsOutOfTerm tid@TermId name@Text date@Text: "#{name}" (#{date}) liegt nicht im Semester #{display tid} DayIsOutOfTerm tid@TermId name@Text date@Text: "#{name}" (#{date}) liegt nicht im Semester #{tid}
UploadModeNone: Kein Upload UploadModeNone: Kein Upload
UploadModeAny: Upload, beliebige Datei(en) UploadModeAny: Upload, beliebige Datei(en)
@ -623,15 +623,15 @@ MailSubjectSheetActive csh@CourseShorthand sheetName@SheetName: #{sheetName} in
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.
MailSubjectSubmissionsUnassigned csh@CourseShorthand sheetName@SheetName: Abgaben zu #{sheetName} in #{csh} konnten nicht verteilt werden MailSubjectSubmissionsUnassigned csh@CourseShorthand sheetName@SheetName: Abgaben zu #{sheetName} in #{csh} konnten nicht verteilt werden
MailSubmissionsUnassignedIntro n@Int courseName@Text termDesc@Text sheetName@SheetName: #{tshow n} Abgaben zu #{sheetName} im Kurs #{courseName} (#{termDesc}) konnten nicht automatisiert verteilt werden. MailSubmissionsUnassignedIntro n@Int courseName@Text termDesc@Text sheetName@SheetName: #{n} Abgaben zu #{sheetName} im Kurs #{courseName} (#{termDesc}) konnten nicht automatisiert verteilt werden.
MailSubjectSheetSoonInactive csh@CourseShorthand sheetName@SheetName: #{sheetName} in #{csh} kann nur noch kurze Zeit abgegeben werden MailSubjectSheetSoonInactive csh@CourseShorthand sheetName@SheetName: #{sheetName} in #{csh} kann nur noch kurze Zeit abgegeben werden
MailSheetSoonInactiveIntro courseName@Text termDesc@Text sheetName@SheetName: Abgabefirst für #{sheetName} im Kurs #{courseName} (#{termDesc}) endet in Kürze. MailSheetSoonInactiveIntro courseName@Text termDesc@Text sheetName@SheetName: Abgabefirst für #{sheetName} im Kurs #{courseName} (#{termDesc}) endet in Kürze.
MailSubjectSheetInactive csh@CourseShorthand sheetName@SheetName: Abgabezeitraum für #{sheetName} in #{csh} abgelaufen MailSubjectSheetInactive csh@CourseShorthand sheetName@SheetName: Abgabezeitraum für #{sheetName} in #{csh} abgelaufen
MailSheetInactiveIntro courseName@Text termDesc@Text sheetName@SheetName n@Int num@Int64: Die Abgabefirst für #{sheetName} im Kurs #{courseName} (#{termDesc}) beendet. Es gab #{noneOneMoreDE n "Keine Abgaben" "Nur eine Abgabe von " (display n <> " Abgaben von ")}#{noneOneMoreDE num "" "einem Teilnehmer" (display num <> " Teilnehmern")}. MailSheetInactiveIntro courseName@Text termDesc@Text sheetName@SheetName n@Int num@Int64: Die Abgabefirst für #{sheetName} im Kurs #{courseName} (#{termDesc}) beendet. Es gab #{noneOneMoreDE n "Keine Abgaben" "Nur eine Abgabe von " (toMessage n <> " Abgaben von ")}#{noneOneMoreDE num "" "einem Teilnehmer" (toMessage num <> " Teilnehmern")}.
MailSubjectCorrectionsAssigned csh@CourseShorthand sheetName@SheetName: Ihnen wurden Korrekturen zu #{sheetName} in #{csh} zugeteilt MailSubjectCorrectionsAssigned csh@CourseShorthand sheetName@SheetName: Ihnen wurden Korrekturen zu #{sheetName} in #{csh} zugeteilt
MailCorrectionsAssignedIntro courseName@Text termDesc@Text sheetName@SheetName n@Int: #{display n} #{pluralDE n "Abgabe wurde" "Abgaben wurden"} Ihnen zur Korrektur für #{sheetName} im Kurs #{courseName} (#{termDesc}) zugeteilt. MailCorrectionsAssignedIntro courseName@Text termDesc@Text sheetName@SheetName n@Int: #{n} #{pluralDE n "Abgabe wurde" "Abgaben wurden"} Ihnen zur Korrektur für #{sheetName} im Kurs #{courseName} (#{termDesc}) zugeteilt.
MailSubjectUserRightsUpdate name@Text: Berechtigungen für #{name} aktualisiert MailSubjectUserRightsUpdate name@Text: Berechtigungen für #{name} aktualisiert
MailUserRightsIntro name@Text email@UserEmail: #{name} <#{email}> hat folgende Uni2work Berechtigungen: MailUserRightsIntro name@Text email@UserEmail: #{name} <#{email}> hat folgende Uni2work Berechtigungen:
@ -644,22 +644,22 @@ MailSubjectSupport: Supportanfrage
MailSubjectSupportCustom customSubject@Text: [Support] #{customSubject} MailSubjectSupportCustom customSubject@Text: [Support] #{customSubject}
CommCourseSubject: Kursmitteilung CommCourseSubject: Kursmitteilung
MailSubjectLecturerInvitation tid@TermId ssh@SchoolId csh@CourseShorthand: [#{display tid}-#{display ssh}-#{csh}] Einladung zum Kursverwalter MailSubjectLecturerInvitation tid@TermId ssh@SchoolId csh@CourseShorthand: [#{tid}-#{ssh}-#{csh}] Einladung zum Kursverwalter
InvitationAcceptDecline: Einladung annehmen/ablehnen InvitationAcceptDecline: Einladung annehmen/ablehnen
MailSubjectParticipantInvitation tid@TermId ssh@SchoolId csh@CourseShorthand: [#{display tid}-#{display ssh}-#{csh}] Einladung zum Kursteilname MailSubjectParticipantInvitation tid@TermId ssh@SchoolId csh@CourseShorthand: [#{tid}-#{ssh}-#{csh}] Einladung zum Kursteilname
MailSubjectCorrectorInvitation tid@TermId ssh@SchoolId csh@CourseShorthand shn@SheetName: [#{display tid}-#{display ssh}-#{csh}] Einladung zum Korrektor für #{shn} MailSubjectCorrectorInvitation tid@TermId ssh@SchoolId csh@CourseShorthand shn@SheetName: [#{tid}-#{ssh}-#{csh}] Einladung zum Korrektor für #{shn}
MailSubjectTutorInvitation tid@TermId ssh@SchoolId csh@CourseShorthand tutn@TutorialName: [#{display tid}-#{display ssh}-#{csh}] Einladung zum Tutor für #{tutn} MailSubjectTutorInvitation tid@TermId ssh@SchoolId csh@CourseShorthand tutn@TutorialName: [#{tid}-#{ssh}-#{csh}] Einladung zum Tutor für #{tutn}
MailSubjectExamCorrectorInvitation tid@TermId ssh@SchoolId csh@CourseShorthand examn@ExamName: [#{display tid}-#{display ssh}-#{csh}] Einladung zum Korrektor für Klausur #{examn} MailSubjectExamCorrectorInvitation tid@TermId ssh@SchoolId csh@CourseShorthand examn@ExamName: [#{tid}-#{ssh}-#{csh}] Einladung zum Korrektor für Klausur #{examn}
MailSubjectSubmissionUserInvitation tid@TermId ssh@SchoolId csh@CourseShorthand shn@SheetName: [#{display tid}-#{display ssh}-#{csh}] Einladung zu einer Abgabe für #{shn} MailSubjectSubmissionUserInvitation tid@TermId ssh@SchoolId csh@CourseShorthand shn@SheetName: [#{tid}-#{ssh}-#{csh}] Einladung zu einer Abgabe für #{shn}
SheetGrading: Bewertung SheetGrading: Bewertung
SheetGradingPoints maxPoints@Points: #{tshow maxPoints} Punkte SheetGradingPoints maxPoints@Points: #{maxPoints} Punkte
SheetGradingPassPoints maxPoints@Points passingPoints@Points: Bestanden ab #{tshow passingPoints} von #{tshow maxPoints} Punkten SheetGradingPassPoints maxPoints@Points passingPoints@Points: Bestanden ab #{passingPoints} von #{maxPoints} Punkten
SheetGradingPassBinary: Bestanden/Nicht Bestanden SheetGradingPassBinary: Bestanden/Nicht Bestanden
SheetGradingInfo: "Bestanden nach Punkten" zählt sowohl zur maximal erreichbaren Gesamtpunktzahl also auch zur Anzahl der zu bestehenden Blätter. SheetGradingInfo: "Bestanden nach Punkten" zählt sowohl zur maximal erreichbaren Gesamtpunktzahl also auch zur Anzahl der zu bestehenden Blätter.
@ -677,8 +677,8 @@ SheetTypeInfoNotGraded: Blätter ohne Wertung werden nirgends angerechnet, die B
SheetTypeInfoBonus: Bonus Blätter zählen normal, erhöhen aber nicht die maximal erreichbare Punktzahl bzw. Anzahl zu bestehender Blätter. SheetTypeInfoBonus: Bonus Blätter zählen normal, erhöhen aber nicht die maximal erreichbare Punktzahl bzw. Anzahl zu bestehender Blätter.
SheetGradingBonusIncluded: Erzielte Bonuspunkte wurden hier bereits zu den erreichten normalen Punkten hinzugezählt. SheetGradingBonusIncluded: Erzielte Bonuspunkte wurden hier bereits zu den erreichten normalen Punkten hinzugezählt.
SummaryTitle: Zusammenfassung über SummaryTitle: Zusammenfassung über
SheetGradingSummaryTitle intgr@Integer: #{display intgr} #{pluralDE intgr "Blatt" "Blätter"} SheetGradingSummaryTitle intgr@Integer: #{intgr} #{pluralDE intgr "Blatt" "Blätter"}
SubmissionGradingSummaryTitle intgr@Integer: #{display intgr} #{pluralDE intgr "Abgabe" "Abgaben"} SubmissionGradingSummaryTitle intgr@Integer: #{intgr} #{pluralDE intgr "Abgabe" "Abgaben"}
SheetTypeBonus': Bonus SheetTypeBonus': Bonus
SheetTypeNormal': Normal SheetTypeNormal': Normal
@ -910,8 +910,8 @@ CommSubject: Betreff
CommBody: Nachricht CommBody: Nachricht
CommRecipients: Empfänger CommRecipients: Empfänger
CommRecipientsTip: Sie selbst erhalten immer eine Kopie der Nachricht CommRecipientsTip: Sie selbst erhalten immer eine Kopie der Nachricht
CommDuplicateRecipients n@Int: #{tshow n} #{pluralDE n "doppelter" "doppelte"} Empfänger ignoriert CommDuplicateRecipients n@Int: #{n} #{pluralDE n "doppelter" "doppelte"} Empfänger ignoriert
CommSuccess n@Int: Nachricht wurde an #{tshow n} Empfänger versandt CommSuccess n@Int: Nachricht wurde an #{n} Empfänger versandt
CommCourseHeading: Kursmitteilung CommCourseHeading: Kursmitteilung
CommTutorialHeading: Tutorium-Mitteilung CommTutorialHeading: Tutorium-Mitteilung
@ -1008,7 +1008,7 @@ TutorialDelete: Löschen
CourseExams: Klausuren CourseExams: Klausuren
CourseTutorials: Übungen CourseTutorials: Übungen
ParticipantsN n@Int: #{tshow n} Teilnehmer ParticipantsN n@Int: #{n} Teilnehmer
TutorialDeleteQuestion: Wollen Sie das unten aufgeführte Tutorium wirklich löschen? TutorialDeleteQuestion: Wollen Sie das unten aufgeführte Tutorium wirklich löschen?
TutorialDeleted: Tutorium gelöscht TutorialDeleted: Tutorium gelöscht
@ -1045,11 +1045,11 @@ HealthLDAPAdmins: Anteil der Administratoren, die im LDAP-Verzeichnis gefunden w
HealthSMTPConnect: SMTP-Server kann erreicht werden HealthSMTPConnect: SMTP-Server kann erreicht werden
HealthWidgetMemcached: Memcached-Server liefert Widgets korrekt aus HealthWidgetMemcached: Memcached-Server liefert Widgets korrekt aus
CourseParticipants n@Int: Derzeit #{tshow n} angemeldete Kursteilnehmer CourseParticipants n@Int: Derzeit #{n} angemeldete Kursteilnehmer
CourseParticipantsInvited n@Int: #{tshow n} #{pluralDE n "Einladung" "Einladungen"} per E-Mail verschickt CourseParticipantsInvited n@Int: #{n} #{pluralDE n "Einladung" "Einladungen"} per E-Mail verschickt
CourseParticipantsAlreadyRegistered n@Int: #{tshow n} Teilnehmer #{pluralDE n "ist" "sind"} bereits angemeldet CourseParticipantsAlreadyRegistered n@Int: #{n} Teilnehmer #{pluralDE n "ist" "sind"} bereits angemeldet
CourseParticipantsRegisteredWithoutField n@Int: #{tshow n} Teilnehmer #{pluralDE n "wurde ohne assoziiertes Hauptfach" "wurden assoziierte Hauptfächer"} angemeldet, da #{pluralDE n "kein eindeutiges Hauptfach bestimmt werden konnte" "keine eindeutigen Hauptfächer bestimmt werden konnten"} CourseParticipantsRegisteredWithoutField n@Int: #{n} Teilnehmer #{pluralDE n "wurde ohne assoziiertes Hauptfach" "wurden assoziierte Hauptfächer"} angemeldet, da #{pluralDE n "kein eindeutiges Hauptfach bestimmt werden konnte" "keine eindeutigen Hauptfächer bestimmt werden konnten"}
CourseParticipantsRegistered n@Int: #{tshow n} Teilnehmer erfolgreich angemeldet CourseParticipantsRegistered n@Int: #{n} Teilnehmer erfolgreich angemeldet
CourseParticipantsRegisterHeading: Kursteilnehmer hinzufügen CourseParticipantsRegisterHeading: Kursteilnehmer hinzufügen
ExamName: Name ExamName: Name
@ -1164,4 +1164,4 @@ ExamClosedMustBeAfterStart: "Noten stehen fest ab" muss nach Start liegen
ExamClosedMustBeAfterEnd: "Noten stehen fest ab" muss nach Ende liegen ExamClosedMustBeAfterEnd: "Noten stehen fest ab" muss nach Ende liegen
VersionHistory: Versionsgeschichte VersionHistory: Versionsgeschichte
KnownBugs: Bekannte Bugs KnownBugs: Bekannte Bugs

82
package-lock.json generated
View File

@ -5919,7 +5919,8 @@
"ansi-regex": { "ansi-regex": {
"version": "2.1.1", "version": "2.1.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"aproba": { "aproba": {
"version": "1.2.0", "version": "1.2.0",
@ -5940,12 +5941,14 @@
"balanced-match": { "balanced-match": {
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"brace-expansion": { "brace-expansion": {
"version": "1.1.11", "version": "1.1.11",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"balanced-match": "^1.0.0", "balanced-match": "^1.0.0",
"concat-map": "0.0.1" "concat-map": "0.0.1"
@ -5960,17 +5963,20 @@
"code-point-at": { "code-point-at": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"concat-map": { "concat-map": {
"version": "0.0.1", "version": "0.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"console-control-strings": { "console-control-strings": {
"version": "1.1.0", "version": "1.1.0",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"core-util-is": { "core-util-is": {
"version": "1.0.2", "version": "1.0.2",
@ -6087,7 +6093,8 @@
"inherits": { "inherits": {
"version": "2.0.3", "version": "2.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"ini": { "ini": {
"version": "1.3.5", "version": "1.3.5",
@ -6099,6 +6106,7 @@
"version": "1.0.0", "version": "1.0.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"number-is-nan": "^1.0.0" "number-is-nan": "^1.0.0"
} }
@ -6113,6 +6121,7 @@
"version": "3.0.4", "version": "3.0.4",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"brace-expansion": "^1.1.7" "brace-expansion": "^1.1.7"
} }
@ -6120,12 +6129,14 @@
"minimist": { "minimist": {
"version": "0.0.8", "version": "0.0.8",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"minipass": { "minipass": {
"version": "2.3.5", "version": "2.3.5",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"safe-buffer": "^5.1.2", "safe-buffer": "^5.1.2",
"yallist": "^3.0.0" "yallist": "^3.0.0"
@ -6144,6 +6155,7 @@
"version": "0.5.1", "version": "0.5.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"minimist": "0.0.8" "minimist": "0.0.8"
} }
@ -6224,7 +6236,8 @@
"number-is-nan": { "number-is-nan": {
"version": "1.0.1", "version": "1.0.1",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"object-assign": { "object-assign": {
"version": "4.1.1", "version": "4.1.1",
@ -6236,6 +6249,7 @@
"version": "1.4.0", "version": "1.4.0",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"wrappy": "1" "wrappy": "1"
} }
@ -6321,7 +6335,8 @@
"safe-buffer": { "safe-buffer": {
"version": "5.1.2", "version": "5.1.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"safer-buffer": { "safer-buffer": {
"version": "2.1.2", "version": "2.1.2",
@ -6357,6 +6372,7 @@
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"code-point-at": "^1.0.0", "code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0", "is-fullwidth-code-point": "^1.0.0",
@ -6376,6 +6392,7 @@
"version": "3.0.1", "version": "3.0.1",
"bundled": true, "bundled": true,
"dev": true, "dev": true,
"optional": true,
"requires": { "requires": {
"ansi-regex": "^2.0.0" "ansi-regex": "^2.0.0"
} }
@ -6419,12 +6436,14 @@
"wrappy": { "wrappy": {
"version": "1.0.2", "version": "1.0.2",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
}, },
"yallist": { "yallist": {
"version": "3.0.3", "version": "3.0.3",
"bundled": true, "bundled": true,
"dev": true "dev": true,
"optional": true
} }
} }
}, },
@ -12465,47 +12484,6 @@
"mkdirp": "^0.5.1" "mkdirp": "^0.5.1"
} }
}, },
"write-file-atomic": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
"integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.11",
"imurmurhash": "^0.1.4",
"signal-exit": "^3.0.2"
}
},
"write-yaml-file": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/write-yaml-file/-/write-yaml-file-3.0.1.tgz",
"integrity": "sha512-OHzbrlgjw/K/BAH6LdEOcSQFz5nkk0I/25CjKLIVFvcg2Ej7+QE/GTnitgqWnhlsdghor7OV5gfttQPGogQ1XA==",
"dev": true,
"requires": {
"graceful-fs": "^4.1.11",
"js-yaml": "^3.8.1",
"make-dir": "^3.0.0",
"pify": "^4.0.0",
"write-file-atomic": "^2.4.3"
},
"dependencies": {
"make-dir": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz",
"integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==",
"dev": true,
"requires": {
"semver": "^6.0.0"
}
},
"semver": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.1.2.tgz",
"integrity": "sha512-z4PqiCpomGtWj8633oeAdXm1Kn1W++3T8epkZYnwiVgIYIJ0QHszhInYSJTYxebByQH7KVCEAn8R9duzZW2PhQ==",
"dev": true
}
}
},
"ws": { "ws": {
"version": "3.3.3", "version": "3.3.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",

View File

@ -0,0 +1,14 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Data.CryptoID.Instances
(
) where
import qualified Data.CryptoID as CID
import Text.Blaze (ToMarkup(..))
import ClassyPrelude
instance ToMarkup s => ToMarkup (CID.CryptoID c s) where
toMarkup = toMarkup . CID.ciphertext

View File

@ -0,0 +1,13 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Data.Fixed.Instances
(
) where
import ClassyPrelude
import Data.Fixed
import Text.Blaze (ToMarkup(..))
instance HasResolution a => ToMarkup (Fixed a) where
toMarkup = toMarkup . showFixed True

View File

@ -0,0 +1,13 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Data.Maybe.Instances
(
) where
import ClassyPrelude
import Text.Blaze (ToMarkup(..), string)
instance ToMarkup a => ToMarkup (Maybe a) where
toMarkup Nothing = string ""
toMarkup (Just x) = toMarkup x

13
src/Data/Sum/Instances.hs Normal file
View File

@ -0,0 +1,13 @@
{-# OPTIONS_GHC -fno-warn-orphans #-}
module Data.Sum.Instances
(
) where
import ClassyPrelude
import Data.Monoid (Sum(..))
import Text.Blaze (ToMarkup(..))
instance ToMarkup a => ToMarkup (Sum a) where
toMarkup = toMarkup . getSum

View File

@ -21,10 +21,7 @@ import qualified Network.Wai as W (pathInfo)
import Yesod.Core.Types (Logger) import Yesod.Core.Types (Logger)
import qualified Yesod.Core.Unsafe as Unsafe import qualified Yesod.Core.Unsafe as Unsafe
import Data.CaseInsensitive (CI) import Data.CaseInsensitive (original, mk)
import qualified Data.CaseInsensitive as CI
import qualified Data.CryptoID as E
import Data.ByteArray (convert) import Data.ByteArray (convert)
import Crypto.Hash (Digest, SHAKE256, SHAKE128) import Crypto.Hash (Digest, SHAKE256, SHAKE128)
@ -91,18 +88,6 @@ import qualified Data.Aeson as JSON
import Data.FileEmbed (embedFile) import Data.FileEmbed (embedFile)
instance DisplayAble b => DisplayAble (E.CryptoID a b) where
display = display . ciphertext
instance {-# OVERLAPS #-} namespace ~ CryptoIDNamespace (CI FilePath) SubmissionId => DisplayAble (E.CryptoID namespace (CI FilePath)) where
display = toPathPiece
instance DisplayAble TermId where
display = termToText . unTermKey
instance DisplayAble SchoolId where
display = CI.original . unSchoolKey
type SMTPPool = Pool SMTPConnection type SMTPPool = Pool SMTPConnection
-- infixl 9 :$: -- infixl 9 :$:
@ -225,9 +210,9 @@ type IntMaybe = Maybe Int
type TextList = [Text] type TextList = [Text]
-- | Convenience function for i18n messages definitions -- | Convenience function for i18n messages definitions
maybeDisplay :: DisplayAble m => Text -> Maybe m -> Text -> Text maybeToMessage :: ToMessage m => Text -> Maybe m -> Text -> Text
maybeDisplay _ Nothing _ = mempty maybeToMessage _ Nothing _ = mempty
maybeDisplay before (Just x) after = before <> (display x) <> after maybeToMessage before (Just x) after = before <> (toMessage x) <> after
-- Messages creates type UniWorXMessage and RenderMessage UniWorX instance -- Messages creates type UniWorXMessage and RenderMessage UniWorX instance
mkMessage "UniWorX" "messages/uniworx" "de" mkMessage "UniWorX" "messages/uniworx" "de"
@ -259,6 +244,17 @@ instance RenderMessage UniWorX ShortTermIdentifier where
instance RenderMessage UniWorX String where instance RenderMessage UniWorX String where
renderMessage f ls str = renderMessage f ls $ Text.pack str renderMessage f ls str = renderMessage f ls $ Text.pack str
-- TODO: raw number representation; instead, display e.g. 1000 as 1.000 or 1,000 or ... (language-dependent!)
instance RenderMessage UniWorX Int where
renderMessage f ls = renderMessage f ls . tshow
instance RenderMessage UniWorX Int64 where
renderMessage f ls = renderMessage f ls . tshow
instance RenderMessage UniWorX Integer where
renderMessage f ls = renderMessage f ls . tshow
instance HasResolution a => RenderMessage UniWorX (Fixed a) where
renderMessage f ls = renderMessage f ls . showFixed True
instance RenderMessage UniWorX Load where instance RenderMessage UniWorX Load where
renderMessage foundation ls = renderMessage foundation ls . \case renderMessage foundation ls = renderMessage foundation ls . \case
(Load {byTutorial=Nothing , byProportion=p}) -> MsgCorByProportionOnly p (Load {byTutorial=Nothing , byProportion=p}) -> MsgCorByProportionOnly p
@ -336,6 +332,23 @@ instance RenderMessage UniWorX ExamGrade where
renderMessage _ _ = pack . (showFixed False :: Deci -> String) . fromRational . review numberGrade renderMessage _ _ = pack . (showFixed False :: Deci -> String) . fromRational . review numberGrade
-- ToMessage instances for converting raw numbers to Text (no internationalization)
instance ToMessage Int where
toMessage = tshow
instance ToMessage Int64 where
toMessage = tshow
instance ToMessage Integer where
toMessage = tshow
instance HasResolution a => ToMessage (Fixed a) where
toMessage = toMessage . showFixed True
-- Do not use toMessage on Rationals and round them automatically. Instead, use rationalToFixed3 (declared in src/Utils.hs) to convert a Rational to Fixed E3!
-- instance ToMessage Rational where
-- toMessage = toMessage . fromRational'
-- where fromRational' = fromRational :: Rational -> Fixed E3
newtype ErrorResponseTitle = ErrorResponseTitle ErrorResponse newtype ErrorResponseTitle = ErrorResponseTitle ErrorResponse
embedRenderMessageVariant ''UniWorX ''ErrorResponseTitle ("ErrorResponseTitle" <>) embedRenderMessageVariant ''UniWorX ''ErrorResponseTitle ("ErrorResponseTitle" <>)
@ -1483,11 +1496,11 @@ instance YesodBreadcrumbs UniWorX where
breadcrumb (TermEditExistR tid) = return ("Editieren" , Just $ TermCourseListR tid) breadcrumb (TermEditExistR tid) = return ("Editieren" , Just $ TermCourseListR tid)
breadcrumb (TermCourseListR (unTermKey -> tid)) = getMessageRender <&> \mr -> (mr $ ShortTermIdentifier tid, Just CourseListR) breadcrumb (TermCourseListR (unTermKey -> tid)) = getMessageRender <&> \mr -> (mr $ ShortTermIdentifier tid, Just CourseListR)
breadcrumb (TermSchoolCourseListR tid ssh) = return (CI.original $ unSchoolKey ssh, Just $ TermCourseListR tid) breadcrumb (TermSchoolCourseListR tid ssh) = return (original $ unSchoolKey ssh, Just $ TermCourseListR tid)
breadcrumb CourseListR = return ("Kurse" , Nothing) breadcrumb CourseListR = return ("Kurse" , Nothing)
breadcrumb CourseNewR = return ("Neu" , Just CourseListR) breadcrumb CourseNewR = return ("Neu" , Just CourseListR)
breadcrumb (CourseR tid ssh csh CShowR) = return (CI.original csh, Just $ TermSchoolCourseListR tid ssh) breadcrumb (CourseR tid ssh csh CShowR) = return (original csh, Just $ TermSchoolCourseListR tid ssh)
-- (CourseR tid ssh csh CRegisterR) -- is POST only -- (CourseR tid ssh csh CRegisterR) -- is POST only
breadcrumb (CourseR tid ssh csh CEditR) = return ("Editieren" , Just $ CourseR tid ssh csh CShowR) breadcrumb (CourseR tid ssh csh CEditR) = return ("Editieren" , Just $ CourseR tid ssh csh CShowR)
breadcrumb (CourseR tid ssh csh CUsersR) = return ("Anmeldungen", Just $ CourseR tid ssh csh CShowR) breadcrumb (CourseR tid ssh csh CUsersR) = return ("Anmeldungen", Just $ CourseR tid ssh csh CShowR)
@ -1507,15 +1520,15 @@ instance YesodBreadcrumbs UniWorX where
breadcrumb (CourseR tid ssh csh CExamListR) = return ("Klausuren", Just $ CourseR tid ssh csh CShowR) breadcrumb (CourseR tid ssh csh CExamListR) = return ("Klausuren", Just $ CourseR tid ssh csh CShowR)
breadcrumb (CourseR tid ssh csh CExamNewR) = return ("Anlegen", Just $ CourseR tid ssh csh CExamListR) breadcrumb (CourseR tid ssh csh CExamNewR) = return ("Anlegen", Just $ CourseR tid ssh csh CExamListR)
breadcrumb (CExamR tid ssh csh examn EShowR) = return (CI.original examn, Just $ CourseR tid ssh csh CExamListR) breadcrumb (CExamR tid ssh csh examn EShowR) = return (original examn, Just $ CourseR tid ssh csh CExamListR)
breadcrumb (CExamR tid ssh csh examn EEditR) = return ("Bearbeiten", Just $ CExamR tid ssh csh examn EShowR) breadcrumb (CExamR tid ssh csh examn EEditR) = return ("Bearbeiten", Just $ CExamR tid ssh csh examn EShowR)
breadcrumb (CTutorialR tid ssh csh tutn TUsersR) = return (CI.original tutn, Just $ CourseR tid ssh csh CTutorialListR) breadcrumb (CTutorialR tid ssh csh tutn TUsersR) = return (original tutn, Just $ CourseR tid ssh csh CTutorialListR)
breadcrumb (CTutorialR tid ssh csh tutn TEditR) = return ("Bearbeiten", Just $ CTutorialR tid ssh csh tutn TUsersR) breadcrumb (CTutorialR tid ssh csh tutn TEditR) = return ("Bearbeiten", Just $ CTutorialR tid ssh csh tutn TUsersR)
breadcrumb (CTutorialR tid ssh csh tutn TDeleteR) = return ("Löschen", Just $ CTutorialR tid ssh csh tutn TUsersR) breadcrumb (CTutorialR tid ssh csh tutn TDeleteR) = return ("Löschen", Just $ CTutorialR tid ssh csh tutn TUsersR)
breadcrumb (CTutorialR tid ssh csh tutn TCommR) = return ("Mitteilung", Just $ CTutorialR tid ssh csh tutn TUsersR) breadcrumb (CTutorialR tid ssh csh tutn TCommR) = return ("Mitteilung", Just $ CTutorialR tid ssh csh tutn TUsersR)
breadcrumb (CSheetR tid ssh csh shn SShowR) = return (CI.original shn, Just $ CourseR tid ssh csh SheetListR) breadcrumb (CSheetR tid ssh csh shn SShowR) = return (original shn, Just $ CourseR tid ssh csh SheetListR)
breadcrumb (CSheetR tid ssh csh shn SEditR) = return ("Bearbeiten" , Just $ CSheetR tid ssh csh shn SShowR) breadcrumb (CSheetR tid ssh csh shn SEditR) = return ("Bearbeiten" , Just $ CSheetR tid ssh csh shn SShowR)
breadcrumb (CSheetR tid ssh csh shn SDelR ) = return ("Löschen" , Just $ CSheetR tid ssh csh shn SShowR) breadcrumb (CSheetR tid ssh csh shn SDelR ) = return ("Löschen" , Just $ CSheetR tid ssh csh shn SShowR)
breadcrumb (CSheetR tid ssh csh shn SSubsR) = return ("Abgaben" , Just $ CSheetR tid ssh csh shn SShowR) breadcrumb (CSheetR tid ssh csh shn SSubsR) = return ("Abgaben" , Just $ CSheetR tid ssh csh shn SShowR)
@ -1531,7 +1544,7 @@ instance YesodBreadcrumbs UniWorX where
breadcrumb (CourseR tid ssh csh MaterialListR) = return ("Material" , Just $ CourseR tid ssh csh CShowR) breadcrumb (CourseR tid ssh csh MaterialListR) = return ("Material" , Just $ CourseR tid ssh csh CShowR)
breadcrumb (CourseR tid ssh csh MaterialNewR ) = return ("Neu" , Just $ CourseR tid ssh csh MaterialListR) breadcrumb (CourseR tid ssh csh MaterialNewR ) = return ("Neu" , Just $ CourseR tid ssh csh MaterialListR)
breadcrumb (CMaterialR tid ssh csh mnm MShowR) = return (CI.original mnm, Just $ CourseR tid ssh csh MaterialListR) breadcrumb (CMaterialR tid ssh csh mnm MShowR) = return (original mnm, Just $ CourseR tid ssh csh MaterialListR)
breadcrumb (CMaterialR tid ssh csh mnm MEditR) = return ("Bearbeiten" , Just $ CMaterialR tid ssh csh mnm MShowR) breadcrumb (CMaterialR tid ssh csh mnm MEditR) = return ("Bearbeiten" , Just $ CMaterialR tid ssh csh mnm MShowR)
breadcrumb (CMaterialR tid ssh csh mnm MDelR) = return ("Löschen" , Just $ CMaterialR tid ssh csh mnm MShowR) breadcrumb (CMaterialR tid ssh csh mnm MDelR) = return ("Löschen" , Just $ CMaterialR tid ssh csh mnm MShowR)
-- (CMaterialR tid ssh csh mnm MFileR) -- just for Downloads -- (CMaterialR tid ssh csh mnm MFileR) -- just for Downloads
@ -2062,8 +2075,8 @@ pageActions (CourseR tid ssh csh SheetListR) =
, menuItemLabel = MsgMenuCorrectionsOwn , menuItemLabel = MsgMenuCorrectionsOwn
, menuItemIcon = Nothing , menuItemIcon = Nothing
, menuItemRoute = SomeRoute (CorrectionsR, [ ("corrections-term" , termToText $ unTermKey tid) , menuItemRoute = SomeRoute (CorrectionsR, [ ("corrections-term" , termToText $ unTermKey tid)
, ("corrections-school", CI.original $ unSchoolKey ssh) , ("corrections-school", original $ unSchoolKey ssh)
, ("corrections-course", CI.original csh) , ("corrections-course", original csh)
]) ])
, menuItemModal = False , menuItemModal = False
, menuItemAccessCallback' = do , menuItemAccessCallback' = do
@ -2223,9 +2236,9 @@ pageActions (CSheetR tid ssh csh shn SShowR) =
, menuItemLabel = MsgMenuCorrectionsOwn , menuItemLabel = MsgMenuCorrectionsOwn
, menuItemIcon = Nothing , menuItemIcon = Nothing
, menuItemRoute = SomeRoute (CorrectionsR, [ ("corrections-term" , termToText $ unTermKey tid) , menuItemRoute = SomeRoute (CorrectionsR, [ ("corrections-term" , termToText $ unTermKey tid)
, ("corrections-school", CI.original $ unSchoolKey ssh) , ("corrections-school", original $ unSchoolKey ssh)
, ("corrections-course", CI.original csh) , ("corrections-course", original csh)
, ("corrections-sheet" , CI.original shn) , ("corrections-sheet" , original shn)
]) ])
, menuItemModal = False , menuItemModal = False
, menuItemAccessCallback' = (== Authorized) <$> evalAccessCorrector tid ssh csh , menuItemAccessCallback' = (== Authorized) <$> evalAccessCorrector tid ssh csh
@ -2576,7 +2589,7 @@ routeNormalizers =
tell $ Any True tell $ Any True
maybeOrig f route = maybeT (return route) $ f route maybeOrig f route = maybeT (return route) $ f route
hasChanged a b hasChanged a b
| ((/=) `on` CI.original) a b = do | ((/=) `on` original) a b = do
$logDebugS "routeNormalizers" [st|#{tshow a} /= #{tshow b}|] $logDebugS "routeNormalizers" [st|#{tshow a} /= #{tshow b}|]
tell $ Any True tell $ Any True
| otherwise = return () | otherwise = return ()
@ -2642,7 +2655,7 @@ instance YesodAuth UniWorX where
now <- liftIO getCurrentTime now <- liftIO getCurrentTime
let let
userIdent = CI.mk credsIdent userIdent = mk credsIdent
uAuth = UniqueAuthentication userIdent uAuth = UniqueAuthentication userIdent
isDummy = credsPlugin == "dummy" isDummy = credsPlugin == "dummy"
@ -2680,7 +2693,7 @@ instance YesodAuth UniWorX where
flip catches excHandlers $ case (,) <$> appLdapConf <*> appLdapPool of flip catches excHandlers $ case (,) <$> appLdapConf <*> appLdapPool of
Just (ldapConf, ldapPool) -> fmap (either id id) . runExceptT $ do Just (ldapConf, ldapPool) -> fmap (either id id) . runExceptT $ do
ldapData <- campusUser ldapConf ldapPool $ Creds credsPlugin (CI.original userIdent) credsExtra ldapData <- campusUser ldapConf ldapPool $ Creds credsPlugin (original userIdent) credsExtra
$logDebugS "LDAP" $ "Successful LDAP lookup: " <> tshow ldapData $logDebugS "LDAP" $ "Successful LDAP lookup: " <> tshow ldapData
let let
@ -2697,7 +2710,7 @@ instance YesodAuth UniWorX where
userEmail <- if userEmail <- if
| Just [bs] <- userEmail' | Just [bs] <- userEmail'
, Right userEmail <- Text.decodeUtf8' bs , Right userEmail <- Text.decodeUtf8' bs
-> return $ CI.mk userEmail -> return $ mk userEmail
| otherwise | otherwise
-> throwError $ ServerError "Could not retrieve user email" -> throwError $ ServerError "Could not retrieve user email"
userDisplayName <- if userDisplayName <- if
@ -2752,7 +2765,7 @@ instance YesodAuth UniWorX where
Right str <- return $ Text.decodeUtf8' v' Right str <- return $ Text.decodeUtf8' v'
return str return str
termNames = nubBy ((==) `on` CI.mk) $ do termNames = nubBy ((==) `on` mk) $ do
(k, v) <- ldapData (k, v) <- ldapData
guard $ k == Attr "dfnEduPersonFieldOfStudyString" guard $ k == Attr "dfnEduPersonFieldOfStudyString"
v' <- v v' <- v

View File

@ -126,7 +126,7 @@ colSheet = sortable (Just "sheet") (i18nCell MsgSheet) $ \row ->
ssh = course ^. _4 ssh = course ^. _4
csh = course ^. _2 csh = course ^. _2
shn = sheetName $ entityVal sheet shn = sheetName $ entityVal sheet
in anchorCell (CSheetR tid ssh csh shn SShowR) [whamlet|#{display shn}|] in anchorCell (CSheetR tid ssh csh shn SShowR) [whamlet|_{shn}|]
colSheetType :: IsDBTable m a => Colonnade Sortable CorrectionTableData (DBCell m a) colSheetType :: IsDBTable m a => Colonnade Sortable CorrectionTableData (DBCell m a)
colSheetType = sortable (toNothing "sheetType") (i18nCell MsgSheetType) $ colSheetType = sortable (toNothing "sheetType") (i18nCell MsgSheetType) $
@ -149,7 +149,7 @@ colSubmissionLink = sortable Nothing (i18nCell MsgSubmission)
mkRoute = do mkRoute = do
cid <- mkCid cid <- mkCid
return $ CSubmissionR tid ssh csh shn cid SubShowR return $ CSubmissionR tid ssh csh shn cid SubShowR
in anchorCellM mkRoute (mkCid >>= \cid -> [whamlet|#{display cid}|]) in anchorCellM mkRoute (mkCid >>= \cid -> [whamlet|#{cid}|])
colSelect :: forall act h. (Semigroup act, Monoid act, Headedness h) => Colonnade h CorrectionTableData (DBCell _ (FormResult (act, DBFormResult CryptoFileNameSubmission Bool CorrectionTableData), SheetTypeSummary)) colSelect :: forall act h. (Semigroup act, Monoid act, Headedness h) => Colonnade h CorrectionTableData (DBCell _ (FormResult (act, DBFormResult CryptoFileNameSubmission Bool CorrectionTableData), SheetTypeSummary))
colSelect = dbSelect (_1 . applying _2) id $ \DBRow{ dbrOutput=(Entity subId _, _, _, _, _, _) } -> encrypt subId colSelect = dbSelect (_1 . applying _2) id $ \DBRow{ dbrOutput=(Entity subId _, _, _, _, _, _) } -> encrypt subId

View File

@ -53,7 +53,7 @@ colCourse :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a)
colCourse = sortable (Just "course") (i18nCell MsgCourse) colCourse = sortable (Just "course") (i18nCell MsgCourse)
$ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, _) } -> $ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, _) } ->
anchorCell (CourseR courseTerm courseSchool courseShorthand CShowR) anchorCell (CourseR courseTerm courseSchool courseShorthand CShowR)
[whamlet|#{display courseName}|] [whamlet|_{courseName}|]
-- colCourseDescr :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a) -- colCourseDescr :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a)
-- colCourseDescr = sortable (Just "course") (i18nCell MsgCourse) $ do -- colCourseDescr = sortable (Just "course") (i18nCell MsgCourse) $ do
@ -70,7 +70,7 @@ colDescription = sortable Nothing mempty
colCShort :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a) colCShort :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a)
colCShort = sortable (Just "cshort") (i18nCell MsgCourseShort) colCShort = sortable (Just "cshort") (i18nCell MsgCourseShort)
$ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, _) } -> $ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, _) } ->
anchorCell (CourseR courseTerm courseSchool courseShorthand CShowR) [whamlet|#{display courseShorthand}|] anchorCell (CourseR courseTerm courseSchool courseShorthand CShowR) [whamlet|_{courseShorthand}|]
-- colCShortDescr :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a) -- colCShortDescr :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a)
-- colCShortDescr = sortable (Just "cshort") (i18nCell MsgCourseShort) -- colCShortDescr = sortable (Just "cshort") (i18nCell MsgCourseShort)
@ -89,17 +89,17 @@ colCShort = sortable (Just "cshort") (i18nCell MsgCourseShort)
colTerm :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a) colTerm :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a)
colTerm = sortable (Just "term") (i18nCell MsgTerm) colTerm = sortable (Just "term") (i18nCell MsgTerm)
$ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, _) } -> $ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, _) } ->
anchorCell (TermCourseListR courseTerm) [whamlet|#{display courseTerm}|] anchorCell (TermCourseListR courseTerm) [whamlet|#{courseTerm}|]
colSchool :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a) colSchool :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a)
colSchool = sortable (Just "school") (i18nCell MsgCourseSchool) colSchool = sortable (Just "school") (i18nCell MsgCourseSchool)
$ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, Entity _ School{..}) } -> $ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, Entity _ School{..}) } ->
anchorCell (TermSchoolCourseListR courseTerm courseSchool) [whamlet|#{display schoolName}|] anchorCell (TermSchoolCourseListR courseTerm courseSchool) [whamlet|_{schoolName}|]
colSchoolShort :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a) colSchoolShort :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a)
colSchoolShort = sortable (Just "schoolshort") (i18nCell MsgCourseSchoolShort) colSchoolShort = sortable (Just "schoolshort") (i18nCell MsgCourseSchoolShort)
$ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, Entity _ School{..}) } -> $ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, Entity _ School{..}) } ->
anchorCell (TermSchoolCourseListR courseTerm courseSchool) [whamlet|#{display schoolShorthand}|] anchorCell (TermSchoolCourseListR courseTerm courseSchool) [whamlet|_{schoolShorthand}|]
colRegFrom :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a) colRegFrom :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a)
colRegFrom = sortable (Just "register-from") (i18nCell MsgRegisterFrom) colRegFrom = sortable (Just "register-from") (i18nCell MsgRegisterFrom)
@ -1220,7 +1220,7 @@ postCUsersR tid ssh csh = do
] ]
addMessageI Success $ MsgCourseUsersDeregistered nrDel addMessageI Success $ MsgCourseUsersDeregistered nrDel
redirect $ CourseR tid ssh csh CUsersR redirect $ CourseR tid ssh csh CUsersR
let headingLong = [whamlet|_{MsgMenuCourseMembers} #{courseName course} #{display tid}|] let headingLong = [whamlet|_{MsgMenuCourseMembers} #{courseName course} #{tid}|]
headingShort = prependCourseTitle tid ssh csh MsgCourseMembers headingShort = prependCourseTitle tid ssh csh MsgCourseMembers
siteLayout headingLong $ do siteLayout headingLong $ do
setTitleI headingShort setTitleI headingShort
@ -1407,7 +1407,7 @@ postCUserR tid ssh csh uCId = do
mRegAt <- for (courseParticipantRegistration . entityVal <$> mRegistration) $ formatTime SelFormatDateTime mRegAt <- for (courseParticipantRegistration . entityVal <$> mRegistration) $ formatTime SelFormatDateTime
-- generate output -- generate output
let headingLong = [whamlet|^{nameWidget userDisplayName userSurname} - _{MsgCourseMemberOf} #{csh} #{display tid}|] let headingLong = [whamlet|^{nameWidget userDisplayName userSurname} - _{MsgCourseMemberOf} #{csh} #{tid}|]
headingShort = prependCourseTitle tid ssh csh $ SomeMessage userDisplayName headingShort = prependCourseTitle tid ssh csh $ SomeMessage userDisplayName
siteLayout headingLong $ do siteLayout headingLong $ do
setTitleI headingShort setTitleI headingShort

View File

@ -33,14 +33,14 @@ homeOpenCourses = do
colonnade = mconcat colonnade = mconcat
[ -- dbRow [ -- dbRow
sortable (Just "term") (i18nCell MsgTerm) $ \DBRow{ dbrOutput=Entity{entityVal = course} } -> sortable (Just "term") (i18nCell MsgTerm) $ \DBRow{ dbrOutput=Entity{entityVal = course} } ->
textCell $ display $ courseTerm course textCell $ toMessage $ courseTerm course
, sortable (Just "school") (i18nCell MsgCourseSchool) $ \DBRow{ dbrOutput=Entity{entityVal = course} } -> , sortable (Just "school") (i18nCell MsgCourseSchool) $ \DBRow{ dbrOutput=Entity{entityVal = course} } ->
textCell $ display $ courseSchool course textCell $ toMessage $ courseSchool course
, sortable (Just "course") (i18nCell MsgCourse) $ \DBRow{ dbrOutput=Entity{entityVal = course} } -> do , sortable (Just "course") (i18nCell MsgCourse) $ \DBRow{ dbrOutput=Entity{entityVal = course} } -> do
let tid = courseTerm course let tid = courseTerm course
ssh = courseSchool course ssh = courseSchool course
csh = courseShorthand course csh = courseShorthand course
anchorCell (CourseR tid ssh csh CShowR) (toWidget $ display csh) anchorCell (CourseR tid ssh csh CShowR) (toWidget csh)
, sortable (Just "deadline") (i18nCell MsgRegisterTo) $ \DBRow{ dbrOutput=Entity{entityVal = course} } -> , sortable (Just "deadline") (i18nCell MsgRegisterTo) $ \DBRow{ dbrOutput=Entity{entityVal = course} } ->
cell $ traverse (formatTime SelFormatDateTime) (courseRegisterTo course) >>= maybe mempty toWidget cell $ traverse (formatTime SelFormatDateTime) (courseRegisterTo course) >>= maybe mempty toWidget
] ]
@ -117,13 +117,13 @@ homeUpcomingSheets uid = do
[ -- dbRow [ -- dbRow
-- TOOD: sortable (Just "term") (textCell MsgTerm) $ \DBRow{ dbrOutput=(view _1 -> E.Value tid) } -> -- TOOD: sortable (Just "term") (textCell MsgTerm) $ \DBRow{ dbrOutput=(view _1 -> E.Value tid) } ->
sortable (Just "term") (i18nCell MsgTerm) $ \DBRow{ dbrOutput=(E.Value tid,_,_,_,_,_) } -> sortable (Just "term") (i18nCell MsgTerm) $ \DBRow{ dbrOutput=(E.Value tid,_,_,_,_,_) } ->
textCell $ display tid textCell $ toMessage tid
, sortable (Just "school") (i18nCell MsgCourseSchool) $ \DBRow{ dbrOutput=(_,E.Value ssh,_,_,_,_) } -> , sortable (Just "school") (i18nCell MsgCourseSchool) $ \DBRow{ dbrOutput=(_,E.Value ssh,_,_,_,_) } ->
textCell $ display ssh textCell $ toMessage ssh
, sortable (Just "course") (i18nCell MsgCourse) $ \DBRow{ dbrOutput=(E.Value tid, E.Value ssh, E.Value csh, _, _, _) } -> , sortable (Just "course") (i18nCell MsgCourse) $ \DBRow{ dbrOutput=(E.Value tid, E.Value ssh, E.Value csh, _, _, _) } ->
anchorCell (CourseR tid ssh csh CShowR) (toWidget $ display csh) anchorCell (CourseR tid ssh csh CShowR) (toWidget csh)
, sortable (Just "sheet") (i18nCell MsgSheet) $ \DBRow{ dbrOutput=(E.Value tid, E.Value ssh, E.Value csh, E.Value shn, _, _) } -> , sortable (Just "sheet") (i18nCell MsgSheet) $ \DBRow{ dbrOutput=(E.Value tid, E.Value ssh, E.Value csh, E.Value shn, _, _) } ->
anchorCell (CSheetR tid ssh csh shn SShowR) (toWidget $ display shn) anchorCell (CSheetR tid ssh csh shn SShowR) (toWidget shn)
, sortable (Just "deadline") (i18nCell MsgDeadline) $ \DBRow{ dbrOutput=(_, _, _, _, E.Value deadline, _) } -> , sortable (Just "deadline") (i18nCell MsgDeadline) $ \DBRow{ dbrOutput=(_, _, _, _, E.Value deadline, _) } ->
cell $ formatTime SelFormatDateTime deadline >>= toWidget cell $ formatTime SelFormatDateTime deadline >>= toWidget
, sortable (Just "done") (i18nCell MsgDone) $ \DBRow{ dbrOutput=(E.Value tid, E.Value ssh, E.Value csh, E.Value shn, _, E.Value mbsid) } -> , sortable (Just "done") (i18nCell MsgDone) $ \DBRow{ dbrOutput=(E.Value tid, E.Value ssh, E.Value csh, E.Value shn, _, E.Value mbsid) } ->

View File

@ -45,7 +45,7 @@ makeSettingForm template html = do
<*> notificationForm (stgNotificationSettings <$> template) <*> notificationForm (stgNotificationSettings <$> template)
return (result, widget) -- no validation required here return (result, widget) -- no validation required here
where where
themeList = [Option (display t) t (toPathPiece t) | t <- universeF] themeList = [Option (toMessage t) t (toPathPiece t) | t <- universeF]
-- --
-- Version with proper grouping: -- Version with proper grouping:
-- --

View File

@ -236,7 +236,7 @@ getSheetListR tid ssh csh = do
mkRoute = do mkRoute = do
cid' <- mkCid cid' <- mkCid
return $ CSubmissionR tid ssh csh sheetName cid' SubShowR return $ CSubmissionR tid ssh csh sheetName cid' SubShowR
in anchorCellM mkRoute (mkCid >>= \cid2 -> [whamlet|#{display cid2}|]) in anchorCellM mkRoute (mkCid >>= \cid2 -> [whamlet|#{cid2}|])
, sortable (Just "rating") (i18nCell MsgRating) , sortable (Just "rating") (i18nCell MsgRating)
$ \DBRow{dbrOutput=(Entity _ Sheet{..}, _, mbSub,_)} -> $ \DBRow{dbrOutput=(Entity _ Sheet{..}, _, mbSub,_)} ->
let stats = sheetTypeSum sheetType in -- for statistics over all shown rows let stats = sheetTypeSum sheetType in -- for statistics over all shown rows

View File

@ -41,7 +41,7 @@ getUsersR = do
(nameWidget userDisplayName userSurname) (nameWidget userDisplayName userSurname)
, sortable (Just "matriculation") (i18nCell MsgMatrikelNr) $ \DBRow{ dbrOutput = Entity uid User{..} } -> anchorCellM , sortable (Just "matriculation") (i18nCell MsgMatrikelNr) $ \DBRow{ dbrOutput = Entity uid User{..} } -> anchorCellM
(AdminUserR <$> encrypt uid) (AdminUserR <$> encrypt uid)
(toWidget . display $ userMatrikelnummer) (toWgt userMatrikelnummer)
-- , sortable (Just "last-name") (i18nCell MsgName) $ \DBRow{ dbrOutput = Entity uid User{..} } -> anchorCellM -- , sortable (Just "last-name") (i18nCell MsgName) $ \DBRow{ dbrOutput = Entity uid User{..} } -> anchorCellM
-- (AdminUserR <$> encrypt uid) -- (AdminUserR <$> encrypt uid)
-- (toWidget . display $ last $ impureNonNull $ words $ userDisplayName) -- (toWidget . display $ last $ impureNonNull $ words $ userDisplayName)

View File

@ -175,8 +175,8 @@ cellHasEMail = emailCell . view _userEmail
maybeDateTimeCell :: IsDBTable m a => Maybe UTCTime -> DBCell m a maybeDateTimeCell :: IsDBTable m a => Maybe UTCTime -> DBCell m a
maybeDateTimeCell = maybe mempty dateTimeCell maybeDateTimeCell = maybe mempty dateTimeCell
numCell :: (IsDBTable m a, Num b, DisplayAble b) => b -> DBCell m a numCell :: (IsDBTable m a, Num b, ToMessage b) => b -> DBCell m a
numCell = textCell . display numCell = textCell . toMessage
int64Cell :: (IsDBTable m a) => Int64-> DBCell m a int64Cell :: (IsDBTable m a) => Int64-> DBCell m a
int64Cell = numCell int64Cell = numCell
@ -185,7 +185,7 @@ termCell :: IsDBTable m a => TermId -> DBCell m a
termCell tid = anchorCell link name termCell tid = anchorCell link name
where where
link = TermCourseListR tid link = TermCourseListR tid
name = text2widget $ display tid name = toWgt tid
termCellCL :: IsDBTable m a => CourseLink -> DBCell m a termCellCL :: IsDBTable m a => CourseLink -> DBCell m a
termCellCL (tid,_,_) = termCell tid termCellCL (tid,_,_) = termCell tid
@ -194,11 +194,11 @@ schoolCell :: IsDBTable m a => Maybe TermId -> SchoolId -> DBCell m a
schoolCell (Just tid) ssh = anchorCell link name schoolCell (Just tid) ssh = anchorCell link name
where where
link = TermSchoolCourseListR tid ssh link = TermSchoolCourseListR tid ssh
name = text2widget $ display ssh name = toWgt ssh
schoolCell Nothing ssh = anchorCell link name schoolCell Nothing ssh = anchorCell link name
where where
link = SchoolShowR ssh link = SchoolShowR ssh
name = text2widget $ display ssh name = toWgt ssh
schoolCellCL :: IsDBTable m a => CourseLink -> DBCell m a schoolCellCL :: IsDBTable m a => CourseLink -> DBCell m a
schoolCellCL (tid,ssh,_) = schoolCell (Just tid) ssh schoolCellCL (tid,ssh,_) = schoolCell (Just tid) ssh
@ -207,7 +207,7 @@ courseCellCL :: IsDBTable m a => CourseLink -> DBCell m a
courseCellCL (tid,ssh,csh) = anchorCell link name courseCellCL (tid,ssh,csh) = anchorCell link name
where where
link = CourseR tid ssh csh CShowR link = CourseR tid ssh csh CShowR
name = citext2widget csh name = toWgt csh
courseCell :: IsDBTable m a => Course -> DBCell m a courseCell :: IsDBTable m a => Course -> DBCell m a
courseCell Course{..} = anchorCell link name `mappend` desc courseCell Course{..} = anchorCell link name `mappend` desc
@ -228,7 +228,7 @@ sheetCell crse shn =
ssh = crse ^. _2 ssh = crse ^. _2
csh = crse ^. _3 csh = crse ^. _3
link= CSheetR tid ssh csh shn SShowR link= CSheetR tid ssh csh shn SShowR
in anchorCell link $ display2widget shn in anchorCell link $ toWgt shn
submissionCell :: IsDBTable m a => CourseLink -> SheetName -> SubmissionId -> DBCell m a submissionCell :: IsDBTable m a => CourseLink -> SheetName -> SubmissionId -> DBCell m a
submissionCell crse shn sid = submissionCell crse shn sid =
@ -237,7 +237,7 @@ submissionCell crse shn sid =
csh = crse ^. _3 csh = crse ^. _3
mkCid = encrypt sid mkCid = encrypt sid
mkRoute cid = CSubmissionR tid ssh csh shn cid SubShowR mkRoute cid = CSubmissionR tid ssh csh shn cid SubShowR
mkText = display2widget mkText = toWgt
in anchorCellM' mkCid mkRoute mkText in anchorCellM' mkCid mkRoute mkText
correctorStateCell :: IsDBTable m a => SheetCorrector -> DBCell m a correctorStateCell :: IsDBTable m a => SheetCorrector -> DBCell m a

View File

@ -76,6 +76,10 @@ import Language.Haskell.TH.Instances as Import ()
import Data.List.NonEmpty.Instances as Import () import Data.List.NonEmpty.Instances as Import ()
import Data.NonNull.Instances as Import () import Data.NonNull.Instances as Import ()
import Data.Monoid.Instances as Import () import Data.Monoid.Instances as Import ()
import Data.Maybe.Instances as Import ()
import Data.CryptoID.Instances as Import ()
import Data.Sum.Instances as Import ()
import Data.Fixed.Instances as Import ()
import Data.Set.Instances as Import () import Data.Set.Instances as Import ()
import Data.HashMap.Strict.Instances as Import () import Data.HashMap.Strict.Instances as Import ()
import Data.HashSet.Instances as Import () import Data.HashSet.Instances as Import ()

View File

@ -16,13 +16,16 @@ import Cron.Types
import Data.Aeson (Value) import Data.Aeson (Value)
import Data.CaseInsensitive (CI) import Data.CaseInsensitive (CI, original)
import Data.CaseInsensitive.Instances () import Data.CaseInsensitive.Instances ()
import Utils.Message (MessageStatus) import Utils.Message (MessageStatus)
import Settings.Cluster (ClusterSettingsKey) import Settings.Cluster (ClusterSettingsKey)
import Text.Blaze (ToMarkup(..))
-- You can define all of your database entities in the entities file. -- You can define all of your database entities in the entities file.
-- You can find more information on persistent and how to declare entities -- You can find more information on persistent and how to declare entities
-- at: -- at:
@ -48,3 +51,17 @@ instance Ord User where
submissionRatingDone :: Submission -> Bool submissionRatingDone :: Submission -> Bool
submissionRatingDone Submission{..} = isJust submissionRatingTime submissionRatingDone Submission{..} = isJust submissionRatingTime
-- ToMarkup and ToMessage instances for displaying selected database primary keys
instance ToMarkup (Key School) where
toMarkup = toMarkup . unSchoolKey
instance ToMessage (Key School) where
toMessage = original . unSchoolKey
instance ToMarkup (Key Term) where
toMarkup = toMarkup . termToText . unTermKey
instance ToMessage (Key Term) where
toMessage = termToText . unTermKey

View File

@ -16,7 +16,6 @@ import qualified Yesod.Auth.Util.PasswordStore as PWStore
type Count = Sum Integer type Count = Sum Integer
type Points = Centi type Points = Centi
type Email = Text type Email = Text
type SchoolName = CI Text type SchoolName = CI Text
@ -34,4 +33,4 @@ type PWHashAlgorithm = ByteString -> PWStore.Salt -> Int -> ByteString
type InstanceId = UUID type InstanceId = UUID
type ClusterId = UUID type ClusterId = UUID
type TokenId = UUID type TokenId = UUID
type TermCandidateIncidence = UUID type TermCandidateIncidence = UUID

View File

@ -45,8 +45,6 @@ seasonFromChar c
where where
(~=) = (==) `on` CI.mk (~=) = (==) `on` CI.mk
-- instance DisplayAble Season
data TermIdentifier = TermIdentifier data TermIdentifier = TermIdentifier
{ year :: Integer -- ^ Using 'Integer' to model years is consistent with 'Data.Time.Calendar' { year :: Integer -- ^ Using 'Integer' to model years is consistent with 'Data.Time.Calendar'
, season :: Season , season :: Season

View File

@ -39,6 +39,6 @@ instance Finite Theme
nullaryPathPiece ''Theme $ camelToPathPiece' 1 nullaryPathPiece ''Theme $ camelToPathPiece' 1
$(deriveSimpleWith ''DisplayAble 'display (over Text.packed $ Text.intercalate " " . unsafeTail . splitCamel) ''Theme) -- describe theme to user $(deriveSimpleWith ''ToMessage 'toMessage (over Text.packed $ Text.intercalate " " . unsafeTail . splitCamel) ''Theme) -- describe theme to user
derivePersistField "Theme" derivePersistField "Theme"

View File

@ -164,13 +164,6 @@ sheetFile2markup SheetHint = iconHint
sheetFile2markup SheetSolution = iconSolution sheetFile2markup SheetSolution = iconSolution
sheetFile2markup SheetMarking = iconMarking sheetFile2markup SheetMarking = iconMarking
-- $(deriveSimpleWith ''DisplayAble 'display (drop 17) ''SheetFileType)
-- instance DisplayAble SheetFileType where -- deprecated, see RenderMessage instance in Foundation
-- display SheetExercise = "Aufgabenstellung"
-- display SheetHint = "Hinweise"
-- display SheetSolution = "Musterlösung"
-- display SheetMarking = "Korrekturhinweise"
-- partitionFileType' :: Ord a => [(SheetFileType,a)] -> Map SheetFileType (Set a) -- partitionFileType' :: Ord a => [(SheetFileType,a)] -> Map SheetFileType (Set a)
-- partitionFileType' = groupMap -- partitionFileType' = groupMap

View File

@ -31,7 +31,6 @@ import Text.Blaze (Markup, ToMarkup)
import Data.Char (isDigit, isSpace, isAscii) import Data.Char (isDigit, isSpace, isAscii)
import Data.Text (dropWhileEnd, takeWhileEnd, justifyRight) import Data.Text (dropWhileEnd, takeWhileEnd, justifyRight)
import Numeric (showFFloat)
import Data.Set (Set) import Data.Set (Set)
import qualified Data.Set as Set import qualified Data.Set as Set
@ -48,9 +47,6 @@ import Control.Monad.Except (MonadError(..))
import Control.Monad.Trans.Maybe as Utils (MaybeT(..)) import Control.Monad.Trans.Maybe as Utils (MaybeT(..))
import Control.Monad.Catch hiding (throwM) import Control.Monad.Catch hiding (throwM)
import qualified Database.Esqueleto as E (Value, unValue)
import Language.Haskell.TH import Language.Haskell.TH
import Language.Haskell.TH.Instances () import Language.Haskell.TH.Instances ()
import Instances.TH.Lift () import Instances.TH.Lift ()
@ -252,63 +248,14 @@ str2widget :: (MonadBaseControl IO m, MonadThrow m, MonadIO m)
=> String -> WidgetT site m () => String -> WidgetT site m ()
str2widget s = [whamlet|#{s}|] str2widget s = [whamlet|#{s}|]
display2widget :: (MonadBaseControl IO m, MonadThrow m, MonadIO m, DisplayAble a)
=> a -> WidgetT site m ()
display2widget = text2widget . display
withFragment :: Monad m => MForm m (a, WidgetT site IO ()) -> Markup -> MForm m (a, WidgetT site IO ()) withFragment :: Monad m => MForm m (a, WidgetT site IO ()) -> Markup -> MForm m (a, WidgetT site IO ())
withFragment form html = flip fmap form $ over _2 (toWidget html >>) withFragment form html = flip fmap form $ over _2 (toWidget html >>)
rationalToFixed :: forall a. HasResolution a => Rational -> Fixed a
rationalToFixed = MkFixed . round . (* (fromIntegral $ resolution (Proxy :: HasResolution a => Proxy a)))
-- Types that can be converted to Text for direct displayed to User! (Show for debugging, Display for Production) rationalToFixed3 :: Rational -> Fixed E3
{- (not so sure we really want to get rid of display?!) DEPRECATED display "Create RenderMessage Instances instead!" -} rationalToFixed3 = rationalToFixed
class DisplayAble a where
display :: a -> Text
-- Default definitions for types belonging to Show (allows empty instance declarations)
default display :: Show a => a -> Text
display = pack . show
instance DisplayAble Text where
display = id
-- instance DisplayAble String where
-- display = pack
instance DisplayAble Int
instance DisplayAble Int64
instance DisplayAble Integer
instance DisplayAble Rational where
display r = showFFloat (Just 2) (rat2float r) ""
& pack
& dropWhileEnd ('0'==)
& dropWhileEnd ('.'==)
where
rat2float :: Rational -> Double
rat2float = fromRational
instance DisplayAble a => DisplayAble (Maybe a) where
display Nothing = ""
display (Just x) = display x
instance DisplayAble a => DisplayAble (E.Value a) where
display = display . E.unValue
instance DisplayAble a => DisplayAble (CI a) where
display = display . CI.original
instance HasResolution a => DisplayAble (Fixed a) where
display = pack . showFixed True
instance DisplayAble a => DisplayAble (Sum a) where
display = display . getSum
{- We do not want DisplayAble for every Show-Class:
We want to explicitly verify that the resulting text can be displayed to the User!
For example: UTCTime values were shown without proper format rendering!
instance {-# OVERLAPPABLE #-} Show a => DisplayAble a where -- The easy way out of UndecidableInstances (TypeFamilies would have been proper, but are much more complicated)
display = pack . show
-}
-- | Convert `part` and `whole` into percentage including symbol -- | Convert `part` and `whole` into percentage including symbol
-- showing trailing zeroes and to decimal digits -- showing trailing zeroes and to decimal digits
@ -326,8 +273,8 @@ textPercent' trailZero precision part whole
| precision == 4 = showPercent (frac :: Micro) | precision == 4 = showPercent (frac :: Micro)
| otherwise = showPercent (frac :: Pico) | otherwise = showPercent (frac :: Pico)
where where
frac :: forall a . HasResolution a => Fixed a frac :: forall a. HasResolution a => Fixed a
frac = MkFixed $ round $ (* (fromInteger $ resolution (Proxy :: Proxy a))) $ (100*) $ toRational part / toRational whole frac = rationalToFixed $ (100*) $ toRational part / toRational whole
showPercent :: HasResolution a => Fixed a -> Text showPercent :: HasResolution a => Fixed a -> Text
showPercent f = pack $ showFixed trailZero f <> "%" showPercent f = pack $ showFixed trailZero f <> "%"

View File

@ -95,9 +95,6 @@ afterN n = do
deriveShowWith :: (String -> String) -> Name -> Q [Dec] deriveShowWith :: (String -> String) -> Name -> Q [Dec]
deriveShowWith = deriveSimpleWith ''Show 'show deriveShowWith = deriveSimpleWith ''Show 'show
-- deriveDisplayWith :: (String -> String) -> Name -> Q [Dec]
-- deriveDisplayWith = deriveSimpleWith ''DisplayAble 'display
deriveSimpleWith :: Name -> Name -> (String -> String) -> Name -> Q [Dec] deriveSimpleWith :: Name -> Name -> (String -> String) -> Name -> Q [Dec]
deriveSimpleWith cls fun strOp ty = do deriveSimpleWith cls fun strOp ty = do
(TyConI tyCon) <- reify ty (TyConI tyCon) <- reify ty

View File

@ -7,8 +7,7 @@ Utils, Utils.*
: Hilfsfunktionionen _unabhängig von Foundation_ : Hilfsfunktionionen _unabhängig von Foundation_
Utils Utils
: Yesod Hilfsfunktionen und Instanzen, Text-HTML-Widget-Konvertierungen : Yesod Hilfsfunktionen und Instanzen, Crud, `NTop`, Utility-Funktionen für `MonadPlus`, `Maybe`,
(`DisplayAble`), Crud, `NTop`, Utility-Funktionen für `MonadPlus`, `Maybe`,
`MaybeT`, `Map`, und Attrs-Lists `MaybeT`, `Map`, und Attrs-Lists
Utils.TH Utils.TH

View File

@ -2,11 +2,11 @@
<table .table .table--striped .table--hover .table--vertical> <table .table .table--striped .table--hover .table--vertical>
<tr .table__row> <tr .table__row>
<th .table__th>_{MsgSubmission} <th .table__th>_{MsgSubmission}
<td .table__td>#{display cid} <td .table__td>#{cid}
$maybe Entity _ User{userDisplayName} <- corrector $maybe Entity _ User{userDisplayName} <- corrector
<tr .table__row> <tr .table__row>
<th .table__th>_{MsgRatingBy} <th .table__th>_{MsgRatingBy}
<td .table__td>#{display userDisplayName} <td .table__td>#{userDisplayName}
$maybe time <- submissionRatingTime $maybe time <- submissionRatingTime
<tr .table__row> <tr .table__row>
<th .table__th>_{MsgRatingTime} <th .table__th>_{MsgRatingTime}

View File

@ -80,7 +80,7 @@
<td .table__td .heated style="--hotness: #{heat ciSubmissionsNr ciCorrected}">#{ciSubmissionsNr - ciCorrected} <td .table__td .heated style="--hotness: #{heat ciSubmissionsNr ciCorrected}">#{ciSubmissionsNr - ciCorrected}
<td .table__td> <td .table__td>
$maybe deficit <- getCorrDeficit ciCorrector $maybe deficit <- getCorrDeficit ciCorrector
#{display deficit} #{rationalToFixed3 deficit}
<td .table__td>#{showDiffDays ciMin} <td .table__td>#{showDiffDays ciMin}
<td .table__td>#{showAvgsDays ciTot ciCorrected} <td .table__td>#{showAvgsDays ciTot ciCorrected}
<td .table__td>#{showDiffDays ciMax} <td .table__td>#{showDiffDays ciMax}

View File

@ -38,7 +38,7 @@
<td .table__td>_{field}#{notUsedT studyFeaturesField} <td .table__td>_{field}#{notUsedT studyFeaturesField}
<td .table__td>_{degree}#{notUsedT studyFeaturesDegree} <td .table__td>_{degree}#{notUsedT studyFeaturesDegree}
<td .table__td>_{studyFeaturesType} <td .table__td>_{studyFeaturesType}
<td .table__td>#{display studyFeaturesSemester} <td .table__td>#{studyFeaturesSemester}
<td .table__td>#{hasTickmark studyFeaturesValid} <td .table__td>#{hasTickmark studyFeaturesValid}
<td .table__td>^{formatTimeW SelFormatDate studyFeaturesUpdated} <td .table__td>^{formatTimeW SelFormatDate studyFeaturesUpdated}
$maybe _ <- mRegistration $maybe _ <- mRegistration

View File

@ -6,13 +6,13 @@
<div .container> <div .container>
#{mailtoHtml userEmail} #{mailtoHtml userEmail}
<div .container> <div .container>
#{display deletedSubmissions} Abgaben wurden unwiederruflich gelöscht. #{deletedSubmissions} Abgaben wurden unwiederruflich gelöscht.
$if groupSubmissions > 0 $if groupSubmissions > 0
<div .container> <div .container>
#{display groupSubmissions} Gruppenabgaben verbleiben in der Datenbank, #{groupSubmissions} Gruppenabgaben verbleiben in der Datenbank,
aber die Zuordnung zum Benutzer wurden gelöscht. aber die Zuordnung zum Benutzer wurden gelöscht.
Gruppenabgaben können dadurch zu Einzelabgaben werden, Gruppenabgaben können dadurch zu Einzelabgaben werden,
welche dann vom letzten Benutzer gelöscht werden können. welche dann vom letzten Benutzer gelöscht werden können.
$if deletedSubmissionGroups > 0 $if deletedSubmissionGroups > 0
<div .container> <div .container>
#{display deletedSubmissionGroups} benannte Abgabengruppen wurden gelöscht, da diese dadurch leer wurden. #{deletedSubmissionGroups} benannte Abgabengruppen wurden gelöscht, da diese dadurch leer wurden.

View File

@ -22,12 +22,12 @@ $newline never
_{MsgSubmission} _{MsgSubmission}
<dd> <dd>
<a href=@{CSubmissionR tid ssh csh shn csid SubShowR}> <a href=@{CSubmissionR tid ssh csh shn csid SubShowR}>
#{display csid} #{csid}
$maybe User{userDisplayName} <- corrector $maybe User{userDisplayName} <- corrector
<dt> <dt>
_{MsgRatingBy} _{MsgRatingBy}
<dd> <dd>
#{display userDisplayName} #{userDisplayName}
$maybe time <- submissionRatingTime' $maybe time <- submissionRatingTime'
<dt> <dt>
_{MsgRatingTime} _{MsgRatingTime}

View File

@ -9,7 +9,7 @@
<dt .deflist__dt> _{MsgEMail} <dt .deflist__dt> _{MsgEMail}
<dd .deflist__dd> #{mailtoHtml userEmail} <dd .deflist__dd> #{mailtoHtml userEmail}
<dt .deflist__dt> _{MsgIdent} <dt .deflist__dt> _{MsgIdent}
<dd .deflist__dd> #{display userIdent} <dd .deflist__dd> #{userIdent}
<dt .deflist__dt> _{MsgLastLogin} <dt .deflist__dt> _{MsgLastLogin}
<dd .deflist__dd> <dd .deflist__dd>
$maybe llogin <- lastLogin $maybe llogin <- lastLogin
@ -23,7 +23,7 @@
$forall (E.Value institute) <- admin_rights $forall (E.Value institute) <- admin_rights
<li .list-ul__item> <li .list-ul__item>
<a href=@{SchoolShowR $ SchoolKey institute}> <a href=@{SchoolShowR $ SchoolKey institute}>
#{display institute} #{institute}
$if not $ null lecturer_rights $if not $ null lecturer_rights
<dt .deflist__dt>_{MsgLecturerFor} <dt .deflist__dt>_{MsgLecturerFor}
<dd .deflist__dd> <dd .deflist__dd>
@ -31,14 +31,14 @@
$forall (E.Value institute) <- lecturer_rights $forall (E.Value institute) <- lecturer_rights
<li .list-ul__item> <li .list-ul__item>
<a href=@{SchoolShowR $ SchoolKey institute}> <a href=@{SchoolShowR $ SchoolKey institute}>
#{display institute} #{institute}
$if not $ null lecture_corrector $if not $ null lecture_corrector
<dt .deflist__dt> Korrektor <dt .deflist__dt> Korrektor
<dd .deflist__dd> <dd .deflist__dd>
<ul .list-ul> <ul .list-ul>
$forall (E.Value tid, E.Value ssh, E.Value csh) <- lecture_corrector $forall (E.Value tid, E.Value ssh, E.Value csh) <- lecture_corrector
<li .list-ul__item> <li .list-ul__item>
<a href=@{CourseR tid ssh csh CShowR}>#{display tid}-#{display ssh}-#{display csh} <a href=@{CourseR tid ssh csh CShowR}>#{tid}-#{ssh}-#{csh}
$if not $ null studies $if not $ null studies
<dt .deflist__dt> Studiengänge <dt .deflist__dt> Studiengänge
<dd .deflist__dd> <dd .deflist__dd>
@ -58,7 +58,7 @@
<td .table__td>_{field}#{notUsedT studyFeaturesField} <td .table__td>_{field}#{notUsedT studyFeaturesField}
<td .table__td>_{degree}#{notUsedT studyFeaturesDegree} <td .table__td>_{degree}#{notUsedT studyFeaturesDegree}
<td .table__td>_{studyFeaturesType} <td .table__td>_{studyFeaturesType}
<td .table__td>#{display studyFeaturesSemester} <td .table__td>#{studyFeaturesSemester}
<td .table__td>#{hasTickmark studyFeaturesValid} <td .table__td>#{hasTickmark studyFeaturesValid}
<td .table__td>^{formatTimeW SelFormatDateTime studyFeaturesUpdated} <td .table__td>^{formatTimeW SelFormatDateTime studyFeaturesUpdated}

View File

@ -20,7 +20,7 @@ $maybe cID <- mcid
$maybe name <- mbName $maybe name <- mbName
<li>_{MsgEditedBy name time} <li>_{MsgEditedBy name time}
$nothing $nothing
<li>#{display time} <li>#{time}
$if maySubmit $if maySubmit
<section> <section>

View File

@ -21,7 +21,7 @@ $#
$if pmax > 0 $if pmax > 0
#{textPercent pacv pmax} #{textPercent pacv pmax}
<td .table__td> <td .table__td>
#{display pacv} / #{display pmax} _{pacv} / _{pmax}
$else $else
<td .table__td> <td .table__td>
<td .table__td> <td .table__td>
@ -29,7 +29,7 @@ $#
$with Sum numPass <- summary ^. _numSheetsPasses $with Sum numPass <- summary ^. _numSheetsPasses
<td .table__td> <td .table__td>
$if numPass > 0 $if numPass > 0
#{display numPass} _{numPass}
$maybe _ <- hasMarkedPoints $maybe _ <- hasMarkedPoints
$with Sum pmax <- summary ^. _sumMarkedPoints $with Sum pmax <- summary ^. _sumMarkedPoints
$with Sum pacv <- summary ^. _achievedPoints $with Sum pacv <- summary ^. _achievedPoints
@ -37,18 +37,18 @@ $#
$if pmax > 0 $if pmax > 0
#{textPercent pacv pmax} #{textPercent pacv pmax}
<td .table__td> <td .table__td>
#{display pacv} / #{display pmax} _{pacv} / _{pmax}
$if ((summary ^. _numMarkedPoints) /= (summary ^. _numSheets)) $if ((summary ^. _numMarkedPoints) /= (summary ^. _numSheets))
$# Falls Anzahl Blätter der Zeile verschieden von Anzahl gewerterer Blätter $# Falls Anzahl Blätter der Zeile verschieden von Anzahl gewerterer Blätter
\ (_{title $ getSum $ summary ^. _numMarkedPoints}) \ (_{title $ getSum $ summary ^. _numMarkedPoints})
$# Kurze Alternative mit Hashtag-Symbol für "Anzahl" $# Kurze Alternative mit Hashtag-Symbol für "Anzahl"
$# \ (##{display $ summary ^. _numMarkedPoints}) $# \ (##{summary ^. _numMarkedPoints})
$maybe _ <- hasPoints $maybe _ <- hasPoints
<td .table__td> <td .table__td>
#{display (summary ^. _sumSheetsPoints)} #{summary ^. _sumSheetsPoints}
$if ((summary ^. _numSheetsPoints) /= (summary ^. _numSheets)) $if ((summary ^. _numSheetsPoints) /= (summary ^. _numSheets))
$# Falls Anzahl Blätter der Zeile verschieden von Anzahl Blätter mit Punkten $# Falls Anzahl Blätter der Zeile verschieden von Anzahl Blätter mit Punkten
\ (_{title $ getSum $ summary ^. _numSheetsPoints}) \ (_{title $ getSum $ summary ^. _numSheetsPoints})
$# Kurze Alternative mit Hashtag-Symbol für "Anzahl" $# Kurze Alternative mit Hashtag-Symbol für "Anzahl"
$# \ (##{display $ summary ^. _numSheetsPoints}) $# \ (##{summary ^. _numSheetsPoints})
<td .table__td>#{display $ summary ^. _numSheets} <td .table__td>#{summary ^. _numSheets}

View File

@ -176,6 +176,24 @@ fillDb = do
, userMailLanguages = MailLanguages ["de"] , userMailLanguages = MailLanguages ["de"]
, userNotificationSettings = def , userNotificationSettings = def
} }
svaupel <- insert User
{ userIdent = "vaupel.sarah@campus.lmu.de"
, userAuthentication = AuthLDAP
, userLastAuthentication = Nothing
, userTokensIssuedAfter = Nothing
, userMatrikelnummer = Nothing
, userEmail = "vaupel.sarah@campus.lmu.de"
, userDisplayName = "Sarah Vaupel"
, userSurname = "Vaupel"
, userMaxFavourites = 14
, userTheme = ThemeMossGreen
, userDateTimeFormat = userDefaultDateTimeFormat
, userDateFormat = userDefaultDateFormat
, userTimeFormat = userDefaultTimeFormat
, userDownloadFiles = userDefaultDownloadFiles
, userMailLanguages = MailLanguages ["de"]
, userNotificationSettings = def
}
void . repsert (TermKey summer2017) $ Term void . repsert (TermKey summer2017) $ Term
{ termName = summer2017 { termName = summer2017
, termStart = fromGregorian 2017 04 09 , termStart = fromGregorian 2017 04 09
@ -210,9 +228,12 @@ fillDb = do
void . insert' $ UserAdmin fhamann ifi void . insert' $ UserAdmin fhamann ifi
void . insert' $ UserAdmin jost ifi void . insert' $ UserAdmin jost ifi
void . insert' $ UserAdmin jost mi void . insert' $ UserAdmin jost mi
void . insert' $ UserAdmin svaupel ifi
void . insert' $ UserAdmin svaupel mi
void . insert' $ UserLecturer gkleen ifi void . insert' $ UserLecturer gkleen ifi
void . insert' $ UserLecturer fhamann ifi void . insert' $ UserLecturer fhamann ifi
void . insert' $ UserLecturer jost ifi void . insert' $ UserLecturer jost ifi
void . insert' $ UserLecturer svaupel ifi
let let
sdBsc = StudyDegreeKey' 82 sdBsc = StudyDegreeKey' 82
sdMst = StudyDegreeKey' 88 sdMst = StudyDegreeKey' 88