Merge branch 'master' into feat/corrections-upload

This commit is contained in:
Gregor Kleen 2018-07-01 18:49:36 +02:00
commit 1d49244d63
22 changed files with 398 additions and 215 deletions

View File

@ -43,7 +43,16 @@ main = db $ do
, userEmail = "jost@tcs.ifi.lmu.de"
, userDisplayName = "Steffen Jost"
, userMaxFavourites = 14
, userTheme = MintGreen
, userTheme = MossGreen
}
void . insert $ User
{ userPlugin = "LDAP"
, userIdent = "max@campus.lmu.de"
, userMatrikelnummer = Nothing
, userEmail = "max@campus.lmu.de"
, userDisplayName = "Max Musterstudent"
, userMaxFavourites = 7
, userTheme = AberdeenReds
}
void . insert $ Term
{ termName = summer2017
@ -91,7 +100,7 @@ main = db $ do
{ courseName = "Fortgeschrittene Funktionale Programmierung"
, courseDescription = Nothing
, courseLinkExternal = Nothing
, courseShorthand = "ffp"
, courseShorthand = "FFP"
, courseTerm = TermKey summer2018
, courseSchool = ifi
, courseCapacity = Just 20
@ -117,7 +126,7 @@ main = db $ do
{ courseName = "Einführung in die Programmierung"
, courseDescription = Nothing
, courseLinkExternal = Nothing
, courseShorthand = "eip"
, courseShorthand = "EIP"
, courseTerm = TermKey summer2017
, courseSchool = ifi
, courseCapacity = Just 20
@ -135,7 +144,7 @@ main = db $ do
{ courseName = "Interaction Design (User Experience Design I & II)"
, courseDescription = Nothing
, courseLinkExternal = Nothing
, courseShorthand = "ixd"
, courseShorthand = "IXD"
, courseTerm = TermKey summer2018
, courseSchool = ifi
, courseCapacity = Just 20
@ -153,7 +162,7 @@ main = db $ do
{ courseName = "Concept Development (User Experience Design III)"
, courseDescription = Nothing
, courseLinkExternal = Nothing
, courseShorthand = "ux3"
, courseShorthand = "UX3"
, courseTerm = TermKey winter2017
, courseSchool = ifi
, courseCapacity = Just 30
@ -171,7 +180,7 @@ main = db $ do
{ courseName = "Programmierung und Modellierung"
, courseDescription = Nothing
, courseLinkExternal = Nothing
, courseShorthand = "pmo"
, courseShorthand = "ProMo"
, courseTerm = TermKey summer2017
, courseSchool = ifi
, courseCapacity = Just 50
@ -189,7 +198,7 @@ main = db $ do
{ courseName = "Datenbanksysteme"
, courseDescription = Nothing
, courseLinkExternal = Nothing
, courseShorthand = "dbs"
, courseShorthand = "DBS"
, courseTerm = TermKey summer2018
, courseSchool = ifi
, courseCapacity = Just 50

View File

@ -7,16 +7,16 @@ BtnDeregister: Abmelden
RegisterFrom: Anmeldungen von
RegisterTo: Anmeldungen bis
SummerTerm year@Integer: Sommersemester #{tshow year}
WinterTerm year@Integer: Wintersemester #{tshow year}/#{tshow $ succ year}
SummerTerm year@Integer: Sommersemester #{display year}
WinterTerm year@Integer: Wintersemester #{display year}/#{display $ succ year}
PSLimitNonPositive: “pagesize” muss größer als null sein
Page n@Int64: #{tshow n}
Page n@Int64: #{display n}
TermsHeading: Semesterübersicht
TermCurrent: Aktuelles Semester
TermEditHeading: Semester editieren/anlegen
TermEditTid tk@TermId: Semester #{display tk} editieren
TermEdited tid@TermIdentifier: Semester #{display tid} erfolgreich editiert.
TermEditTid tid@TermId: Semester #{display tid} editieren
TermEdited tid@TermId: Semester #{display tid} erfolgreich editiert.
TermNewTitle: Semester editieren/anlegen.
InvalidInput: Eingaben bitte korrigieren.
Term: Semester
@ -26,33 +26,50 @@ LectureStart: Beginn Vorlesungen
Course: Kurs
CourseSecret: Zugangspasswort
CourseNewOk tid@TermIdentifier courseShortHand@Text: Kurs #{termToText tid}-#{courseShortHand} wurde erfolgreich erstellt.
CourseEditOk tid@TermIdentifier courseShortHand@Text: Kurs #{termToText tid}-#{courseShortHand} wurde erfolgreich geändert.
CourseNewDupShort tid@TermIdentifier courseShortHand@Text: Kurs #{termToText tid}-#{courseShortHand} konnte nicht erstellt werden: Es gibt bereits einen anderen Kurs mit dem Kürzel #{courseShortHand} in diesem Semester.
CourseEditDupShort tid@TermIdentifier courseShortHand@Text: Kurs #{termToText tid}-#{courseShortHand} konnte nicht geändert werden: Es gibt bereits einen anderen Kurs mit dem Kürzel #{courseShortHand} in diesem Semester.
CourseNewOk tid@TermId courseShortHand@Text: Kurs #{display tid}-#{courseShortHand} wurde erfolgreich erstellt.
CourseEditOk tid@TermId courseShortHand@Text: Kurs #{display tid}-#{courseShortHand} wurde erfolgreich geändert.
CourseNewDupShort tid@TermId courseShortHand@Text: Kurs #{display tid}-#{courseShortHand} konnte nicht erstellt werden: Es gibt bereits einen anderen Kurs mit dem Kürzel #{courseShortHand} in diesem Semester.
CourseEditDupShort tid@TermId courseShortHand@Text: Kurs #{display tid}-#{courseShortHand} konnte nicht geändert werden: Es gibt bereits einen anderen Kurs mit dem Kürzel #{courseShortHand} in diesem Semester.
FFSheetName: Name
TermCourseListHeading tk@TermId: Kursübersicht #{display tk}
TermCourseListTitle tk@TermId: Kurse #{display tk}
TermCourseListHeading tid@TermId: Kursübersicht #{display tid}
TermCourseListTitle tid@TermId: Kurse #{display tid}
CourseNewHeading: Neuen Kurs anlegen
CourseEditHeading tk@TermId courseShortHand@Text: Kurs #{display tk}-#{courseShortHand} editieren
CourseEditHeading tid@TermId courseShortHand@Text: Kurs #{display tid}-#{courseShortHand} editieren
CourseEditTitle: Kurs editieren/anlegen
Sheet: Blatt
SheetList tk@TermId courseShortHand@Text: #{display tk}-#{courseShortHand} Übersicht Übungsblätter
SheetNewHeading tk@TermId courseShortHand@Text: #{display tk}-#{courseShortHand} Neues Übungsblatt anlegen
SheetNewOk tk@TermId courseShortHand@Text sheetName@Text: Neues Übungsblatt #{sheetName} wurde im Kurs #{display tk}-#{courseShortHand} erfolgreich erstellt.
SheetTitle tk@TermId courseShortHand@Text sheetName@Text: #{display tk}-#{courseShortHand} #{sheetName}
SheetTitleNew tk@TermId courseShortHand@Text : #{display tk}-#{courseShortHand}: Neues Übungsblatt
SheetEditHead tk@TermId courseShortHand@Text sheetName@Text: #{display tk}-#{courseShortHand} #{sheetName} editieren
SheetEditOk tk@TermId courseShortHand@Text sheetName@Text: Übungsblatt #{sheetName} aus Kurs #{display tk}-#{courseShortHand} wurde gespeichert.
SheetNameDup tk@TermId courseShortHand@Text sheetName@Text: Es gibt bereits ein Übungsblatt #{sheetName} in diesem Kurs #{display tk}-#{courseShortHand}.
SheetDelHead tk@TermId courseShortHand@Text sheetName@Text: Übungsblatt #{sheetName} wirklich aus Kurs #{display tk}-#{courseShortHand} herauslöschen?
SheetDelText submissionNo@Int: Dies kann nicht mehr rückgängig gemacht werden! Alle Einreichungen gehen ebenfalls verloren! Es gibt #{show submissionNo} Abgaben.
SheetDelOk tk@TermId courseShortHand@Text sheetName@Text: #{display tk}-#{courseShortHand}: Übungsblatt #{sheetName} gelöscht.
SheetList tid@TermId courseShortHand@Text: #{display tid}-#{courseShortHand} Übersicht Übungsblätter
SheetNewHeading tid@TermId courseShortHand@Text: #{display tid}-#{courseShortHand} Neues Übungsblatt anlegen
SheetNewOk tid@TermId courseShortHand@Text sheetName@Text: Neues Übungsblatt #{sheetName} wurde im Kurs #{display tid}-#{courseShortHand} erfolgreich erstellt.
SheetTitle tid@TermId courseShortHand@Text sheetName@Text: #{display tid}-#{courseShortHand} #{sheetName}
SheetTitleNew tid@TermId courseShortHand@Text : #{display tid}-#{courseShortHand}: Neues Übungsblatt
SheetEditHead tid@TermId courseShortHand@Text sheetName@Text: #{display tid}-#{courseShortHand} #{sheetName} editieren
SheetEditOk tid@TermId courseShortHand@Text sheetName@Text: Übungsblatt #{sheetName} aus Kurs #{display tid}-#{courseShortHand} wurde gespeichert.
SheetNameDup tid@TermId courseShortHand@Text sheetName@Text: Es gibt bereits ein Übungsblatt #{sheetName} in diesem Kurs #{display tid}-#{courseShortHand}.
SheetDelHead tid@TermId courseShortHand@Text sheetName@Text: Übungsblatt #{sheetName} wirklich aus Kurs #{display tid}-#{courseShortHand} herauslöschen?
SheetDelText submissionNo@Int: Dies kann nicht mehr rückgängig gemacht werden! Alle Einreichungen gehen ebenfalls verloren! Es gibt #{display submissionNo} Abgaben.
SheetDelOk tid@TermId courseShortHand@Text sheetName@Text: #{display tid}-#{courseShortHand}: Übungsblatt #{sheetName} gelöscht.
SheetExercise: Aufgabenstellung
SheetHint: Hinweise
SheetSolution: Lösung
SheetMarking: Korrekturhinweise
Deadline: Abgabe
Done: Eingereicht
Submission: Abgabenummer
SubmissionWrongSheet: Abgabenummer gehört nicht zum angegebenen Übungsblatt.
SubmissionAlreadyExists: Sie haben bereits eine Abgabe zu diesem Übungsblatt.
SubmissionEditHead tid@TermId courseShortHand@Text sheetName@Text: #{display tid}-#{courseShortHand} #{sheetName}: Abgabe editieren/anlegen
SubmissionMember g@Int: Mitabgebende(r) ##{display g}
SubmissionArchive: Zip-Archiv der Abgabedatei(en)
SubmissionFile: Datei zur Abgabe
SubmissionAlreadyExistsFor user@Text: #{user} hat bereits eine Abgabe zu diesem bÜbungsblatt.
CorrectionsTitle: Zugewiesene Korrekturen
CourseCorrectionsTitle: Korrekturen für diesen Kurs
Unauthorized: Sie haben hierfür keine explizite Berechtigung.
UnauthorizedAnd l@Text r@Text: #{l} UND #{r}
UnauthorizedOr l@Text r@Text: #{l} ODER #{r}
@ -72,26 +89,13 @@ DeprecatedRoute: Diese Ansicht ist obsolet und könnte in Zukunft entfallen.
UnfreeMaterials: Die Materialien für diese Veranstaltung sind nicht allgemein freigegeben.
UnauthorizedWrite: Sie haben hierfür keine Schreibberechtigung
Submission: Abgabenummer
SubmissionWrongSheet: Abgabenummer gehört nicht zum angegebenen Übungsblatt.
SubmissionAlreadyExists: Sie haben bereits eine Abgabe zu diesem Übungsblatt.
SubmissionEditHead tk@TermId courseShortHand@Text sheetName@Text: #{display tk}-#{courseShortHand} #{sheetName}: Abgabe editieren/anlegen
SubmissionMember g@Int: Mitabgebende(r) ##{tshow g}
SubmissionArchive: Zip-Archiv der Abgabedatei(en)
SubmissionFile: Datei zur Abgabe
SubmissionAlreadyExistsFor user@Text: #{user} hat bereits eine Abgabe zu diesem bÜbungsblatt.
CorrectionsTitle: Zugewiesene Korrekturen
CourseCorrectionsTitle: Korrekturen für diesen Kurs
EMail: E-Mail
EMailUnknown email@Text: E-Mail #{email} gehört zu keinem bekannten Benutzer.
NotAParticipant user@Text tk@TermId csh@Text: #{user} ist nicht im Kurs #{display tk}-#{csh} angemeldet.
NotAParticipant user@Text tid@TermId csh@Text: #{user} ist nicht im Kurs #{display tid}-#{csh} angemeldet.
AddCorrector: Zusätzlicher Korrektor
CorrectorExists user@Text: #{user} ist bereits als Korrektor eingetragen
SheetCorrectorsTitle tid@TermIdentifier courseShortHand@Text sheetName@Text: Korrektoren für #{termToText tid}-#{courseShortHand} #{sheetName}
SheetCorrectorsTitle tid@TermId courseShortHand@Text sheetName@Text: Korrektoren für #{display tid}-#{courseShortHand} #{sheetName}
CountTutProp: Tutorien zählen gegen Proportion
Corrector: Korrektor
Correctors: Korrektoren
@ -108,7 +112,7 @@ HomeHeading: Aktuelle Termine
ProfileHeading: Benutzerprofil und Einstellungen
ProfileDataHeading: Gespeicherte Benutzerdaten
NumCourses n@Int64: #{tshow n} Kurse
NumCourses n@Int64: #{display n} Kurse
CloseAlert: Schliessen
Name: Name
@ -120,11 +124,6 @@ Ident: Identifizierung
Settings: Individuelle Benutzereinstellungen
SettingsUpdate: Einstellungen wurden gespeichert.
SheetExercise: Aufgabenstellung
SheetHint: Hinweise
SheetSolution: Lösung
SheetMarking: Korrekturhinweise
MultiFileUploadInfo: (Mehrere Dateien mit Shift oder Strg auswählen)
NrColumn: Nr
@ -144,4 +143,4 @@ RemovedCorrections num@Int64: Korrektur-Daten wurden von #{display num} Abgaben
UpdatedAssignedCorrectorsAuto num@Int64: #{display num} Abgaben wurden unter den Korrektoren aufgeteilt.
CouldNotAssignCorrectorsAuto num@Int64: #{display num} Abgaben konnten nicht automatisch zugewiesen werden:
CorrectionsUploaded num@Int64: #{display num} Korrekturen wurden gespeichert:
CorrectionsUploaded num@Int64: #{display num} Korrekturen wurden gespeichert:

View File

@ -607,6 +607,19 @@ instance YesodBreadcrumbs UniWorX where
-- Others
breadcrumb _ = return ("Uni2work", Nothing) -- Default is no breadcrumb at all
submissionList :: TermId -> Text -> Text -> UserId -> DB [E.Value SubmissionId]
submissionList tid csh shn uid = E.select . E.from $ \(course `E.InnerJoin` sheet `E.InnerJoin` submission `E.InnerJoin` submissionUser) -> do
E.on $ submissionUser E.^. SubmissionUserSubmission E.==. submission E.^. SubmissionId
E.on $ submission E.^. SubmissionSheet E.==. sheet E.^. SheetId
E.on $ sheet E.^. SheetCourse E.==. course E.^. CourseId
E.where_ $ submissionUser E.^. SubmissionUserUser E.==. E.val uid
E.&&. sheet E.^. SheetName E.==. E.val shn
E.&&. course E.^. CourseShorthand E.==. E.val csh
E.&&. course E.^. CourseTerm E.==. E.val tid
return $ submission E.^. SubmissionId
pageActions :: Route UniWorX -> [MenuTypes]
pageActions (CourseR tid csh CShowR) =
[ PageActionPrime $ MenuItem
@ -657,13 +670,21 @@ pageActions (CSheetR tid csh shn SShowR) =
{ menuItemLabel = "Abgabe anlegen"
, menuItemIcon = Nothing
, menuItemRoute = CSheetR tid csh shn SubmissionNewR
, menuItemAccessCallback' = return True -- TODO: check that no submission already exists
, menuItemAccessCallback' = runDB . maybeT (return False) $ do
uid <- MaybeT $ liftHandlerT maybeAuthId
submissions <- lift $ submissionList tid csh shn uid
guard $ null submissions
return True
}
, PageActionPrime $ MenuItem
{ menuItemLabel = "Abgabe ansehen"
, menuItemIcon = Nothing
, menuItemRoute = CSheetR tid csh shn SubmissionOwnR
, menuItemAccessCallback' = return True -- TODO: check that a submission already exists
, menuItemAccessCallback' = runDB . maybeT (return False) $ do
uid <- MaybeT $ liftHandlerT maybeAuthId
submissions <- lift $ submissionList tid csh shn uid
guard . not $ null submissions
return True
}
, PageActionPrime $ MenuItem
{ menuItemLabel = "Korrektoren"
@ -719,7 +740,7 @@ pageActions (HomeR) =
-- ,
NavbarAside $ MenuItem
{ menuItemLabel = "AdminDemo"
, menuItemIcon = Nothing
, menuItemIcon = Just "book"
, menuItemRoute = AdminTestR
, menuItemAccessCallback' = return True
}

View File

@ -174,7 +174,6 @@ courseEditHandler isGet course = do
, cfShort = csh
, cfTerm = tid
})) -> do -- create new course
let tident = unTermKey tid
now <- liftIO getCurrentTime
insertOkay <- runDB $ insertUnique $ Course
{ courseName = cfName res
@ -195,17 +194,16 @@ courseEditHandler isGet course = do
runDB $ do
insert_ $ CourseEdit aid now cid
insert_ $ Lecturer aid cid
addMessageI "info" $ MsgCourseNewOk tident csh
addMessageI "info" $ MsgCourseNewOk tid csh
redirect $ TermCourseListR tid
Nothing ->
addMessageI "danger" $ MsgCourseNewDupShort tident csh
addMessageI "danger" $ MsgCourseNewDupShort tid csh
(FormSuccess res@(
CourseForm { cfCourseId = Just cid
, cfShort = csh
, cfTerm = tid
})) -> do -- edit existing course
let tident = unTermKey tid
now <- liftIO getCurrentTime
-- addMessage "debug" [shamlet| #{show res}|]
runDB $ do
@ -215,7 +213,7 @@ courseEditHandler isGet course = do
(Just oldCourse) -> do
-- existing <- getBy $ CourseTermShort tid csh
-- if ((entityKey <$> existing) /= Just cid)
-- then addMessageI "danger" $ MsgCourseEditDupShort tident csh
-- then addMessageI "danger" $ MsgCourseEditDupShort tid csh
-- else do
-- addMessage "debug" $ fromMaybe [shamlet|No description given.|] $ cfDesc res
-- update cid
@ -249,9 +247,9 @@ courseEditHandler isGet course = do
insert_ $ CourseEdit aid now cid
-- if (isNothing updOkay)
-- then do
addMessageI "success" $ MsgCourseEditOk tident csh
addMessageI "success" $ MsgCourseEditOk tid csh
-- redirect $ TermCourseListR tid
-- else addMessageI "danger" $ MsgCourseEditDupShort tident csh
-- else addMessageI "danger" $ MsgCourseEditDupShort tid csh
(FormFailure _) -> addMessageI "warning" MsgInvalidInput
(FormMissing) | isGet -> return ()

View File

@ -31,7 +31,7 @@ makeSettingForm template = identForm FIDsettings $ \html -> do
<$> areq (natFieldI $ MsgNatField "Favoriten") -- TODO: natFieldI not working here
(fslpI MsgFavoriten "Anzahl Favoriten") (stgMaxFavourties <$> template)
<*> areq (selectFieldList themeList)
(fslI MsgTheme ) (stgTheme <$> template)
(fslpI MsgTheme "theme-select" ) (stgTheme <$> template) -- TODO: pass theme-select as id-attribute or similar.
<* submitButton
return (result, widget) -- no validation required here
@ -70,7 +70,7 @@ getProfileR = do
E.where_ $ adright ^. UserAdminUser E.==. E.val uid
E.on $ adright ^. UserAdminSchool E.==. school ^. SchoolId
return (school ^. SchoolShorthand)
)
)
<*>
(E.select $ E.from $ \(lecright `E.InnerJoin` school) -> do
E.where_ $ lecright ^. UserLecturerUser E.==. E.val uid

View File

@ -592,7 +592,7 @@ getSCorrR, postSCorrR :: TermId
-> Text -- ^ Sheet name
-> Handler Html
postSCorrR = getSCorrR
getSCorrR tid@(unTermKey -> tident) csh shn = do
getSCorrR tid csh shn = do
Entity shid Sheet{..} <- runDB $ fetchSheet tid csh shn
((res,formWidget), formEnctype) <- runFormPost . identForm FIDcorrectors . renderAForm FormStandard $ formToAForm (correctorForm shid) <* submitButton
@ -606,10 +606,10 @@ getSCorrR tid@(unTermKey -> tident) csh shn = do
FormMissing -> return ()
let
formTitle = MsgSheetCorrectorsTitle tident csh shn
formTitle = MsgSheetCorrectorsTitle tid csh shn
formText = Nothing :: Maybe (SomeMessage UniWorX)
actionUrl = CSheetR tid csh shn SCorrR
-- actionUrl = CSheetR tid csh shn SShowR
defaultLayout $ do
setTitleI $ MsgSheetCorrectorsTitle tident csh shn
setTitleI $ MsgSheetCorrectorsTitle tid csh shn
$(widgetFile "formPageI18n")

View File

@ -121,14 +121,15 @@ termEditHandler term = do
((result, formWidget), formEnctype) <- runFormPost $ newTermForm term
case result of
(FormSuccess res) -> do
let tid = TermKey $ termName res
-- term <- runDB $ get $ TermKey termName
runDB $ repsert (TermKey $ termName res) res
runDB $ repsert tid res
-- VOR INTERNATIONALISIERUNG:
-- let tid = termToText $ termName res
-- let msg = "Semester " `T.append` tid `T.append` " erfolgreich editiert."
-- addMessage "success" [shamlet| #{msg} |]
-- MIT INTERNATIONALISIERUNG:
addMessageI "success" $ MsgTermEdited $ termName res
addMessageI "success" $ MsgTermEdited tid
redirect TermShowR
(FormMissing ) -> return ()
(FormFailure _) -> addMessageI "warning" MsgInvalidInput

View File

@ -207,7 +207,7 @@ termFromRational n = TermIdentifier{..}
season
| remainder == 0 = Summer
| otherwise = Winter
instance PersistField TermIdentifier where
toPersistValue = PersistRational . termToRational
fromPersistValue (PersistRational t) = Right $ termFromRational t
@ -231,20 +231,20 @@ instance ToJSON TermIdentifier where
instance FromJSON TermIdentifier where
parseJSON = withText "Term" $ either (fail . Text.unpack) return . termFromText
{- Must be defined in a later module:
termField :: Field (HandlerT UniWorX IO) TermIdentifier
termField = checkMMap (return . termFromText) termToText textField
-- TODO: this is too simple and inconvenient, use selector and year picker
-}
-- TODO: this is too simple and inconvenient, use selector and year picker
-}
withinTerm :: Day -> TermIdentifier -> Bool
time `withinTerm` term = timeYear `mod` 100 == termYear `mod` 100
where
timeYear = fst3 $ toGregorian time
termYear = year term
where
timeYear = fst3 $ toGregorian time
termYear = year term
data StudyFieldType = FieldPrimary | FieldSecondary
deriving (Eq, Ord, Enum, Show, Read, Bounded)
@ -254,9 +254,10 @@ derivePersistField "StudyFieldType"
-- Skins / Themes
data Theme --Simply add Themes to this type only. CamelCase will be converted to "-lower"
= Default
| Lavender
| NeutralBlue
| AberdeenReds
| MintGreen
| AberdeenReds -- e.g. turned into "theme--aberdeen-reds"
| MossGreen
| SkyLove
deriving (Eq,Ord,Bounded,Enum)
@ -280,5 +281,3 @@ instance Default Theme where
-}
derivePersistField "Theme"

View File

@ -1,40 +1,44 @@
0<div .container>
<div .container>
<div .scrolltable>
<table .table.table--striped.table--hover.table--vertical>
$maybe school <- schoolMB
<tr .table__row>
<th #school>Fakultät/Institut
<td>
#{schoolName school}
<th #school .table__th>Fakultät/Institut
<td .table__td>
<div.table__td-content>
#{schoolName school}
$maybe descr <- courseDescription course
<tr .table__row>
<th #description>Beschreibung
<td>
#{descr}
<th #description .table__th>Beschreibung
<td .table__td>
<div.table__td-content>
#{descr}
$maybe link <- courseLinkExternal course
<tr .table__row>
<th #website>Website
<td>
<a href=#{link} target="_blank" rel="noopener" title="Website des Kurses">#{link}
<th #website .table__th>Website
<td .table__td>
<div.table__td-content>
<a href=#{link} target="_blank" rel="noopener" title="Website des Kurses">#{link}
<tr .table__row>
<th #participants>Teilnehmer
<td>
#{participants}
$maybe capacity <- courseCapacity course
\ von #{capacity}
<tr .table__row>
<th #registration>Anmeldezeitraum
<td>
$maybe regFrom <- courseRegisterFrom course
#{formatTimeGerWD regFrom}
$maybe regTo <- courseRegisterTo course
\ bis #{formatTimeGerWD regTo}
<tr .table__row>
<th>
<td>
$if registrationOpen
<div .course__registration.container>
<th #participants .table__th>Teilnehmer
<td .table__td>
<div.table__td-content>
#{participants}
$maybe capacity <- courseCapacity course
\ von #{capacity}
$maybe regFrom <- courseRegisterFrom course
<tr .table__row>
<th #registration .table__th>Anmeldezeitraum
<td .table__td>
<div.table__td-content>
Ab #{formatTimeGerWD regFrom}
$maybe regTo <- courseRegisterTo course
\ bis #{formatTimeGerWD regTo}
$if registrationOpen
<tr .table__row>
<th .table__th>
<td .table__td>
<div .table__td-content.course__registration.container>
<form method=post action=@{CourseR tid csh CRegisterR} enctype=#{regEnctype}>
$# regWidget is defined through templates/widgets/registerForm
^{regWidget}

View File

@ -12,11 +12,11 @@
/* FONTS */
--font-base: "Source Sans Pro", Helvetica, sans-serif;
--font-base: "Source Sans Pro", "Trebuchet MS", sans-serif;
--font-logo: "Roboto", var(--font-base);
/* DIMENSIONS */
--header-height: 80px;
--header-height: 100px;
--header-height-collapsed: 50px;
}
@ -38,15 +38,25 @@ body {
/* THEMES */
body {
/* DEFAULT THEME */
--color-primary: #4C7A9C;
--color-light: #598EB5;
--color-lighter: #5F98C2;
--color-dark: #425d79;
--color-darker: #274a65;
--color-link: var(--color-dark);
--color-link-hover: var(--color-darker);
/* DEFAULT LMU THEME */
--color-primary: #0a9342;
--color-light: #31cc72;
--color-lighter: #35db7a;
--color-dark: #087536;
--color-darker: #075728;
--color-link: var(--color-font);
--color-link-hover: var(--color-font);
--color-lmu-box-border: var(--color-lightwhite);
&.theme--lavender {
--color-primary: #4C7A9C;
--color-light: #598EB5;
--color-lighter: #5F98C2;
--color-dark: #425d79;
--color-darker: #274a65;
--color-link: var(--color-dark);
--color-link-hover: var(--color-darker);
}
&.theme--neutral-blue {
--color-primary: #3E606F;
@ -64,7 +74,7 @@ body {
--color-darker: #2E112D;
}
&.theme--mint-green {
&.theme--moss-green {
--color-primary: #5C996B;
--color-light: #7ACC8F;
--color-lighter: #99FFB2;
@ -159,7 +169,6 @@ h4 {
.main__content {
position: relative;
background-color: white;
z-index: 0;
overflow: hidden;
> .container {
@ -291,7 +300,7 @@ a.btn.btn-info:hover,
.table__td {
font-size: 16px;
color: #808080;
color: var(--color-font);
line-height: 1.4;
vertical-align: top;
}

View File

@ -1,9 +1,9 @@
$newline never
$forall FileUploadInfo{..} <- fileInfos
<div .file-checkbox__container :fuiChecked:.file-checkbox__container--checked>
<label .file-checkbox__label.reactive-label.btn for=#{fuiHtmlId}>#{fuiTitle}
<div .file-container :fuiChecked:.file-container--checked>
<label .file-container__label.btn for=#{fuiHtmlId}>#{fuiTitle}
<div .checkbox>
<input .file-checkbox.js-file-checkbox id=#{fuiHtmlId} name=#{fieldName} :fuiChecked:checked value=#{toPathPiece fuiId} type="checkbox">
<input .file-container__checkbox.js-file-checkbox id=#{fuiHtmlId} name=#{fieldName} :fuiChecked:checked value=#{toPathPiece fuiId} type="checkbox">
<label for=#{fuiHtmlId}>
$# new files

View File

@ -22,3 +22,34 @@
margin-top: 10px;
font-weight: 600;
}
.file-container {
display: flex;
align-items: center;
margin-bottom: 20px;
&.file-container--checked {
&::after {
content: none;
}
.file-container__label {
opacity: 1;
}
}
&::after {
/* TODO: get this from .msg-file */
content: '(wird entfernt)';
margin-left: 12px;
}
.checkbox {
margin-left: 12px;
}
}
.file-container__label {
opacity: 0.4;
}

View File

@ -3,71 +3,71 @@
<div .scrolltable>
<table .table.table--striped.table--hover.table--vertical>
<tr.table__row>
<th> _{MsgName}
<td> #{display userDisplayName}
<th .table__th> _{MsgName}
<td .table__td> #{display userDisplayName}
<tr.table__row>
<th> _{MsgMatrikelNr}
<td> #{display userMatrikelnummer}
<th .table__th> _{MsgMatrikelNr}
<td .table__td> #{display userMatrikelnummer}
<tr.table__row>
<th> _{MsgEMail}
<td> #{display userEmail}
<th .table__th> _{MsgEMail}
<td .table__td> #{display userEmail}
<tr.table__row>
<th> _{MsgIdent}
<td> #{display userIdent}
<th .table__th> _{MsgIdent}
<td .table__td> #{display userIdent}
<tr.table__row>
<th> _{MsgPlugin}
<td> #{display userPlugin}
<th .table__th> _{MsgPlugin}
<td .table__td> #{display userPlugin}
$if not $ null admin_rights
<tr.table__row>
<th> Administrator
<td>
<th .table__th> Administrator
<td .table__td>
<ul>
$forall institute <- admin_rights
<li>#{display institute}
$if not $ null lecturer_rights
<tr.table__row>
<th> Lehrberechtigt
<td>
<th .table__th> Lehrberechtigt
<td .table__td>
<ul>
$forall institute <- lecturer_rights
<li>#{display institute}
$if not $ null lecture_owner
<tr.table__row>
<th> Eigene Kurse
<td>
<th .table__th> Eigene Kurse
<td .table__td>
<ul>
$forall (E.Value csh, E.Value tid) <- lecture_owner
<li>
<a href=@{CourseR tid csh CShowR}>#{display tid} - #{csh}
$if not $ null lecture_corrector
<tr.table__row>
<th> Korrektor
<td>
<th .table__th> Korrektor
<td .table__td>
<ul>
$forall (E.Value csh, E.Value tid) <- lecture_corrector
<li>
<a href=@{CourseR tid csh CShowR}>#{display tid} - #{csh}
$if not $ null studies
<tr.table__row>
<th> Studiengänge
<td>
<th .table__th> Studiengänge
<td .table__td>
<table .table .table-striped .table-hover>
<tr.table__row>
<th> Abschluss
<th> Studiengang
<th> Studienart
<th> Semester
<th .table__th> Abschluss
<th .table__th> Studiengang
<th .table__th> Studienart
<th .table__th> Semester
$forall (degree,field,fieldtype,semester) <- studies
<tr.table__row>
<td> #{display degree}
<td> #{display field}
<td> #{display fieldtype}
<td> #{display semester}
<td .table__td> #{display degree}
<td .table__td> #{display field}
<td .table__td> #{display fieldtype}
<td .table__td> #{display semester}
$if not $ null participant
<tr.table__row>
<th> Teilnehmer
<td>
<th .table__th> Teilnehmer
<td .table__td>
<ul>
$forall (E.Value csh, E.Value tid, regSince) <- participant
<li>

17
templates/profile.julius Normal file
View File

@ -0,0 +1,17 @@
document.addEventListener('DOMContentLoaded', function () {
var themeSelector = document.querySelector('[placeholder="theme-select"]');
themeSelector.addEventListener('change', function() {
// get rid of old themes on body
var options = Array.from(themeSelector.options)
.forEach(function (option) {
document.body.classList.remove(optionToTheme(option));
});
// add newly selected theme
document.body.classList.add(optionToTheme(themeSelector.options[themeSelector.value - 1]));
});
function optionToTheme(option) {
return optionValue = 'theme--' + option.innerText.toLowerCase().trim().replace(/\s/g, '-');
}
});

View File

@ -13,6 +13,7 @@
.alerts {
top: 150px;
bottom: auto;
}
}

View File

@ -72,7 +72,7 @@
// adds eventlistener(s)
function addListener(container) {
input.addEventListener('change', function(event) {
container.classList.toggle('file-checkbox__container--checked', this.checked);
container.classList.toggle('file-container--checked', this.checked);
});
}
@ -80,18 +80,11 @@
function setup() {
var cont = input.parentNode;
while (cont !== document.body) {
if (cont.classList.contains('file-checkbox__container')) {
if (cont.matches('.file-container')) {
break;
}
cont = cont.parentNode;
}
// take care of properly moving elements
if (input.parentNode.classList.contains('checkbox')) {
input.parentNode.classList.add('file-checkbox__checkbox');
} else {
input.classList.add('file-checkbox__checkbox');
}
addListener(cont);
}
setup();

View File

@ -68,6 +68,7 @@ input[type*="time"] {
border: 1px solid transparent;
border-radius: 4px;
font-size: 1rem;
font-family: var(--font-base);
line-height: 1.5;
padding: 4px 13px;
}
@ -104,11 +105,12 @@ textarea {
width: 100%;
height: 170px;
max-width: 600px;
font-size: 1rem;
line-height: 1.5;
color: #363636;
background-color: #f3f3f3;
padding: 4px 13px;
font-size: 1rem;
font-family: var(--font-base);
-webkit-appearance: none;
appearance: none;
border: 1px solid #dbdbdb;

View File

@ -4,7 +4,7 @@
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
z-index: 1;
flex: 0 0 300px;
min-height: calc(100% - 80px);
min-height: calc(100% - var(--header-height));
transition: all .2s ease-out;
width: 24%;
@ -48,9 +48,15 @@
justify-content: flex-start;
align-items: center;
&:not(.asidenav__list-item--active):hover {
background-color: var(--color-darker);
> .asidenav__link-wrapper {
color: var(--color-lightwhite);
}
}
&:hover {
color: var(--color-link);
background-color: var(--color-lightwhite);
.asidenav__link-shorthand {
transform: scale(1.05, 1.0);
@ -58,10 +64,6 @@
text-shadow: none;
}
> .asidenav__link-wrapper {
color: var(--color-link);
}
.asidenav__nested-list {
transform: translateX(100%);
opacity: 1;
@ -103,13 +105,13 @@
padding: 7px 10px;
justify-content: flex-start;
color: var(--color-lightwhite);
width: 100%;
z-index: 1;
.glyphicon {
width: 50px;
}
.glyphicon + .asidenav__link-label {
padding-left: 0;
}
@ -143,15 +145,10 @@
background-color: var(--color-dark);
&:hover {
color: var(--color-link);
background-color: var(--color-lightwhite);
.asidenav__link-wrapper {
background-color: white;
color: var(--color-link);
}
background-color: var(--color-darker);
}
.asidenav__link-wrapper {
.asidenav__link-wrapper {
padding-left: 13px;
padding-right: 13px;
border-left: 20px solid white;
@ -167,7 +164,7 @@
width: 50px;
flex-basis: 50px;
overflow: hidden;
min-height: calc(100% - 50px);
min-height: calc(100% - var(--header-height-collapsed));
~ .main__content {
padding-left: 50px;
@ -194,7 +191,6 @@
flex-shrink: 0;
padding: 1px;
outline: 1px solid white;
text-transform: uppercase;
word-break: break-all;
align-items: center;
justify-content: center;

View File

@ -10,6 +10,12 @@
if (requireds.length == 0) {
return false;
}
if (typeof button.dataset.formnorequired !== 'undefined' && button.dataset.formnorequired !== null) {
button.addEventListener('click', function() {
form.submit();
});
return false;
}
updateButtonState();
requireds.forEach(function(el) {
@ -66,10 +72,10 @@ document.addEventListener('DOMContentLoaded', function() {
var forms = document.querySelectorAll('form');
Array.from(forms).forEach(function(form) {
// auto reactiveButton submit-buttons with required fields
var submitBtn = form.querySelector('[type=submit]');
if (submitBtn) {
var submitBtns = Array.from(form.querySelectorAll('[type=submit]'));
submitBtns.forEach(function(submitBtn) {
window.utils.reactiveButton(form, submitBtn, validateForm);
}
});
// auto conditonal fieldsets
var fieldSets = Array.from(form.querySelectorAll('fieldset[data-conditional-id][data-conditional-value]'));

View File

@ -1,3 +1,15 @@
.hidden {
display: none;
visibility: hidden;
height: 0;
opacity: 0;
}
fieldset {
border: 0;
margin: 20px 0 30px;
legend {
display: none;
}
}

View File

@ -4,7 +4,7 @@ $newline never
<a href="/" .navbar__logo>
<ul .navbar__list.list--inline>
<ul .navbar__list.list--inline.navbar__list-left>
$forall menuType <- menuTypes
$case menuType
$of NavbarAside (MenuItem label mIcon route _)

View File

@ -3,11 +3,9 @@
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
justify-content: flex-start;
width: 100%;
height: var(--header-height);
padding-right: 2vw;
padding-left: calc(24% + 40px);
background: var(--color-darker); /* Old browsers */
background: -moz-linear-gradient(bottom, var(--color-dark) 0%, var(--color-darker) 100%); /* FF3.6-15 */
background: -webkit-linear-gradient(bottom, var(--color-dark) 0%,var(--color-darker) 100%); /* Chrome10-25,Safari5.1-6 */
@ -21,13 +19,6 @@
transition: all .2s cubic-bezier(0.03, 0.43, 0.58, 1);
}
@media (min-width: 1200px) {
.navbar {
padding-left: 340px;
}
}
@media (max-width: 768px) {
.navbar {
@ -36,31 +27,71 @@
}
.navbar__logo {
position: absolute;
top: 15px;
top: 10px;
left: 20px;
transition: all .2s ease;
transform-origin: left;
width: 0px;
height: 80px;
padding: 0 20px;
display: flex;
flex-basis: 300px;
font-size: 16px;
align-items: center;
color: var(--color-lightwhite);
transform-origin: left;
transition: all .2s ease-out;
&:hover {
color: var(--color-lightwhite);
}
&::before {
content: 'Uni2work';
content: 'LMU';
font-family: var(--font-logo);
font-size: 42px;
font-weight: bold;
letter-spacing: 2px;
display: flex;
align-items: flex-end;
font-size: 30px;
min-width: 70px;
height: calc(100% - 4px);
padding: 0 6px 4px;
box-shadow: 0 0 0 1px inset var(--color-lmu-box-border);
}
&::after {
content: 'Uni2work';
margin-left: 12px;
font-weight: normal;
letter-spacing: 2px;
display: flex;
align-items: flex-end;
text-transform: uppercase;
width: 100%;
height: calc(100% - 4px);
padding: 0 6px 4px;
box-shadow: 0 0 0 1px inset var(--color-lmu-box-border);
}
}
@media (max-width: 1199px) {
.navbar__logo {
flex-basis: 24%;
font-size: 16px;
}
}
@media (max-width: 1024px) {
.navbar__logo {
transform: scale(0.7);
font-size: 14px;
&::before {
content: none;
}
&::after {
margin-left: 0;
}
}
}
@ -75,21 +106,30 @@
.navbar__link-wrapper {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
height: var(--header-height);
justify-content: flex-end;
align-items: flex-start;
height: 80px;
min-width: 90px;
color: var(--color-lightwhite);
transition: height .2s cubic-bezier(0.03, 0.43, 0.58, 1);
box-shadow: 0 0 0 1px inset var(--color-lmu-box-border);
}
.navbar__link-label {
transition: opacity .2s ease;
padding: 0 13px;
padding: 4px 6px;
text-transform: uppercase;
}
@media (max-width: 768px) {
.navbar__link-wrapper {
box-shadow: none;
min-width: 0;
align-items: center;
justify-content: center;
}
.navbar__link-label {
padding: 0 7px;
}
@ -105,6 +145,17 @@
/* navbar list */
.navbar__list {
white-space: nowrap;
+ .navbar__list {
margin-left: 12px;
}
}
@media (min-width: 768px) {
.navbar__list:last-of-type {
margin-right: 20px;
}
}
/* list item */
@ -112,6 +163,10 @@
position: relative;
transition: background-color .1s ease;
+ .navbar__list-item {
margin-left: 12px;
}
.glyphicon {
position: relative;
width: 20px;
@ -120,10 +175,22 @@
.glyphicon::before {
height: 20px;
margin-left: 6px;
}
.fas {
height: 20px;
margin-left: 8px;
}
}
@media (max-width: 768px) {
.navbar__list-item {
.fas {
margin-left: 0;
}
}
}
@ -134,15 +201,36 @@
}
}
.navbar__list-left {
flex: 5;
padding-left: 40px;
}
@media (max-width: 768px) {
.navbar__list-left {
padding-left: 0;
}
}
.navbar__list-item--secondary {
margin-left: 20px;
color: var(--color-grey);
.navbar__link-wrapper {
color: var(--color-grey);
box-shadow: 0 0 0 1px inset var(--color-grey);
}
}
@media (max-width: 768px) {
.navbar__list-item--secondary {
margin-left: 0;
.navbar__link-wrapper {
box-shadow: none;
}
}
}
@ -169,10 +257,6 @@
color: var(--color-lightwhite);
}
.navbar__list-item--secondary .navbar__link-wrapper {
color: var(--color-grey);
}
/* sticky state */
.navbar--sticky {
height: var(--header-height-collapsed);
@ -209,7 +293,7 @@
}
}
@media (max-height: 768px) {
@media (max-height: 500px) {
.navbar,
.navbar__pushdown {
@ -222,5 +306,6 @@
.navbar__logo {
top: 5px;
height: var(--header-height-collapsed);
}
}