From 321d39ace240f25afed665f9827890809daddc47 Mon Sep 17 00:00:00 2001 From: SJost Date: Fri, 15 Feb 2019 13:26:17 +0100 Subject: [PATCH] UX/UI [olish in various places --- assets/favicon-0.png | Bin 0 -> 1027 bytes assets/favicon-5.png | Bin 0 -> 557 bytes assets/logo.png | Bin 0 -> 6698 bytes messages/uniworx/de.msg | 11 +++-- src/Handler/Course.hs | 84 ++++++++++++++++++++-------------- src/Handler/Home.hs | 3 +- src/Handler/Utils/DateTime.hs | 20 +++++++- src/Model/Types.hs | 4 +- src/Utils.hs | 7 +++ templates/authpreds.hamlet | 1 + templates/infoLecturer.hamlet | 6 +-- 11 files changed, 91 insertions(+), 45 deletions(-) create mode 100644 assets/favicon-0.png create mode 100644 assets/favicon-5.png create mode 100644 assets/logo.png diff --git a/assets/favicon-0.png b/assets/favicon-0.png new file mode 100644 index 0000000000000000000000000000000000000000..68830769b8363c1ee3c0cfc7b9fc2e6b82ab5527 GIT binary patch literal 1027 zcmeAS@N?(olHy`uVBq!ia0y~yU<5K58911MRQ8&P5Fo{p?&#~tz_78O`%fY(kgt&J z5#-CjP^HGe(9pub@Czu^@PdJ%)PRBERRRNp)eHs(@q#(K0&Rd2IRQQ)u0Wb|vLokY zXU@qETvMF5raEy>a^jxo!~tYab`t1!;O=+e0&*uia8GjL0J0}Lb4_vts^OaA%r)78 z10)C*2dQ`D1dkB5x zzZWoQa7b_nxPSkAKth7T{qy%1Y*3ic-@l+>FY9NZYQ`jQcNb-?q#P>-2Bu0+7srr_ zTW{~44GMM?X}#zY@KZ2AS);3=@_&2Eztn@;HC8ScB$osI}XzP6T^L^MgqSpUKSHf^l zegSX!Kj%yL>(wqZRXaXn0VN<5P*LBYx8QTVYX8Z!6L}{vN`P^T=*1t6@O{Mi0R}i zhKKP+xhqWeKG?_|vv&f9f`SR=)-za+tT)}~4>Vo1#5JNMC9x#cD!C{XNHG{07+UHY z80i|Ch8S2_85mg^T4);>S{WF)gsG>aXvob^$xN$6XfO#eG_*1`urjoSXb94oBoA`G Mr>mdKI;Vst0OQ>(-2eap literal 0 HcmV?d00001 diff --git a/assets/favicon-5.png b/assets/favicon-5.png new file mode 100644 index 0000000000000000000000000000000000000000..5fb1fc3278b93df5c27ebdbf19dc6d7ffd241992 GIT binary patch literal 557 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 Ap8x;= literal 0 HcmV?d00001 diff --git a/messages/uniworx/de.msg b/messages/uniworx/de.msg index 7a04221e8..c5fe7c827 100644 --- a/messages/uniworx/de.msg +++ b/messages/uniworx/de.msg @@ -47,7 +47,7 @@ LectureStart: Beginn Vorlesungen Course: Kurs CourseShort: Kürzel CourseCapacity: Kapazität -CourseCapacityTip: Falls angegeben wird die Anzahl an Kursanmeldungen, die zugelassen werden, beschränkt +CourseCapacityTip: Anzahl erlaubter Kursanmeldungen, leer lassen für unbeschränkte Kurskapazität CourseNoCapacity: In diesem Kurs sind keine Plätze mehr frei. CourseNotEmpty: In diesem Kurs sind momentan Teilnehmer angemeldet. CourseRegisterOk: Sie wurden angemeldet @@ -75,14 +75,15 @@ CourseDescription: Beschreibung CourseDescriptionTip: Beliebiges HTML-Markup ist gestattet CourseHomepage: Homepage CourseShorthand: Kürzel -CourseShorthandUnique: Muss innerhalb des Semesters eindeutig sein +CourseShorthandUnique: Muss innerhalb Institut und Semester eindeutig sein CourseSemester: Semester CourseSchool: Institut CourseSchoolShort: Fach CourseSecretTip: Anmeldung zum Kurs erfordert Eingabe des Passworts, sofern gesetzt +CourseSecretFormat: beliebige Zeichenkette CourseRegisterFromTip: Ohne Datum ist KEINE eigenständige Anmeldung von Studierenden möglich -CourseRegisterToTip: Anmeldung darf auch ohne Begrenzung möglich sein -CourseDeregisterUntilTip: Abmeldung darf auch ohne Begrenzung möglich sein +CourseRegisterToTip: Anmeldung darf auch unbegrenzt offen bleiben +CourseDeregisterUntilTip: Abmeldung darf auch unbegrenzt erlaubt bleiben CourseFilterSearch: Volltext-Suche CourseFilterRegistered: Registriert CourseDeleteQuestion: Wollen Sie den unten aufgeführten Kurs wirklich löschen? @@ -342,6 +343,7 @@ LecturersFor: Dozenten UserListTitle: Komprehensive Benutzerliste AccessRightsSaved: Berechtigungsänderungen wurden gespeichert. +Date: Datum DateTimeFormat: Datums- und Uhrzeitformat DateFormat: Datumsformat TimeFormat: Uhrzeitformat @@ -603,6 +605,7 @@ MenuCorrectionsCreate: Abgaben registrieren MenuCorrectionsGrade: Abgaben bewerten MenuAuthPreds: Authorisierungseinstellungen +AuthPredsInfo: Um eigene Veranstaltungen aus Sicht der Teilnehmer anzusehen, können Veranstalter und Korrektoren hier die Prüfung ihrer erweiterten Berechtigungen temporär deaktivieren. Abgewählte Prädikate werden nicht geprüft um Zugriffe zu gewähren, welche andernfalls nicht erlaubt wären. Diese Einstellungen gelten nur temporär bis Ihre Sitzung abgelaufen ist (d.h. bis ihr Browser-Cookie abgelaufen ist). AuthPredsActive: Aktive Authorisierungsprädikate AuthPredsActiveChanged: Authorisierungseinstellungen für aktuelle Sitzung gespeichert AuthTagFree: Seite ist universell zugänglich diff --git a/src/Handler/Course.hs b/src/Handler/Course.hs index f0ed8bca7..3401cf4de 100644 --- a/src/Handler/Course.hs +++ b/src/Handler/Course.hs @@ -330,11 +330,14 @@ getCourseNewR = do <$> iopt termNewField "tid" <*> iopt ciField "ssh" <*> iopt ciField "csh" - let noTemplateAction = courseEditHandler True Nothing - case params of -- DO NOT REMOVE: without this distinction, lecturers would never see an empty newCourseForm any more! + + + let noTemplateAction = courseEditHandler Nothing + case params of -- DO NOT REMOVE: without this distinction, lecturers would never see an empty makeCourseForm any more! FormMissing -> noTemplateAction FormFailure msgs -> forM_ msgs (addMessage Error . toHtml) >> noTemplateAction + FormSuccess (Nothing, Nothing, Nothing) -> noTemplateAction FormSuccess (fmap TermKey -> mbTid, fmap SchoolKey -> mbSsh, mbCsh) -> do oldCourses <- runDB $ E.select $ E.from $ \course -> do @@ -378,21 +381,21 @@ getCourseNewR = do unless cshOk $ addMessageI Warning $ MsgNoSuchCourseShorthand $ fromJust mbCsh when (tidOk && sshOk && cshOk) $ addMessageI Warning MsgNoSuchCourse return Nothing - courseEditHandler True template + courseEditHandler template postCourseNewR :: Handler Html -postCourseNewR = courseEditHandler False Nothing -- Note: Nothing is safe here, since we will create a new course. +postCourseNewR = courseEditHandler Nothing -- Note: Nothing is safe here, since we will create a new course. getCEditR, postCEditR :: TermId -> SchoolId -> CourseShorthand -> Handler Html -getCEditR = pgCEditR True -postCEditR = pgCEditR False +getCEditR = pgCEditR +postCEditR = pgCEditR -pgCEditR :: Bool -> TermId -> SchoolId -> CourseShorthand -> Handler Html -pgCEditR isGetReq tid ssh csh = do +pgCEditR :: TermId -> SchoolId -> CourseShorthand -> Handler Html +pgCEditR tid ssh csh = do course <- runDB $ getBy $ TermSchoolCourseShort tid ssh csh -- IMPORTANT: both GET and POST Handler must use the same template, -- since an Edit is identified via CourseID, which is not embedded in the received form data for security reasons. - courseEditHandler isGetReq $ courseToForm <$> course + courseEditHandler $ courseToForm <$> course getCDeleteR, postCDeleteR :: TermId -> SchoolId -> CourseShorthand -> Handler Html @@ -408,10 +411,10 @@ postCDeleteR tid ssh csh = do -- | Course Creation and Editing -- | IMPORTANT: in case of Edit, Post/Get Request is provided with the same CourseForm template (cannot be Nothing), -- | since an edit is identified via cfCourseId which is not contained in the received form data for security reasons! -courseEditHandler :: Bool -> Maybe CourseForm -> Handler Html -- FIXME: _isGet is not used -courseEditHandler _isGet mbCourseForm = do +courseEditHandler :: Maybe CourseForm -> Handler Html +courseEditHandler mbCourseForm = do aid <- requireAuthId -- TODO: Verify that Editor is owner of the Course to be Edited!!! - ((result, formWidget), formEnctype) <- runFormPost $ newCourseForm mbCourseForm + ((result, formWidget), formEnctype) <- runFormPost $ makeCourseForm mbCourseForm case result of (FormSuccess res@CourseForm { cfCourseId = Nothing @@ -520,8 +523,13 @@ courseToForm (Entity cid Course{..}) = CourseForm , cfDeRegUntil = courseDeregisterUntil } -newCourseForm :: Maybe CourseForm -> Form CourseForm -newCourseForm template = identForm FIDcourse $ \html -> do +makeCourseForm :: Maybe CourseForm -> Form CourseForm +makeCourseForm template = identForm FIDcourse $ \html -> do + -- TODO: Refactor to avoid the four repeated calls to liftHandlerT and three runDBs + -- let editCid = cfCourseId =<< template -- possible start for refactoring + + mr <- liftHandlerT getMessageRender -- needed for translation of placeholders + userSchools <- liftHandlerT . runDB $ do userId <- liftHandlerT requireAuthId (fmap concat . sequence) @@ -529,9 +537,9 @@ newCourseForm template = identForm FIDcourse $ \html -> do , map (userAdminSchool . entityVal) <$> selectList [UserAdminUser ==. userId] [] ] - termsField <- liftHandlerT $ case template of + termsField <- case template of -- Change of term is only allowed if user may delete the course (i.e. no participants) or admin - (Just cform) | (Just cid) <- cfCourseId cform -> do -- edit existing course + (Just cform) | (Just cid) <- cfCourseId cform -> liftHandlerT $ do -- edit existing course _courseOld@Course{..} <- runDB $ get404 cid mayEditTerm <- isAuthorized TermEditR True mayDelete <- isAuthorized (CourseR courseTerm courseSchool courseShorthand CDeleteR) True @@ -539,29 +547,37 @@ newCourseForm template = identForm FIDcourse $ \html -> do | (mayEditTerm == Authorized) || (mayDelete == Authorized) -> termsAllowedField | otherwise -> termsSetField [cfTerm cform] _allOtherCases -> return termsAllowedField + + (newRegFrom,newRegTo,newDeRegUntil) <- case template of + (Just cform) | (Just _cid) <- cfCourseId cform -> return (Nothing,Nothing,Nothing) + _allIOtherCases -> do + mbLastTerm <- liftHandlerT $ runDB $ selectFirst [TermActive ==. True] [Desc TermName] + return ( (Just . toMidnight . termStart . entityVal) <$> mbLastTerm + , (Just . beforeMidnight . termEnd . entityVal) <$> mbLastTerm + , (Just . beforeMidnight . termEnd . entityVal) <$> mbLastTerm ) + (result, widget) <- flip (renderAForm FormStandard) html $ CourseForm <$> pure (cfCourseId =<< template) - <*> areq ciField (fslI MsgCourseName) (cfName <$> template) + <*> areq ciField (fslI MsgCourseName) (cfName <$> template) <*> aopt htmlField (fslI MsgCourseDescription - & setTooltip MsgCourseDescriptionTip) (cfDesc <$> template) - <*> aopt urlField (fslI MsgCourseHomepage) (cfLink <$> template) + & setTooltip MsgCourseDescriptionTip) (cfDesc <$> template) + <*> aopt urlField (fslI MsgCourseHomepage) (cfLink <$> template) <*> areq ciField (fslI MsgCourseShorthand -- & addAttr "disabled" "disabled" - & setTooltip MsgCourseShorthandUnique) - (cfShort <$> template) - <*> areq termsField (fslI MsgCourseSemester) (cfTerm <$> template) - <*> areq (schoolFieldFor userSchools) (fslI MsgCourseSchool) (cfSchool <$> template) - <*> aopt (natField "Kapazität") (fslI MsgCourseCapacity - & setTooltip MsgCourseCapacityTip) (cfCapacity <$> template) - <*> aopt textField (fslpI MsgCourseSecret "beliebige Zeichenkette" - & setTooltip MsgCourseSecretTip) (cfSecret <$> template) - <*> areq checkBoxField (fslI MsgMaterialFree) (cfMatFree <$> template) - <*> aopt utcTimeField (fslpI MsgRegisterFrom "Datum" - & setTooltip MsgCourseRegisterFromTip) (cfRegFrom <$> template) - <*> aopt utcTimeField (fslpI MsgRegisterTo "Datum" - & setTooltip MsgCourseRegisterToTip) (cfRegTo <$> template) - <*> aopt utcTimeField (fslpI MsgDeRegUntil "Datum" - & setTooltip MsgCourseDeregisterUntilTip) (cfDeRegUntil <$> template) + & setTooltip MsgCourseShorthandUnique) (cfShort <$> template) + <*> areq termsField (fslI MsgCourseSemester) (cfTerm <$> template) + <*> areq (schoolFieldFor userSchools) (fslI MsgCourseSchool) (cfSchool <$> template) + <*> aopt (natFieldI MsgCourseCapacity) (fslI MsgCourseCapacity + & setTooltip MsgCourseCapacityTip) (cfCapacity <$> template) + <*> aopt textField (fslpI MsgCourseSecret (mr MsgCourseSecretFormat) + & setTooltip MsgCourseSecretTip) (cfSecret <$> template) + <*> areq checkBoxField (fslI MsgMaterialFree) (cfMatFree <$> template) + <*> aopt utcTimeField (fslpI MsgRegisterFrom (mr MsgDate) + & setTooltip MsgCourseRegisterFromTip) (deepAlt (cfRegFrom <$> template) newRegFrom) + <*> aopt utcTimeField (fslpI MsgRegisterTo (mr MsgDate) + & setTooltip MsgCourseRegisterToTip) (deepAlt (cfRegTo <$> template) newRegTo) + <*> aopt utcTimeField (fslpI MsgDeRegUntil (mr MsgDate) + & setTooltip MsgCourseDeregisterUntilTip) (deepAlt (cfDeRegUntil <$> template) newDeRegUntil) <* submitButton return $ case result of FormSuccess courseResult diff --git a/src/Handler/Home.hs b/src/Handler/Home.hs index 1421ee515..f94023be3 100644 --- a/src/Handler/Home.hs +++ b/src/Handler/Home.hs @@ -259,6 +259,7 @@ getInfoLecturerR :: Handler Html getInfoLecturerR = siteLayoutMsg' MsgInfoLecturerTitle $ do setTitleI MsgInfoLecturerTitle + -- TODO: Translation. This is simply too much for a simple message and too akwward to cut into bits. Create i18nWidgetFile tool. $(widgetFile "infoLecturer") @@ -288,6 +289,6 @@ postAuthPredsR = do addMessageI Success MsgAuthPredsActiveChanged redirect $ fromMaybe AuthPredsR mReferer - defaultLayout $ do + siteLayoutMsg MsgAuthPredsActive $ do setTitleI MsgAuthPredsActive $(widgetFile "authpreds") diff --git a/src/Handler/Utils/DateTime.hs b/src/Handler/Utils/DateTime.hs index 4f87bd361..f67850fe2 100644 --- a/src/Handler/Utils/DateTime.hs +++ b/src/Handler/Utils/DateTime.hs @@ -1,6 +1,7 @@ module Handler.Utils.DateTime ( utcToLocalTime , localTimeToUTC, TZ.LocalToUTCResult(..) + , toMidnight, beforeMidnight, toMidday, toMorning , formatTime, formatTime', formatTimeW , getTimeLocale, getDateTimeFormat , validDateTimeFormats, dateTimeFormatOptions @@ -29,6 +30,24 @@ utcToLocalTime = TZ.utcToLocalTimeTZ appTZ localTimeToUTC :: LocalTime -> LocalToUTCResult localTimeToUTC = TZ.localTimeToUTCFull appTZ +-- | Local midnight of given day +toMidnight :: Day -> UTCTime +toMidnight d = localTimeToUTCTZ appTZ $ LocalTime d midnight + +-- | Local midnight of given day +toMidday :: Day -> UTCTime +toMidday d = localTimeToUTCTZ appTZ $ LocalTime d midday + +-- | One second before the end of day +beforeMidnight :: Day -> UTCTime +beforeMidnight d = localTimeToUTCTZ appTZ $ LocalTime d $ TimeOfDay 23 59 59 + +-- | 6am in the morning +toMorning :: Day -> UTCTime +toMorning d = localTimeToUTCTZ appTZ $ LocalTime d $ TimeOfDay 6 0 0 + + + class FormatTime t => HasLocalTime t where toLocalTime :: t -> LocalTime @@ -150,7 +169,6 @@ addWeeks n utct = localTimeToUTCTZ appTZ newLocal newDay = addDays (7*n) oldDay newLocal = oldLocal { localDay = newDay } - weeksToAdd :: UTCTime -> UTCTime -> Integer -- ^ Number of weeks needed to add so that first -- time occurs later than second time diff --git a/src/Model/Types.hs b/src/Model/Types.hs index c72254dbd..5c5e045ab 100644 --- a/src/Model/Types.hs +++ b/src/Model/Types.hs @@ -709,8 +709,7 @@ pseudonymFragments = folding data AuthTag - = AuthFree - | AuthAdmin + = AuthAdmin | AuthNoEscalation | AuthDeprecated | AuthDevelopment @@ -729,6 +728,7 @@ data AuthTag | AuthAuthentication | AuthRead | AuthWrite + | AuthFree deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic) instance Universe AuthTag diff --git a/src/Utils.hs b/src/Utils.hs index 2990778dc..d5dee863e 100644 --- a/src/Utils.hs +++ b/src/Utils.hs @@ -326,6 +326,13 @@ maybeAdd (Just x) (Just y) = Just (x + y) maybeAdd Nothing y = y maybeAdd x Nothing = x +-- | Deep alternative to avoid any occurrence of Nothing at all costs, left-biased +deepAlt :: Maybe (Maybe a) -> Maybe (Maybe a) -> Maybe (Maybe a) +deepAlt Nothing altSnd = altSnd +deepAlt altFst Nothing = altFst +deepAlt (Just Nothing) altSnd = altSnd +deepAlt altFst _ = altFst + maybeEmpty :: Monoid m => Maybe a -> (a -> m) -> m maybeEmpty = flip foldMap diff --git a/templates/authpreds.hamlet b/templates/authpreds.hamlet index d7430fbae..f9ba8cb05 100644 --- a/templates/authpreds.hamlet +++ b/templates/authpreds.hamlet @@ -1,3 +1,4 @@ +_{MsgAuthPredsInfo}
$maybe referer <- mReferer diff --git a/templates/infoLecturer.hamlet b/templates/infoLecturer.hamlet index fb9ee5863..dcb92c51c 100644 --- a/templates/infoLecturer.hamlet +++ b/templates/infoLecturer.hamlet @@ -10,13 +10,13 @@ hier die wichtigsten Neuerungen. Alle Veranstaltungen müssen ein Kürzel zur Identifikation besitzen, z.B. EiP, ProMo, SysPrak, etc.
- Das Kürzel muss innerhalb Institut und Semesters eindeutig sein. + Das Kürzel muss innerhalb Institut und Semester eindeutig sein.
Kurse klonen
Veranstalter können alle Kurse Ihres Instituts für das aktuelle Semesters klonen.
- Dabei werden vor allem Kurkürzel und die Kursbeschreibung übernommen; + Dabei werden vor allem Kurskürzel und die Kursbeschreibung übernommen; nicht jedoch Übungsblätter, Klausuren oder Anmeldungen.
Die Kursbeschreibung kann in Html verfasst werden und @@ -42,7 +42,7 @@ hier die wichtigsten Neuerungen.
Korrektoren
- Korrektoren werden ad hoc pro Übungsblatt vom Veranstalter festgelegt; + Korrektoren und Korrekturweise werden ad hoc pro Übungsblatt vom Veranstalter festgelegt; es gibt keine Korrektoren Eintragung in der Veranstaltungskonfiguration mehr. Für ein neues Blatt werden die Einstellung des vorangegangenen