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:
commit
aae9fbc3a9
1
.gitignore
vendored
1
.gitignore
vendored
@ -34,3 +34,4 @@ src/Handler/Course.SnapCustom.hs
|
||||
.directory
|
||||
tags
|
||||
test.log
|
||||
*.dump-splices
|
||||
|
||||
@ -41,18 +41,18 @@ GenericAvg: Avg
|
||||
GenericMax: Max
|
||||
GenericAll: Insgesamt
|
||||
|
||||
SummerTerm year@Integer: Sommersemester #{display year}
|
||||
WinterTerm year@Integer: Wintersemester #{display year}/#{display $ succ year}
|
||||
SummerTermShort year@Integer: SoSe #{display year}
|
||||
WinterTermShort year@Integer: WiSe #{display year}/#{display $ mod (succ year) 100}
|
||||
SummerTerm year@Integer: Sommersemester #{year}
|
||||
WinterTerm year@Integer: Wintersemester #{year}/#{succ year}
|
||||
SummerTermShort year@Integer: SoSe #{year}
|
||||
WinterTermShort year@Integer: WiSe #{year}/#{mod (succ year) 100}
|
||||
PSLimitNonPositive: “pagesize” muss größer als null sein
|
||||
Page num@Int64: #{display num}
|
||||
Page num@Int64: #{num}
|
||||
|
||||
TermsHeading: Semesterübersicht
|
||||
TermCurrent: Aktuelles Semester
|
||||
TermEditHeading: Semester editieren/anlegen
|
||||
TermEditTid tid@TermId: Semester #{display tid} editieren
|
||||
TermEdited tid@TermId: Semester #{display tid} erfolgreich editiert.
|
||||
TermEditTid tid@TermId: Semester #{tid} editieren
|
||||
TermEdited tid@TermId: Semester #{tid} erfolgreich editiert.
|
||||
TermNewTitle: Semester editieren/anlegen.
|
||||
InvalidInput: Eingaben bitte korrigieren.
|
||||
Term: Semester
|
||||
@ -91,23 +91,23 @@ CourseTutorial: Tutorium
|
||||
CourseStudyFeatureTooltip: Korrekte Angabe kann Notenweiterleitungen beschleunigen
|
||||
CourseSecretWrong: Falsches Kennwort
|
||||
CourseSecret: Zugangspasswort
|
||||
CourseEditOk tid@TermId ssh@SchoolId csh@CourseShorthand: Kurs #{display tid}-#{display 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.
|
||||
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.
|
||||
CourseEditOk tid@TermId ssh@SchoolId csh@CourseShorthand: Kurs #{tid}-#{ssh}-#{csh} wurde erfolgreich geändert.
|
||||
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 #{tid}-#{ssh}-#{csh} konnte nicht geändert werden: Es gibt bereits einen anderen Kurs mit dem Kürzel #{csh} in diesem Semester.
|
||||
FFSheetName: Name
|
||||
TermCourseListHeading tid@TermId: Kursübersicht #{display tid}
|
||||
TermSchoolCourseListHeading tid@TermId school@SchoolName: Kursübersicht #{display tid} für #{school}
|
||||
TermCourseListHeading tid@TermId: Kursübersicht #{tid}
|
||||
TermSchoolCourseListHeading tid@TermId school@SchoolName: Kursübersicht #{tid} für #{school}
|
||||
CourseListTitle: Alle Kurse
|
||||
TermCourseListTitle tid@TermId: Kurse #{display tid}
|
||||
TermSchoolCourseListTitle tid@TermId school@SchoolName: Kurse #{display tid} für #{school}
|
||||
TermCourseListTitle tid@TermId: Kurse #{tid}
|
||||
TermSchoolCourseListTitle tid@TermId school@SchoolName: Kurse #{tid} für #{school}
|
||||
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
|
||||
CourseMembers: Teilnehmer
|
||||
CourseMemberOf: Teilnehmer
|
||||
CourseMembersCount n@Int: #{display n}
|
||||
CourseMembersCountLimited n@Int max@Int: #{display n}/#{display max}
|
||||
CourseMembersCountOf n@Int mbNum@IntMaybe: #{display n} Anmeldungen #{maybeDisplay " von " mbNum " möglichen"}
|
||||
CourseMembersCount n@Int: #{n}
|
||||
CourseMembersCountLimited n@Int max@Int: #{n}/#{max}
|
||||
CourseMembersCountOf n@Int mbNum@IntMaybe: #{n} Anmeldungen #{maybeToMessage " von " mbNum " möglichen"}
|
||||
CourseName: Name
|
||||
CourseDescription: Beschreibung
|
||||
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
|
||||
CourseLecturerRightsIdentical: Alle Sorten von Kursverwalter haben identische Rechte.
|
||||
|
||||
NoSuchTerm tid@TermId: Semester #{display tid} gibt es nicht.
|
||||
NoSuchSchool ssh@SchoolId: Institut #{display ssh} gibt es nicht.
|
||||
NoSuchTerm tid@TermId: Semester #{tid} gibt es nicht.
|
||||
NoSuchSchool ssh@SchoolId: Institut #{ssh} gibt es nicht.
|
||||
NoSuchCourseShorthand csh@CourseShorthand: Kein Kurs mit Kürzel #{csh} bekannt.
|
||||
NoSuchCourse: Keinen passenden Kurs gefunden.
|
||||
|
||||
Sheet: Blatt
|
||||
SheetList tid@TermId ssh@SchoolId csh@CourseShorthand: #{display tid}-#{display ssh}-#{csh} Übersicht Übungsblätter
|
||||
SheetNewHeading tid@TermId ssh@SchoolId csh@CourseShorthand: #{display tid}-#{display 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.
|
||||
SheetTitle tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{display tid}-#{display ssh}-#{csh} #{sheetName}
|
||||
SheetTitleNew tid@TermId ssh@SchoolId csh@CourseShorthand : #{display tid}-#{display ssh}-#{csh}: Neues Übungsblatt
|
||||
SheetEditHead tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{display tid}-#{display ssh}-#{csh} #{sheetName} editieren
|
||||
SheetEditOk tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: Übungsblatt #{sheetName} wurde gespeichert in Kurs #{display tid}-#{display 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}
|
||||
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!
|
||||
SheetDelOk tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{display tid}-#{display ssh}-#{csh}: #{sheetName} gelöscht.
|
||||
SheetDelHasSubmissions objs@Int: Inkl. #{tshow objs} #{pluralDE objs "Abgabe" "Abgaben"}!
|
||||
SheetList tid@TermId ssh@SchoolId csh@CourseShorthand: #{tid}-#{ssh}-#{csh} Übersicht Übungsblätter
|
||||
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 #{tid}-#{ssh}-#{csh} erfolgreich erstellt.
|
||||
SheetTitle tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{tid}-#{ssh}-#{csh} #{sheetName}
|
||||
SheetTitleNew tid@TermId ssh@SchoolId csh@CourseShorthand : #{tid}-#{ssh}-#{csh}: Neues Übungsblatt
|
||||
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 #{tid}-#{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 #{tid}-#{ssh}-#{csh} herauslöschen? Alle assoziierten Abgaben und Korrekturen gehen ebenfalls verloren!
|
||||
SheetDelOk tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName: #{tid}-#{ssh}-#{csh}: #{sheetName} gelöscht.
|
||||
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?
|
||||
SheetDeleted: Übungsblatt gelöscht
|
||||
@ -209,12 +209,12 @@ Deadline: Abgabe
|
||||
Done: Eingereicht
|
||||
|
||||
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}
|
||||
SubmissionWrongSheet: Abgabenummer gehört nicht zum angegebenen Ü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
|
||||
CorrectionHead tid@TermId ssh@SchoolId csh@CourseShorthand sheetName@SheetName cid@CryptoFileNameSubmission: #{display tid}-#{display ssh}-#{csh} #{sheetName}: Korrektur
|
||||
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: #{tid}-#{ssh}-#{csh} #{sheetName}: Korrektur
|
||||
SubmissionMembers: Abgebende
|
||||
SubmissionMember: Abgebende(r)
|
||||
SubmissionArchive: Zip-Archiv der Abgabedatei(en)
|
||||
@ -253,10 +253,10 @@ MaterialNewHeading: Neues Material veröffentlichen
|
||||
MaterialNewTitle: Neues Material
|
||||
MaterialEditHeading 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}
|
||||
MaterialNameDup tid@TermId ssh@SchoolId csh@CourseShorthand materialName@MaterialName: Es gibt bereits Material mit Namen "#{materialName}" in diesem 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 #{tid}-#{ssh}-#{csh}
|
||||
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.
|
||||
MaterialDeleted materialName@MaterialName: Material "#{materialName}" gelöscht
|
||||
|
||||
@ -310,12 +310,12 @@ UnauthorizedTutorialRegisterGroup: Sie sind bereits in einem Tutorium mit dersel
|
||||
|
||||
EMail: E-Mail
|
||||
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
|
||||
|
||||
AddCorrector: Zusätzlicher Korrektor
|
||||
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
|
||||
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
|
||||
@ -325,11 +325,11 @@ CorState: Status
|
||||
CorByTut: Zuteilung nach Tutorium
|
||||
CorProportion: Anteil
|
||||
CorDeficitProportion: Defizit Anteile
|
||||
CorByProportionOnly proportion@Rational: #{display proportion} Anteile
|
||||
CorByProportionIncludingTutorial proportion@Rational: #{display proportion} Anteile - Tutorium
|
||||
CorByProportionExcludingTutorial proportion@Rational: #{display proportion} Anteile + Tutorium
|
||||
CorByProportionOnly proportion@Rational: #{rationalToFixed3 proportion} Anteile
|
||||
CorByProportionIncludingTutorial proportion@Rational: #{rationalToFixed3 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
|
||||
ProportionNegative: Anteile dürfen nicht negativ sein
|
||||
CorrectorUpdated: Korrektor erfolgreich aktualisiert
|
||||
@ -357,7 +357,7 @@ TokensResetSuccess: Authorisierungs-Tokens invalidiert
|
||||
HomeOpenCourses: Kurse mit offener Registrierung
|
||||
HomeUpcomingSheets: Anstehende Übungsblätter
|
||||
|
||||
NumCourses num@Int64: #{display num} Kurse
|
||||
NumCourses num@Int64: #{num} Kurse
|
||||
CloseAlert: Schliessen
|
||||
|
||||
Name: Name
|
||||
@ -394,23 +394,23 @@ NatField name@Text: #{name} muss eine natürliche Zahl sein!
|
||||
JSONFieldDecodeFailure aesonFailure@String: Konnte JSON nicht parsen: #{aesonFailure}
|
||||
SecretJSONFieldDecryptFailure: Konnte versteckte vertrauliche Daten nicht entschlüsseln
|
||||
|
||||
SubmissionsAlreadyAssigned num@Int64: #{display 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):
|
||||
UpdatedAssignedCorrectorSingle num@Int64: #{display num} Abgaben wurden dem neuen Korrektor zugeteilt.
|
||||
SubmissionsAlreadyAssigned num@Int64: #{num} Abgaben waren bereits einem Korrektor zugeteilt und wurden nicht verändert:
|
||||
SubmissionsAssignUnauthorized num@Int64: #{num} Abgaben können momentan nicht einem Korrektor zugeteilt werden (z.B. weil die Abgabe noch offen ist):
|
||||
UpdatedAssignedCorrectorSingle num@Int64: #{num} Abgaben wurden dem neuen Korrektor zugeteilt.
|
||||
NoCorrector: Kein Korrektor
|
||||
RemovedCorrections num@Int64: Korrektur-Daten wurden von #{display num} Abgaben entfernt.
|
||||
UpdatedAssignedCorrectorsAuto num@Int64: #{display num} Abgaben wurden unter den Korrektoren aufgeteilt.
|
||||
UpdatedSheetCorrectorsAutoAssigned n@Int: #{display 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.
|
||||
CouldNotAssignCorrectorsAuto num@Int64: #{display num} Abgaben konnten nicht automatisch zugewiesen werden:
|
||||
SelfCorrectors num@Int64: #{display num} Abgaben wurden Abgebenden als eigenem Korrektor zugeteilt!
|
||||
RemovedCorrections num@Int64: Korrektur-Daten wurden von #{num} Abgaben entfernt.
|
||||
UpdatedAssignedCorrectorsAuto num@Int64: #{num} Abgaben wurden unter den Korrektoren aufgeteilt.
|
||||
UpdatedSheetCorrectorsAutoAssigned n@Int: #{n} #{pluralDE n "Abgabe wurde einem Korrektor" "Abgaben wurden Korrektoren"} zugteilt.
|
||||
UpdatedSheetCorrectorsAutoFailed n@Int: #{n} #{pluralDE n "Abgabe konnte" "Abgaben konnten"} nicht automatisch zugewiesen werden.
|
||||
CouldNotAssignCorrectorsAuto num@Int64: #{num} Abgaben konnten nicht automatisch zugewiesen werden:
|
||||
SelfCorrectors num@Int64: #{num} Abgaben wurden Abgebenden als eigenem Korrektor zugeteilt!
|
||||
|
||||
|
||||
CorrectionSheets: Übersicht Korrekturen nach Blättern
|
||||
CorrectionCorrectors: Übersicht Korrekturen nach Korrektoren
|
||||
AssignSubmissionExceptionNoCorrectors: Es sind keine Korrektoren 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
|
||||
NrSubmissionsTotal: Abgaben
|
||||
NrSubmissionsTotalShort: Abg.
|
||||
@ -424,7 +424,7 @@ NrSubmissionsNotCorrectedShort: Unkg.
|
||||
CorrectionTime: Korrekturdauer
|
||||
AssignSubmissionsRandomWarning: Die Zuteilungsvorschau kann von der tatsächlichen Zuteilung abweichen, wenn mehrere Blätter auf einmal zugeteilt werden, da beim Ausgleich der Kontigente nur bereits zugeteilte Abgaben berücksichtigt werden. Da es ein randomisierte Prozess ist, kann es auch bei einzelnen Blättern gerinfgügige Abweichungen geben.
|
||||
|
||||
CorrectionsUploaded num@Int64: #{display num} Korrekturen wurden gespeichert:
|
||||
CorrectionsUploaded num@Int64: #{num} Korrekturen wurden gespeichert:
|
||||
NoCorrectionsUploaded: In der hochgeladenen Datei wurden keine Korrekturen gefunden.
|
||||
|
||||
RatingBy: Korrigiert von
|
||||
@ -433,8 +433,8 @@ AssignedTime: Zuteilung
|
||||
AchievedBonusPoints: Erreichte Bonuspunkte
|
||||
AchievedNormalPoints: Erreichte Punkte
|
||||
AchievedPassPoints: Erreichte Punkte
|
||||
AchievedOf achieved@Points possible@Points: #{display achieved} von #{display possible}
|
||||
PassAchievedOf points@Points passingPoints@Points maxPoints@Points: #{display points} von #{display maxPoints} (Bestanden ab #{display passingPoints})
|
||||
AchievedOf achieved@Points possible@Points: #{achieved} von #{possible}
|
||||
PassAchievedOf points@Points passingPoints@Points maxPoints@Points: #{points} von #{maxPoints} (Bestanden ab #{passingPoints})
|
||||
PassedResult: Ergebnis
|
||||
Passed: Bestanden
|
||||
NotPassed: Nicht bestanden
|
||||
@ -447,7 +447,7 @@ RatingDone: Bewertung sichtbar
|
||||
RatingPercent: Erreicht
|
||||
RatingFiles: Korrigierte Dateien
|
||||
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
|
||||
ColumnRatingPoints: Punktzahl
|
||||
Pseudonyms: Pseudonyme
|
||||
@ -527,7 +527,7 @@ LastEdit: Letzte Änderung
|
||||
LastEditByUser: Ihre letzte Bearbeitung
|
||||
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}.
|
||||
|
||||
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.
|
||||
|
||||
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}
|
||||
DayIsOutOfTerm tid@TermId name@Text date@Text: "#{name}" (#{date}) liegt nicht im Semester #{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 #{tid}
|
||||
|
||||
UploadModeNone: Kein Upload
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
MailUserRightsIntro name@Text email@UserEmail: #{name} <#{email}> hat folgende Uni2work Berechtigungen:
|
||||
@ -644,22 +644,22 @@ MailSubjectSupport: Supportanfrage
|
||||
MailSubjectSupportCustom customSubject@Text: [Support] #{customSubject}
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
SheetGradingPoints maxPoints@Points: #{tshow maxPoints} Punkte
|
||||
SheetGradingPassPoints maxPoints@Points passingPoints@Points: Bestanden ab #{tshow passingPoints} von #{tshow maxPoints} Punkten
|
||||
SheetGradingPoints maxPoints@Points: #{maxPoints} Punkte
|
||||
SheetGradingPassPoints maxPoints@Points passingPoints@Points: Bestanden ab #{passingPoints} von #{maxPoints} Punkten
|
||||
SheetGradingPassBinary: Bestanden/Nicht Bestanden
|
||||
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.
|
||||
SheetGradingBonusIncluded: Erzielte Bonuspunkte wurden hier bereits zu den erreichten normalen Punkten hinzugezählt.
|
||||
SummaryTitle: Zusammenfassung über
|
||||
SheetGradingSummaryTitle intgr@Integer: #{display intgr} #{pluralDE intgr "Blatt" "Blätter"}
|
||||
SubmissionGradingSummaryTitle intgr@Integer: #{display intgr} #{pluralDE intgr "Abgabe" "Abgaben"}
|
||||
SheetGradingSummaryTitle intgr@Integer: #{intgr} #{pluralDE intgr "Blatt" "Blätter"}
|
||||
SubmissionGradingSummaryTitle intgr@Integer: #{intgr} #{pluralDE intgr "Abgabe" "Abgaben"}
|
||||
|
||||
SheetTypeBonus': Bonus
|
||||
SheetTypeNormal': Normal
|
||||
@ -910,8 +910,8 @@ CommSubject: Betreff
|
||||
CommBody: Nachricht
|
||||
CommRecipients: Empfänger
|
||||
CommRecipientsTip: Sie selbst erhalten immer eine Kopie der Nachricht
|
||||
CommDuplicateRecipients n@Int: #{tshow n} #{pluralDE n "doppelter" "doppelte"} Empfänger ignoriert
|
||||
CommSuccess n@Int: Nachricht wurde an #{tshow n} Empfänger versandt
|
||||
CommDuplicateRecipients n@Int: #{n} #{pluralDE n "doppelter" "doppelte"} Empfänger ignoriert
|
||||
CommSuccess n@Int: Nachricht wurde an #{n} Empfänger versandt
|
||||
|
||||
CommCourseHeading: Kursmitteilung
|
||||
CommTutorialHeading: Tutorium-Mitteilung
|
||||
@ -1008,7 +1008,7 @@ TutorialDelete: Löschen
|
||||
CourseExams: Klausuren
|
||||
CourseTutorials: Übungen
|
||||
|
||||
ParticipantsN n@Int: #{tshow n} Teilnehmer
|
||||
ParticipantsN n@Int: #{n} Teilnehmer
|
||||
TutorialDeleteQuestion: Wollen Sie das unten aufgeführte Tutorium wirklich löschen?
|
||||
TutorialDeleted: Tutorium gelöscht
|
||||
|
||||
@ -1045,11 +1045,11 @@ HealthLDAPAdmins: Anteil der Administratoren, die im LDAP-Verzeichnis gefunden w
|
||||
HealthSMTPConnect: SMTP-Server kann erreicht werden
|
||||
HealthWidgetMemcached: Memcached-Server liefert Widgets korrekt aus
|
||||
|
||||
CourseParticipants n@Int: Derzeit #{tshow n} angemeldete Kursteilnehmer
|
||||
CourseParticipantsInvited n@Int: #{tshow n} #{pluralDE n "Einladung" "Einladungen"} per E-Mail verschickt
|
||||
CourseParticipantsAlreadyRegistered n@Int: #{tshow 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"}
|
||||
CourseParticipantsRegistered n@Int: #{tshow n} Teilnehmer erfolgreich angemeldet
|
||||
CourseParticipants n@Int: Derzeit #{n} angemeldete Kursteilnehmer
|
||||
CourseParticipantsInvited n@Int: #{n} #{pluralDE n "Einladung" "Einladungen"} per E-Mail verschickt
|
||||
CourseParticipantsAlreadyRegistered n@Int: #{n} Teilnehmer #{pluralDE n "ist" "sind"} bereits angemeldet
|
||||
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: #{n} Teilnehmer erfolgreich angemeldet
|
||||
CourseParticipantsRegisterHeading: Kursteilnehmer hinzufügen
|
||||
|
||||
ExamName: Name
|
||||
@ -1164,4 +1164,4 @@ ExamClosedMustBeAfterStart: "Noten stehen fest ab" muss nach Start liegen
|
||||
ExamClosedMustBeAfterEnd: "Noten stehen fest ab" muss nach Ende liegen
|
||||
|
||||
VersionHistory: Versionsgeschichte
|
||||
KnownBugs: Bekannte Bugs
|
||||
KnownBugs: Bekannte Bugs
|
||||
|
||||
82
package-lock.json
generated
82
package-lock.json
generated
@ -5919,7 +5919,8 @@
|
||||
"ansi-regex": {
|
||||
"version": "2.1.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
@ -5940,12 +5941,14 @@
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@ -5960,17 +5963,20 @@
|
||||
"code-point-at": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
@ -6087,7 +6093,8 @@
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
@ -6099,6 +6106,7 @@
|
||||
"version": "1.0.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
@ -6113,6 +6121,7 @@
|
||||
"version": "3.0.4",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
@ -6120,12 +6129,14 @@
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.3.5",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.2",
|
||||
"yallist": "^3.0.0"
|
||||
@ -6144,6 +6155,7 @@
|
||||
"version": "0.5.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
@ -6224,7 +6236,8 @@
|
||||
"number-is-nan": {
|
||||
"version": "1.0.1",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
@ -6236,6 +6249,7 @@
|
||||
"version": "1.4.0",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
@ -6321,7 +6335,8 @@
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
@ -6357,6 +6372,7 @@
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
@ -6376,6 +6392,7 @@
|
||||
"version": "3.0.1",
|
||||
"bundled": true,
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
@ -6419,12 +6436,14 @@
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.3",
|
||||
"bundled": true,
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -12465,47 +12484,6 @@
|
||||
"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": {
|
||||
"version": "3.3.3",
|
||||
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
|
||||
|
||||
14
src/Data/CryptoID/Instances.hs
Normal file
14
src/Data/CryptoID/Instances.hs
Normal 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
|
||||
13
src/Data/Fixed/Instances.hs
Normal file
13
src/Data/Fixed/Instances.hs
Normal 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
|
||||
13
src/Data/Maybe/Instances.hs
Normal file
13
src/Data/Maybe/Instances.hs
Normal 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
13
src/Data/Sum/Instances.hs
Normal 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
|
||||
@ -21,10 +21,7 @@ import qualified Network.Wai as W (pathInfo)
|
||||
|
||||
import Yesod.Core.Types (Logger)
|
||||
import qualified Yesod.Core.Unsafe as Unsafe
|
||||
import Data.CaseInsensitive (CI)
|
||||
import qualified Data.CaseInsensitive as CI
|
||||
|
||||
import qualified Data.CryptoID as E
|
||||
import Data.CaseInsensitive (original, mk)
|
||||
|
||||
import Data.ByteArray (convert)
|
||||
import Crypto.Hash (Digest, SHAKE256, SHAKE128)
|
||||
@ -91,18 +88,6 @@ import qualified Data.Aeson as JSON
|
||||
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
|
||||
|
||||
-- infixl 9 :$:
|
||||
@ -225,9 +210,9 @@ type IntMaybe = Maybe Int
|
||||
type TextList = [Text]
|
||||
|
||||
-- | Convenience function for i18n messages definitions
|
||||
maybeDisplay :: DisplayAble m => Text -> Maybe m -> Text -> Text
|
||||
maybeDisplay _ Nothing _ = mempty
|
||||
maybeDisplay before (Just x) after = before <> (display x) <> after
|
||||
maybeToMessage :: ToMessage m => Text -> Maybe m -> Text -> Text
|
||||
maybeToMessage _ Nothing _ = mempty
|
||||
maybeToMessage before (Just x) after = before <> (toMessage x) <> after
|
||||
|
||||
-- Messages creates type UniWorXMessage and RenderMessage UniWorX instance
|
||||
mkMessage "UniWorX" "messages/uniworx" "de"
|
||||
@ -259,6 +244,17 @@ instance RenderMessage UniWorX ShortTermIdentifier where
|
||||
instance RenderMessage UniWorX String where
|
||||
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
|
||||
renderMessage foundation ls = renderMessage foundation ls . \case
|
||||
(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
|
||||
|
||||
|
||||
-- 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
|
||||
embedRenderMessageVariant ''UniWorX ''ErrorResponseTitle ("ErrorResponseTitle" <>)
|
||||
@ -1483,11 +1496,11 @@ instance YesodBreadcrumbs UniWorX where
|
||||
breadcrumb (TermEditExistR tid) = return ("Editieren" , Just $ TermCourseListR tid)
|
||||
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 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
|
||||
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)
|
||||
@ -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 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 (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 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 (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 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)
|
||||
@ -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 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 MDelR) = return ("Löschen" , Just $ CMaterialR tid ssh csh mnm MShowR)
|
||||
-- (CMaterialR tid ssh csh mnm MFileR) -- just for Downloads
|
||||
@ -2062,8 +2075,8 @@ pageActions (CourseR tid ssh csh SheetListR) =
|
||||
, menuItemLabel = MsgMenuCorrectionsOwn
|
||||
, menuItemIcon = Nothing
|
||||
, menuItemRoute = SomeRoute (CorrectionsR, [ ("corrections-term" , termToText $ unTermKey tid)
|
||||
, ("corrections-school", CI.original $ unSchoolKey ssh)
|
||||
, ("corrections-course", CI.original csh)
|
||||
, ("corrections-school", original $ unSchoolKey ssh)
|
||||
, ("corrections-course", original csh)
|
||||
])
|
||||
, menuItemModal = False
|
||||
, menuItemAccessCallback' = do
|
||||
@ -2223,9 +2236,9 @@ pageActions (CSheetR tid ssh csh shn SShowR) =
|
||||
, menuItemLabel = MsgMenuCorrectionsOwn
|
||||
, menuItemIcon = Nothing
|
||||
, menuItemRoute = SomeRoute (CorrectionsR, [ ("corrections-term" , termToText $ unTermKey tid)
|
||||
, ("corrections-school", CI.original $ unSchoolKey ssh)
|
||||
, ("corrections-course", CI.original csh)
|
||||
, ("corrections-sheet" , CI.original shn)
|
||||
, ("corrections-school", original $ unSchoolKey ssh)
|
||||
, ("corrections-course", original csh)
|
||||
, ("corrections-sheet" , original shn)
|
||||
])
|
||||
, menuItemModal = False
|
||||
, menuItemAccessCallback' = (== Authorized) <$> evalAccessCorrector tid ssh csh
|
||||
@ -2576,7 +2589,7 @@ routeNormalizers =
|
||||
tell $ Any True
|
||||
maybeOrig f route = maybeT (return route) $ f route
|
||||
hasChanged a b
|
||||
| ((/=) `on` CI.original) a b = do
|
||||
| ((/=) `on` original) a b = do
|
||||
$logDebugS "routeNormalizers" [st|#{tshow a} /= #{tshow b}|]
|
||||
tell $ Any True
|
||||
| otherwise = return ()
|
||||
@ -2642,7 +2655,7 @@ instance YesodAuth UniWorX where
|
||||
now <- liftIO getCurrentTime
|
||||
|
||||
let
|
||||
userIdent = CI.mk credsIdent
|
||||
userIdent = mk credsIdent
|
||||
uAuth = UniqueAuthentication userIdent
|
||||
|
||||
isDummy = credsPlugin == "dummy"
|
||||
@ -2680,7 +2693,7 @@ instance YesodAuth UniWorX where
|
||||
|
||||
flip catches excHandlers $ case (,) <$> appLdapConf <*> appLdapPool of
|
||||
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
|
||||
|
||||
let
|
||||
@ -2697,7 +2710,7 @@ instance YesodAuth UniWorX where
|
||||
userEmail <- if
|
||||
| Just [bs] <- userEmail'
|
||||
, Right userEmail <- Text.decodeUtf8' bs
|
||||
-> return $ CI.mk userEmail
|
||||
-> return $ mk userEmail
|
||||
| otherwise
|
||||
-> throwError $ ServerError "Could not retrieve user email"
|
||||
userDisplayName <- if
|
||||
@ -2752,7 +2765,7 @@ instance YesodAuth UniWorX where
|
||||
Right str <- return $ Text.decodeUtf8' v'
|
||||
return str
|
||||
|
||||
termNames = nubBy ((==) `on` CI.mk) $ do
|
||||
termNames = nubBy ((==) `on` mk) $ do
|
||||
(k, v) <- ldapData
|
||||
guard $ k == Attr "dfnEduPersonFieldOfStudyString"
|
||||
v' <- v
|
||||
|
||||
@ -126,7 +126,7 @@ colSheet = sortable (Just "sheet") (i18nCell MsgSheet) $ \row ->
|
||||
ssh = course ^. _4
|
||||
csh = course ^. _2
|
||||
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 = sortable (toNothing "sheetType") (i18nCell MsgSheetType) $
|
||||
@ -149,7 +149,7 @@ colSubmissionLink = sortable Nothing (i18nCell MsgSubmission)
|
||||
mkRoute = do
|
||||
cid <- mkCid
|
||||
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 = dbSelect (_1 . applying _2) id $ \DBRow{ dbrOutput=(Entity subId _, _, _, _, _, _) } -> encrypt subId
|
||||
|
||||
@ -53,7 +53,7 @@ colCourse :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a)
|
||||
colCourse = sortable (Just "course") (i18nCell MsgCourse)
|
||||
$ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, _) } ->
|
||||
anchorCell (CourseR courseTerm courseSchool courseShorthand CShowR)
|
||||
[whamlet|#{display courseName}|]
|
||||
[whamlet|_{courseName}|]
|
||||
|
||||
-- colCourseDescr :: IsDBTable m a => Colonnade Sortable CourseTableData (DBCell m a)
|
||||
-- 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 = sortable (Just "cshort") (i18nCell MsgCourseShort)
|
||||
$ \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 = 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 = sortable (Just "term") (i18nCell MsgTerm)
|
||||
$ \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 = sortable (Just "school") (i18nCell MsgCourseSchool)
|
||||
$ \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 = sortable (Just "schoolshort") (i18nCell MsgCourseSchoolShort)
|
||||
$ \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 = sortable (Just "register-from") (i18nCell MsgRegisterFrom)
|
||||
@ -1220,7 +1220,7 @@ postCUsersR tid ssh csh = do
|
||||
]
|
||||
addMessageI Success $ MsgCourseUsersDeregistered nrDel
|
||||
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
|
||||
siteLayout headingLong $ do
|
||||
setTitleI headingShort
|
||||
@ -1407,7 +1407,7 @@ postCUserR tid ssh csh uCId = do
|
||||
mRegAt <- for (courseParticipantRegistration . entityVal <$> mRegistration) $ formatTime SelFormatDateTime
|
||||
|
||||
-- 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
|
||||
siteLayout headingLong $ do
|
||||
setTitleI headingShort
|
||||
|
||||
@ -33,14 +33,14 @@ homeOpenCourses = do
|
||||
colonnade = mconcat
|
||||
[ -- dbRow
|
||||
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} } ->
|
||||
textCell $ display $ courseSchool course
|
||||
textCell $ toMessage $ courseSchool course
|
||||
, sortable (Just "course") (i18nCell MsgCourse) $ \DBRow{ dbrOutput=Entity{entityVal = course} } -> do
|
||||
let tid = courseTerm course
|
||||
ssh = courseSchool 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} } ->
|
||||
cell $ traverse (formatTime SelFormatDateTime) (courseRegisterTo course) >>= maybe mempty toWidget
|
||||
]
|
||||
@ -117,13 +117,13 @@ homeUpcomingSheets uid = do
|
||||
[ -- dbRow
|
||||
-- TOOD: sortable (Just "term") (textCell MsgTerm) $ \DBRow{ dbrOutput=(view _1 -> 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,_,_,_,_) } ->
|
||||
textCell $ display ssh
|
||||
textCell $ toMessage ssh
|
||||
, 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, _, _) } ->
|
||||
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, _) } ->
|
||||
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) } ->
|
||||
|
||||
@ -45,7 +45,7 @@ makeSettingForm template html = do
|
||||
<*> notificationForm (stgNotificationSettings <$> template)
|
||||
return (result, widget) -- no validation required here
|
||||
where
|
||||
themeList = [Option (display t) t (toPathPiece t) | t <- universeF]
|
||||
themeList = [Option (toMessage t) t (toPathPiece t) | t <- universeF]
|
||||
--
|
||||
-- Version with proper grouping:
|
||||
--
|
||||
|
||||
@ -236,7 +236,7 @@ getSheetListR tid ssh csh = do
|
||||
mkRoute = do
|
||||
cid' <- mkCid
|
||||
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)
|
||||
$ \DBRow{dbrOutput=(Entity _ Sheet{..}, _, mbSub,_)} ->
|
||||
let stats = sheetTypeSum sheetType in -- for statistics over all shown rows
|
||||
|
||||
@ -41,7 +41,7 @@ getUsersR = do
|
||||
(nameWidget userDisplayName userSurname)
|
||||
, sortable (Just "matriculation") (i18nCell MsgMatrikelNr) $ \DBRow{ dbrOutput = Entity uid User{..} } -> anchorCellM
|
||||
(AdminUserR <$> encrypt uid)
|
||||
(toWidget . display $ userMatrikelnummer)
|
||||
(toWgt userMatrikelnummer)
|
||||
-- , sortable (Just "last-name") (i18nCell MsgName) $ \DBRow{ dbrOutput = Entity uid User{..} } -> anchorCellM
|
||||
-- (AdminUserR <$> encrypt uid)
|
||||
-- (toWidget . display $ last $ impureNonNull $ words $ userDisplayName)
|
||||
|
||||
@ -175,8 +175,8 @@ cellHasEMail = emailCell . view _userEmail
|
||||
maybeDateTimeCell :: IsDBTable m a => Maybe UTCTime -> DBCell m a
|
||||
maybeDateTimeCell = maybe mempty dateTimeCell
|
||||
|
||||
numCell :: (IsDBTable m a, Num b, DisplayAble b) => b -> DBCell m a
|
||||
numCell = textCell . display
|
||||
numCell :: (IsDBTable m a, Num b, ToMessage b) => b -> DBCell m a
|
||||
numCell = textCell . toMessage
|
||||
|
||||
int64Cell :: (IsDBTable m a) => Int64-> DBCell m a
|
||||
int64Cell = numCell
|
||||
@ -185,7 +185,7 @@ termCell :: IsDBTable m a => TermId -> DBCell m a
|
||||
termCell tid = anchorCell link name
|
||||
where
|
||||
link = TermCourseListR tid
|
||||
name = text2widget $ display tid
|
||||
name = toWgt tid
|
||||
|
||||
termCellCL :: IsDBTable m a => CourseLink -> DBCell m a
|
||||
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
|
||||
where
|
||||
link = TermSchoolCourseListR tid ssh
|
||||
name = text2widget $ display ssh
|
||||
name = toWgt ssh
|
||||
schoolCell Nothing ssh = anchorCell link name
|
||||
where
|
||||
link = SchoolShowR ssh
|
||||
name = text2widget $ display ssh
|
||||
name = toWgt ssh
|
||||
|
||||
schoolCellCL :: IsDBTable m a => CourseLink -> DBCell m a
|
||||
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
|
||||
where
|
||||
link = CourseR tid ssh csh CShowR
|
||||
name = citext2widget csh
|
||||
name = toWgt csh
|
||||
|
||||
courseCell :: IsDBTable m a => Course -> DBCell m a
|
||||
courseCell Course{..} = anchorCell link name `mappend` desc
|
||||
@ -228,7 +228,7 @@ sheetCell crse shn =
|
||||
ssh = crse ^. _2
|
||||
csh = crse ^. _3
|
||||
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 crse shn sid =
|
||||
@ -237,7 +237,7 @@ submissionCell crse shn sid =
|
||||
csh = crse ^. _3
|
||||
mkCid = encrypt sid
|
||||
mkRoute cid = CSubmissionR tid ssh csh shn cid SubShowR
|
||||
mkText = display2widget
|
||||
mkText = toWgt
|
||||
in anchorCellM' mkCid mkRoute mkText
|
||||
|
||||
correctorStateCell :: IsDBTable m a => SheetCorrector -> DBCell m a
|
||||
|
||||
@ -76,6 +76,10 @@ import Language.Haskell.TH.Instances as Import ()
|
||||
import Data.List.NonEmpty.Instances as Import ()
|
||||
import Data.NonNull.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.HashMap.Strict.Instances as Import ()
|
||||
import Data.HashSet.Instances as Import ()
|
||||
|
||||
19
src/Model.hs
19
src/Model.hs
@ -16,13 +16,16 @@ import Cron.Types
|
||||
|
||||
import Data.Aeson (Value)
|
||||
|
||||
import Data.CaseInsensitive (CI)
|
||||
import Data.CaseInsensitive (CI, original)
|
||||
import Data.CaseInsensitive.Instances ()
|
||||
|
||||
import Utils.Message (MessageStatus)
|
||||
|
||||
import Settings.Cluster (ClusterSettingsKey)
|
||||
|
||||
import Text.Blaze (ToMarkup(..))
|
||||
|
||||
|
||||
-- You can define all of your database entities in the entities file.
|
||||
-- You can find more information on persistent and how to declare entities
|
||||
-- at:
|
||||
@ -48,3 +51,17 @@ instance Ord User where
|
||||
|
||||
submissionRatingDone :: Submission -> Bool
|
||||
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
|
||||
@ -16,7 +16,6 @@ import qualified Yesod.Auth.Util.PasswordStore as PWStore
|
||||
type Count = Sum Integer
|
||||
type Points = Centi
|
||||
|
||||
|
||||
type Email = Text
|
||||
|
||||
type SchoolName = CI Text
|
||||
@ -34,4 +33,4 @@ type PWHashAlgorithm = ByteString -> PWStore.Salt -> Int -> ByteString
|
||||
type InstanceId = UUID
|
||||
type ClusterId = UUID
|
||||
type TokenId = UUID
|
||||
type TermCandidateIncidence = UUID
|
||||
type TermCandidateIncidence = UUID
|
||||
@ -45,8 +45,6 @@ seasonFromChar c
|
||||
where
|
||||
(~=) = (==) `on` CI.mk
|
||||
|
||||
-- instance DisplayAble Season
|
||||
|
||||
data TermIdentifier = TermIdentifier
|
||||
{ year :: Integer -- ^ Using 'Integer' to model years is consistent with 'Data.Time.Calendar'
|
||||
, season :: Season
|
||||
|
||||
@ -39,6 +39,6 @@ instance Finite Theme
|
||||
|
||||
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"
|
||||
|
||||
@ -164,13 +164,6 @@ sheetFile2markup SheetHint = iconHint
|
||||
sheetFile2markup SheetSolution = iconSolution
|
||||
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' = groupMap
|
||||
|
||||
|
||||
65
src/Utils.hs
65
src/Utils.hs
@ -31,7 +31,6 @@ import Text.Blaze (Markup, ToMarkup)
|
||||
|
||||
import Data.Char (isDigit, isSpace, isAscii)
|
||||
import Data.Text (dropWhileEnd, takeWhileEnd, justifyRight)
|
||||
import Numeric (showFFloat)
|
||||
|
||||
import Data.Set (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.Catch hiding (throwM)
|
||||
|
||||
|
||||
import qualified Database.Esqueleto as E (Value, unValue)
|
||||
|
||||
import Language.Haskell.TH
|
||||
import Language.Haskell.TH.Instances ()
|
||||
import Instances.TH.Lift ()
|
||||
@ -252,63 +248,14 @@ str2widget :: (MonadBaseControl IO m, MonadThrow m, MonadIO m)
|
||||
=> String -> WidgetT site m ()
|
||||
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 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)
|
||||
{- (not so sure we really want to get rid of display?!) DEPRECATED display "Create RenderMessage Instances instead!" -}
|
||||
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
|
||||
-}
|
||||
rationalToFixed3 :: Rational -> Fixed E3
|
||||
rationalToFixed3 = rationalToFixed
|
||||
|
||||
-- | Convert `part` and `whole` into percentage including symbol
|
||||
-- showing trailing zeroes and to decimal digits
|
||||
@ -326,8 +273,8 @@ textPercent' trailZero precision part whole
|
||||
| precision == 4 = showPercent (frac :: Micro)
|
||||
| otherwise = showPercent (frac :: Pico)
|
||||
where
|
||||
frac :: forall a . HasResolution a => Fixed a
|
||||
frac = MkFixed $ round $ (* (fromInteger $ resolution (Proxy :: Proxy a))) $ (100*) $ toRational part / toRational whole
|
||||
frac :: forall a. HasResolution a => Fixed a
|
||||
frac = rationalToFixed $ (100*) $ toRational part / toRational whole
|
||||
|
||||
showPercent :: HasResolution a => Fixed a -> Text
|
||||
showPercent f = pack $ showFixed trailZero f <> "%"
|
||||
|
||||
@ -95,9 +95,6 @@ afterN n = do
|
||||
deriveShowWith :: (String -> String) -> Name -> Q [Dec]
|
||||
deriveShowWith = deriveSimpleWith ''Show 'show
|
||||
|
||||
-- deriveDisplayWith :: (String -> String) -> Name -> Q [Dec]
|
||||
-- deriveDisplayWith = deriveSimpleWith ''DisplayAble 'display
|
||||
|
||||
deriveSimpleWith :: Name -> Name -> (String -> String) -> Name -> Q [Dec]
|
||||
deriveSimpleWith cls fun strOp ty = do
|
||||
(TyConI tyCon) <- reify ty
|
||||
|
||||
@ -7,8 +7,7 @@ Utils, Utils.*
|
||||
: Hilfsfunktionionen _unabhängig von Foundation_
|
||||
|
||||
Utils
|
||||
: Yesod Hilfsfunktionen und Instanzen, Text-HTML-Widget-Konvertierungen
|
||||
(`DisplayAble`), Crud, `NTop`, Utility-Funktionen für `MonadPlus`, `Maybe`,
|
||||
: Yesod Hilfsfunktionen und Instanzen, Crud, `NTop`, Utility-Funktionen für `MonadPlus`, `Maybe`,
|
||||
`MaybeT`, `Map`, und Attrs-Lists
|
||||
|
||||
Utils.TH
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
<table .table .table--striped .table--hover .table--vertical>
|
||||
<tr .table__row>
|
||||
<th .table__th>_{MsgSubmission}
|
||||
<td .table__td>#{display cid}
|
||||
<td .table__td>#{cid}
|
||||
$maybe Entity _ User{userDisplayName} <- corrector
|
||||
<tr .table__row>
|
||||
<th .table__th>_{MsgRatingBy}
|
||||
<td .table__td>#{display userDisplayName}
|
||||
<td .table__td>#{userDisplayName}
|
||||
$maybe time <- submissionRatingTime
|
||||
<tr .table__row>
|
||||
<th .table__th>_{MsgRatingTime}
|
||||
|
||||
@ -80,7 +80,7 @@
|
||||
<td .table__td .heated style="--hotness: #{heat ciSubmissionsNr ciCorrected}">#{ciSubmissionsNr - ciCorrected}
|
||||
<td .table__td>
|
||||
$maybe deficit <- getCorrDeficit ciCorrector
|
||||
#{display deficit}
|
||||
#{rationalToFixed3 deficit}
|
||||
<td .table__td>#{showDiffDays ciMin}
|
||||
<td .table__td>#{showAvgsDays ciTot ciCorrected}
|
||||
<td .table__td>#{showDiffDays ciMax}
|
||||
|
||||
@ -38,7 +38,7 @@
|
||||
<td .table__td>_{field}#{notUsedT studyFeaturesField}
|
||||
<td .table__td>_{degree}#{notUsedT studyFeaturesDegree}
|
||||
<td .table__td>_{studyFeaturesType}
|
||||
<td .table__td>#{display studyFeaturesSemester}
|
||||
<td .table__td>#{studyFeaturesSemester}
|
||||
<td .table__td>#{hasTickmark studyFeaturesValid}
|
||||
<td .table__td>^{formatTimeW SelFormatDate studyFeaturesUpdated}
|
||||
$maybe _ <- mRegistration
|
||||
|
||||
@ -6,13 +6,13 @@
|
||||
<div .container>
|
||||
#{mailtoHtml userEmail}
|
||||
<div .container>
|
||||
#{display deletedSubmissions} Abgaben wurden unwiederruflich gelöscht.
|
||||
#{deletedSubmissions} Abgaben wurden unwiederruflich gelöscht.
|
||||
$if groupSubmissions > 0
|
||||
<div .container>
|
||||
#{display groupSubmissions} Gruppenabgaben verbleiben in der Datenbank,
|
||||
#{groupSubmissions} Gruppenabgaben verbleiben in der Datenbank,
|
||||
aber die Zuordnung zum Benutzer wurden gelöscht.
|
||||
Gruppenabgaben können dadurch zu Einzelabgaben werden,
|
||||
welche dann vom letzten Benutzer gelöscht werden können.
|
||||
$if deletedSubmissionGroups > 0
|
||||
<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.
|
||||
|
||||
@ -22,12 +22,12 @@ $newline never
|
||||
_{MsgSubmission}
|
||||
<dd>
|
||||
<a href=@{CSubmissionR tid ssh csh shn csid SubShowR}>
|
||||
#{display csid}
|
||||
#{csid}
|
||||
$maybe User{userDisplayName} <- corrector
|
||||
<dt>
|
||||
_{MsgRatingBy}
|
||||
<dd>
|
||||
#{display userDisplayName}
|
||||
#{userDisplayName}
|
||||
$maybe time <- submissionRatingTime'
|
||||
<dt>
|
||||
_{MsgRatingTime}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
<dt .deflist__dt> _{MsgEMail}
|
||||
<dd .deflist__dd> #{mailtoHtml userEmail}
|
||||
<dt .deflist__dt> _{MsgIdent}
|
||||
<dd .deflist__dd> #{display userIdent}
|
||||
<dd .deflist__dd> #{userIdent}
|
||||
<dt .deflist__dt> _{MsgLastLogin}
|
||||
<dd .deflist__dd>
|
||||
$maybe llogin <- lastLogin
|
||||
@ -23,7 +23,7 @@
|
||||
$forall (E.Value institute) <- admin_rights
|
||||
<li .list-ul__item>
|
||||
<a href=@{SchoolShowR $ SchoolKey institute}>
|
||||
#{display institute}
|
||||
#{institute}
|
||||
$if not $ null lecturer_rights
|
||||
<dt .deflist__dt>_{MsgLecturerFor}
|
||||
<dd .deflist__dd>
|
||||
@ -31,14 +31,14 @@
|
||||
$forall (E.Value institute) <- lecturer_rights
|
||||
<li .list-ul__item>
|
||||
<a href=@{SchoolShowR $ SchoolKey institute}>
|
||||
#{display institute}
|
||||
#{institute}
|
||||
$if not $ null lecture_corrector
|
||||
<dt .deflist__dt> Korrektor
|
||||
<dd .deflist__dd>
|
||||
<ul .list-ul>
|
||||
$forall (E.Value tid, E.Value ssh, E.Value csh) <- lecture_corrector
|
||||
<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
|
||||
<dt .deflist__dt> Studiengänge
|
||||
<dd .deflist__dd>
|
||||
@ -58,7 +58,7 @@
|
||||
<td .table__td>_{field}#{notUsedT studyFeaturesField}
|
||||
<td .table__td>_{degree}#{notUsedT studyFeaturesDegree}
|
||||
<td .table__td>_{studyFeaturesType}
|
||||
<td .table__td>#{display studyFeaturesSemester}
|
||||
<td .table__td>#{studyFeaturesSemester}
|
||||
<td .table__td>#{hasTickmark studyFeaturesValid}
|
||||
<td .table__td>^{formatTimeW SelFormatDateTime studyFeaturesUpdated}
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ $maybe cID <- mcid
|
||||
$maybe name <- mbName
|
||||
<li>_{MsgEditedBy name time}
|
||||
$nothing
|
||||
<li>#{display time}
|
||||
<li>#{time}
|
||||
|
||||
$if maySubmit
|
||||
<section>
|
||||
|
||||
@ -21,7 +21,7 @@ $#
|
||||
$if pmax > 0
|
||||
#{textPercent pacv pmax}
|
||||
<td .table__td>
|
||||
#{display pacv} / #{display pmax}
|
||||
_{pacv} / _{pmax}
|
||||
$else
|
||||
<td .table__td>
|
||||
<td .table__td>
|
||||
@ -29,7 +29,7 @@ $#
|
||||
$with Sum numPass <- summary ^. _numSheetsPasses
|
||||
<td .table__td>
|
||||
$if numPass > 0
|
||||
#{display numPass}
|
||||
_{numPass}
|
||||
$maybe _ <- hasMarkedPoints
|
||||
$with Sum pmax <- summary ^. _sumMarkedPoints
|
||||
$with Sum pacv <- summary ^. _achievedPoints
|
||||
@ -37,18 +37,18 @@ $#
|
||||
$if pmax > 0
|
||||
#{textPercent pacv pmax}
|
||||
<td .table__td>
|
||||
#{display pacv} / #{display pmax}
|
||||
_{pacv} / _{pmax}
|
||||
$if ((summary ^. _numMarkedPoints) /= (summary ^. _numSheets))
|
||||
$# Falls Anzahl Blätter der Zeile verschieden von Anzahl gewerterer Blätter
|
||||
\ (_{title $ getSum $ summary ^. _numMarkedPoints})
|
||||
$# Kurze Alternative mit Hashtag-Symbol für "Anzahl"
|
||||
$# \ (##{display $ summary ^. _numMarkedPoints})
|
||||
$# \ (##{summary ^. _numMarkedPoints})
|
||||
$maybe _ <- hasPoints
|
||||
<td .table__td>
|
||||
#{display (summary ^. _sumSheetsPoints)}
|
||||
#{summary ^. _sumSheetsPoints}
|
||||
$if ((summary ^. _numSheetsPoints) /= (summary ^. _numSheets))
|
||||
$# Falls Anzahl Blätter der Zeile verschieden von Anzahl Blätter mit Punkten
|
||||
\ (_{title $ getSum $ summary ^. _numSheetsPoints})
|
||||
$# Kurze Alternative mit Hashtag-Symbol für "Anzahl"
|
||||
$# \ (##{display $ summary ^. _numSheetsPoints})
|
||||
<td .table__td>#{display $ summary ^. _numSheets}
|
||||
$# \ (##{summary ^. _numSheetsPoints})
|
||||
<td .table__td>#{summary ^. _numSheets}
|
||||
|
||||
@ -176,6 +176,24 @@ fillDb = do
|
||||
, userMailLanguages = MailLanguages ["de"]
|
||||
, 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
|
||||
{ termName = summer2017
|
||||
, termStart = fromGregorian 2017 04 09
|
||||
@ -210,9 +228,12 @@ fillDb = do
|
||||
void . insert' $ UserAdmin fhamann ifi
|
||||
void . insert' $ UserAdmin jost ifi
|
||||
void . insert' $ UserAdmin jost mi
|
||||
void . insert' $ UserAdmin svaupel ifi
|
||||
void . insert' $ UserAdmin svaupel mi
|
||||
void . insert' $ UserLecturer gkleen ifi
|
||||
void . insert' $ UserLecturer fhamann ifi
|
||||
void . insert' $ UserLecturer jost ifi
|
||||
void . insert' $ UserLecturer svaupel ifi
|
||||
let
|
||||
sdBsc = StudyDegreeKey' 82
|
||||
sdMst = StudyDegreeKey' 88
|
||||
|
||||
Loading…
Reference in New Issue
Block a user