Code clean; abandoned utf8 tickmark in favour of font-awesome checkmark

This commit is contained in:
SJost 2019-02-22 10:50:29 +01:00
parent 8d29354818
commit 0938d93039
14 changed files with 156 additions and 77 deletions

View File

@ -73,7 +73,7 @@ CourseMembersCountLimited num@Int64 max@Int64: #{display num}/#{display max}
CourseName: Name CourseName: Name
CourseDescription: Beschreibung CourseDescription: Beschreibung
CourseDescriptionTip: Beliebiges HTML-Markup ist gestattet CourseDescriptionTip: Beliebiges HTML-Markup ist gestattet
CourseHomepage: Homepage CourseHomepageExternal: Externe Homepage
CourseShorthand: Kürzel CourseShorthand: Kürzel
CourseShorthandUnique: Muss innerhalb Institut und Semester eindeutig sein CourseShorthandUnique: Muss innerhalb Institut und Semester eindeutig sein
CourseSemester: Semester CourseSemester: Semester
@ -582,6 +582,7 @@ ErrorCryptoIdMismatch: Verschlüsselte Id der Abgabe passte nicht zu anderen Dat
InvalidRoute: Konnte URL nicht interpretieren InvalidRoute: Konnte URL nicht interpretieren
MenuHome: Aktuell MenuHome: Aktuell
MenuInformation: Informationen
MenuImpressum: Impressum MenuImpressum: Impressum
MenuDataProt: Datenschutz MenuDataProt: Datenschutz
MenuVersion: Versionsgeschichte MenuVersion: Versionsgeschichte

View File

@ -1162,6 +1162,14 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
, menuItemModal = False , menuItemModal = False
, menuItemAccessCallback' = return True , menuItemAccessCallback' = return True
} }
, return MenuItem
{ menuItemType = Footer
, menuItemLabel = MsgMenuInformation
, menuItemIcon = Just "info"
, menuItemRoute = SomeRoute InfoR
, menuItemModal = False
, menuItemAccessCallback' = return True
}
, do , do
mCurrentRoute <- getCurrentRoute mCurrentRoute <- getCurrentRoute

View File

@ -44,7 +44,7 @@ colDescription = sortable Nothing mempty
$ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, _) } -> $ \DBRow{ dbrOutput=(Entity _ Course{..}, _, _, _) } ->
case courseDescription of case courseDescription of
Nothing -> mempty Nothing -> mempty
(Just descr) -> cell $ modal (commentWidget True) (Right $ toWidget descr) (Just descr) -> cell $ modal (toWidget $ hasComment True) (Right $ toWidget descr)
colCShort :: IsDBTable m a => Colonnade _ CourseTableData (DBCell m a) colCShort :: IsDBTable m a => Colonnade _ CourseTableData (DBCell m a)
colCShort = sortable (Just "cshort") (i18nCell MsgCourseShort) colCShort = sortable (Just "cshort") (i18nCell MsgCourseShort)
@ -564,9 +564,10 @@ makeCourseForm template = identForm FIDcourse $ \html -> do
(result, widget) <- flip (renderAForm FormStandard) html $ CourseForm (result, widget) <- flip (renderAForm FormStandard) html $ CourseForm
<$> pure (cfCourseId =<< template) <$> pure (cfCourseId =<< template)
<*> areq ciField (fslI MsgCourseName) (cfName <$> template) <*> areq ciField (fslI MsgCourseName) (cfName <$> template)
<*> aopt htmlField (fslI MsgCourseDescription <*> aopt htmlField (fslpI MsgCourseDescription "Bitte mindestens die Modulbeschreibung angeben"
& setTooltip MsgCourseDescriptionTip) (cfDesc <$> template) & setTooltip MsgCourseDescriptionTip) (cfDesc <$> template)
<*> aopt urlField (fslI MsgCourseHomepage) (cfLink <$> template) <*> aopt urlField (fslpI MsgCourseHomepageExternal "Optionale externe URL")
(cfLink <$> template)
<*> areq ciField (fslI MsgCourseShorthand <*> areq ciField (fslI MsgCourseShorthand
-- & addAttr "disabled" "disabled" -- & addAttr "disabled" "disabled"
& setTooltip MsgCourseShorthandUnique) (cfShort <$> template) & setTooltip MsgCourseShorthandUnique) (cfShort <$> template)
@ -671,7 +672,7 @@ colUserComment tid ssh csh =
sortable (Just "course-user-note") (i18nCell MsgCourseUserNote) sortable (Just "course-user-note") (i18nCell MsgCourseUserNote)
$ \DBRow{ dbrOutput=(Entity uid _, _, mbNoteKey) } -> $ \DBRow{ dbrOutput=(Entity uid _, _, mbNoteKey) } ->
maybeEmpty mbNoteKey $ const $ maybeEmpty mbNoteKey $ const $
anchorCellM (courseLink <$> encrypt uid) (commentWidget True) anchorCellM (courseLink <$> encrypt uid) (toWidget $ hasComment True)
where where
courseLink = CourseR tid ssh csh . CUserR courseLink = CourseR tid ssh csh . CUserR

View File

@ -137,7 +137,7 @@ homeUser uid = do
case mbsid of case mbsid of
Nothing -> mempty Nothing -> mempty
(Just sid) -> anchorCellM (CSubmissionR tid ssh csh shn <$> encrypt sid <*> pure SubShowR) (Just sid) -> anchorCellM (CSubmissionR tid ssh csh shn <$> encrypt sid <*> pure SubShowR)
tickmark (toWidget $ hasTickmark True)
] ]
let validator = def & defaultSorting [SortDescBy "done", SortAscBy "deadline"] let validator = def & defaultSorting [SortDescBy "done", SortAscBy "deadline"]
sheetTable <- runDB $ dbTableWidget' validator DBTable sheetTable <- runDB $ dbTableWidget' validator DBTable

View File

@ -10,18 +10,19 @@ import qualified Data.Set as Set
import qualified Data.List.NonEmpty as NonEmpty import qualified Data.List.NonEmpty as NonEmpty
import Handler.Utils import Handler.Utils
import Handler.Utils.Table.Cells
import Utils.Lens import Utils.Lens
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
htmlField' :: Field (HandlerT UniWorX IO) Html htmlField' :: Field (HandlerT UniWorX IO) Html
htmlField' = htmlField htmlField' = htmlField
{ fieldParse = \vs fis -> fieldParse htmlField (map Text.strip vs) fis { fieldParse = \vs fis -> fieldParse htmlField (map Text.strip vs) fis
} }
getMessageR, postMessageR :: CryptoUUIDSystemMessage -> Handler Html getMessageR, postMessageR :: CryptoUUIDSystemMessage -> Handler Html
getMessageR = postMessageR getMessageR = postMessageR
@ -88,7 +89,7 @@ postMessageR cID = do
] ]
addMessageI Success MsgSystemMessageEditTranslationSuccess addMessageI Success MsgSystemMessageEditTranslationSuccess
redirect $ MessageR cID redirect $ MessageR cID
let let
messageEditModal = modal [whamlet|_{MsgSystemMessageEdit}|] $ Right messageEditModal = modal [whamlet|_{MsgSystemMessageEdit}|] $ Right
[whamlet| [whamlet|
@ -113,7 +114,7 @@ postMessageR cID = do
maySubmit <- (== Authorized) <$> evalAccess (MessageR cID) True maySubmit <- (== Authorized) <$> evalAccess (MessageR cID) True
forms <- traverse (const mkForm) $ () <$ guard maySubmit forms <- traverse (const mkForm) $ () <$ guard maySubmit
defaultLayout defaultLayout
$(widgetFile "system-message") $(widgetFile "system-message")
where where

View File

@ -2,6 +2,7 @@ module Handler.Term where
import Import import Import
import Handler.Utils import Handler.Utils
import Handler.Utils.Table.Cells
import qualified Data.Map as Map import qualified Data.Map as Map
-- import qualified Data.Text as T -- import qualified Data.Text as T
@ -75,7 +76,7 @@ getTermShowR = do
, sortable (Just "lecture-end") "Ende Vorlesungen" $ \(Entity _ Term{..},_) -> , sortable (Just "lecture-end") "Ende Vorlesungen" $ \(Entity _ Term{..},_) ->
cell $ formatTime SelFormatDate termLectureEnd >>= toWidget cell $ formatTime SelFormatDate termLectureEnd >>= toWidget
, sortable Nothing "Aktiv" $ \(Entity _ Term{..},_) -> , sortable Nothing "Aktiv" $ \(Entity _ Term{..},_) ->
textCell (bool "" tickmark termActive :: Text) tickmarkCell termActive
, sortable Nothing "Kurse" $ \(_, E.Value numCourses) -> , sortable Nothing "Kurse" $ \(_, E.Value numCourses) ->
cell [whamlet|_{MsgNumCourses numCourses}|] cell [whamlet|_{MsgNumCourses numCourses}|]
, sortable (Just "start") "Semesteranfang" $ \(Entity _ Term{..},_) -> , sortable (Just "start") "Semesteranfang" $ \(Entity _ Term{..},_) ->

View File

@ -70,18 +70,3 @@ warnTermDays tid times = do
forM_ outoflecture $ warnI MsgDayIsOutOfLecture forM_ outoflecture $ warnI MsgDayIsOutOfLecture
forM_ outoftermdays $ warnI MsgDayIsOutOfTerm forM_ outoftermdays $ warnI MsgDayIsOutOfTerm
visibleWidget :: Bool -> Widget
-- ^ @visibleWidget False@ is an icon that denotes that something™ is not visible
visibleWidget True = mempty
visibleWidget False = [whamlet|<i .fas .fa-eye-slash>|]
isVisibleWidget :: Bool -> Widget
-- ^ @visibleWidget True@ is an icon that denotes that something™ is visible
isVisibleWidget True = [whamlet|<i .fas .fa-eye>|]
isVisibleWidget False = mempty
commentWidget :: Bool -> Widget
-- ^ @commentWidget True@ is an icon that denotes that something™ has a comment
commentWidget True = [whamlet|<i .fas .fa-comment-alt>|]
commentWidget False = mempty

View File

@ -12,7 +12,11 @@ import Handler.Utils
type CourseLink = (TermId, SchoolId, CourseShorthand) -- TODO: Refactor with WithHoles ! type CourseLink = (TermId, SchoolId, CourseShorthand) -- TODO: Refactor with WithHoles !
-------------------- ----------------
-- Some basic cells are defined in Handler.Utils.Table.Pagination
-- such as: i18nCell, cellTooltip, anchorCell for links, etc.
----------------
-- Special cells -- Special cells
tellCell :: (Monoid a, IsDBTable m a) => a -> DBCell m a -> DBCell m a tellCell :: (Monoid a, IsDBTable m a) => a -> DBCell m a -> DBCell m a
@ -27,6 +31,19 @@ indicatorCell = writerCell . tell $ Any True
writerCell :: IsDBTable m w => WriterT w m () -> DBCell m w writerCell :: IsDBTable m w => WriterT w m () -> DBCell m w
writerCell act = mempty & cellContents %~ (<* act) writerCell act = mempty & cellContents %~ (<* act)
---------------------
-- Icon cells
tickmarkCell :: (IsDBTable m a) => Bool -> DBCell m a
tickmarkCell = cell . toWidget . hasTickmark
commentCell :: IsDBTable m a => Maybe (Route UniWorX) -> DBCell m a
commentCell Nothing = mempty
commentCell (Just link) = anchorCell link icon
where icon = toWidget $ hasComment True
-----------------
-- Datatype cells -- Datatype cells
timeCell :: IsDBTable m a => UTCTime -> DBCell m a timeCell :: IsDBTable m a => UTCTime -> DBCell m a
timeCell t = cell $ formatTime SelFormatDateTime t >>= toWidget timeCell t = cell $ formatTime SelFormatDateTime t >>= toWidget
@ -128,10 +145,3 @@ correctorStateCell sc =
correctorLoadCell :: IsDBTable m a => SheetCorrector -> DBCell m a correctorLoadCell :: IsDBTable m a => SheetCorrector -> DBCell m a
correctorLoadCell sc = correctorLoadCell sc =
i18nCell $ sheetCorrectorLoad sc i18nCell $ sheetCorrectorLoad sc
commentCell :: IsDBTable m a => Maybe (Route UniWorX) -> DBCell m a
commentCell Nothing = mempty
commentCell (Just link) = anchorCell link icon
where
icon = commentWidget True

View File

@ -23,7 +23,7 @@ module Handler.Utils.Table.Pagination
, widgetColonnade, formColonnade, dbColonnade , widgetColonnade, formColonnade, dbColonnade
, cell, textCell, stringCell, i18nCell , cell, textCell, stringCell, i18nCell
, anchorCell, anchorCell', anchorCellM, anchorCellM' , anchorCell, anchorCell', anchorCellM, anchorCellM'
, tickmarkCell, cellTooltip , cellTooltip
, listCell , listCell
, formCell, DBFormResult, getDBFormResult , formCell, DBFormResult, getDBFormResult
, dbRow, dbSelect , dbRow, dbSelect
@ -780,7 +780,8 @@ pagesizeField psLim = selectField $ do
return . toOptionList . toNullable $ pagesizeOptions psLim return . toOptionList . toNullable $ pagesizeOptions psLim
--- DBCell utility functions ---------------------------------------------------------------
--- DBCell utility functions, more in Handler.Utils.Table.Cells
cell :: IsDBTable m a => Widget -> DBCell m a cell :: IsDBTable m a => Widget -> DBCell m a
cell wgt = dbCell # ([], return wgt) cell wgt = dbCell # ([], return wgt)
@ -794,10 +795,6 @@ i18nCell msg = cell $ do
mr <- getMessageRender mr <- getMessageRender
toWidget $ mr msg toWidget $ mr msg
tickmarkCell :: (IsDBTable m a) => Bool -> DBCell m a
tickmarkCell True = textCell (tickmark :: Text)
tickmarkCell False = mempty
cellTooltip :: (RenderMessage UniWorX msg, IsDBTable m a) => msg -> DBCell m a -> DBCell m a cellTooltip :: (RenderMessage UniWorX msg, IsDBTable m a) => msg -> DBCell m a -> DBCell m a
cellTooltip msg = cellContents.mapped %~ (<> tipWdgt) cellTooltip msg = cellContents.mapped %~ (<> tipWdgt)
where where
@ -807,7 +804,6 @@ cellTooltip msg = cellContents.mapped %~ (<> tipWdgt)
<div .tooltip__content>_{msg} <div .tooltip__content>_{msg}
|] |]
anchorCell :: IsDBTable m a => Route UniWorX -> Widget -> DBCell m a anchorCell :: IsDBTable m a => Route UniWorX -> Widget -> DBCell m a
anchorCell = anchorCellM . return anchorCell = anchorCellM . return

View File

@ -123,17 +123,51 @@ instance HasRoute site (SomeRoute site) where
urlRoute (SomeRoute url) = urlRoute url urlRoute (SomeRoute url) = urlRoute url
-- | A @Widget@ for any site; no language interpolation, etc.
type WidgetSiteless = forall site. forall m. (MonadIO m, MonadThrow m, MonadBaseControl IO m)
=> WidgetT site m ()
-----------
-- Icons --
-----------
isVisible :: Bool -> Markup
-- ^ Display an icon that denotes that something™ is visible or invisible
isVisible True = [shamlet|<i .fas .fa-eye>|]
isVisible False = [shamlet|<i .fas .fa-eye-slash>|]
--
-- For documentation on how to avoid these unneccessary functions
-- we implement them here just once for the first icon:
--
isVisibleWidget :: Bool -> WidgetSiteless
-- ^ Widget having an icon that denotes that something™ is visible or invisible
isVisibleWidget = toWidget . isVisible
maybeIsVisibleWidget :: Maybe Bool -> WidgetSiteless
-- ^ Maybe a widget with an icon that denotes that something™ is visible or invisible
maybeIsVisibleWidget = toWidget . foldMap isVisible
-- Other _frequently_ used icons:
hasComment :: Bool -> Markup
-- ^ Display an icon that denotes that something™ has a comment or not
hasComment True = [shamlet|<i .fas .fa-comment-alt>|]
hasComment False = [shamlet|<i .fas .fa-comment-slash>|] -- comment-alt-slash is not available for free
hasTickmark :: Bool -> Markup
-- ^ Display an icon that denotes that something™ is okay
hasTickmark True = [shamlet|<i .fas .fa-check>|]
hasTickmark False = mempty
--------------------- ---------------------
-- Text and String -- -- Text and String --
--------------------- ---------------------
tickmark :: IsString a => a -- DEPRECATED: use hasTickmark instead;
tickmark = fromString "" -- maybe reinstate if needed for @bewertung.txt@ files
-- Avoid annoying warnings:
tickmarkS :: String -- tickmark :: IsString a => a
tickmarkS = tickmark -- tickmark = fromString "✔"
tickmarkT :: Text
tickmarkT = tickmark
text2Html :: Text -> Html text2Html :: Text -> Html
text2Html = toHtml -- prevents ambiguous types text2Html = toHtml -- prevents ambiguous types

View File

@ -37,4 +37,4 @@
<li> <li>
^{modal "Email-Test" (Right emailWidget')} ^{modal "Email-Test" (Right emailWidget')}
<li> <li>
^{visibleWidget False} Some icons: ^{isVisible False} ^{hasComment True}

View File

@ -1,7 +1,6 @@
<div .container> <div .container>
<section> <section>
$# <h2>Stand <h2>Stand 19.02.2019
$# <h3>Version 0.91 vom 22.5.2018
<p> <p>
Die LMU unterliegt als Körperschaft des öffentlichen Rechts dem Die LMU unterliegt als Körperschaft des öffentlichen Rechts dem
bayerischen Datenschutzgesetz, in einigen Bereichen dem Bundesdatenschutzgesetz, bayerischen Datenschutzgesetz, in einigen Bereichen dem Bundesdatenschutzgesetz,

View File

@ -1,40 +1,79 @@
UniWorX erfahrene Veranstalter finden UniWorX erfahrene Veranstalter finden
hier die wichtigsten Neuerungen. hier die wichtigsten Neuerungen.
<section>
<h2>Bekannte Probleme in Bearbeitung
<dl .deflist>
$#
$# MOVE ITEM TO SECTION "VERANSTALTUNGEN", once it is implemented:
$#
<dt .deflist__dt> Kurs Assistenten
<dd .deflist__dd>
Momentan ist leider nur ein Dozent/Veranstalter pro Kurs erlaubt.
<p>
<h4>Folgendes ist in Vorbereitung:
Kurs-Veranstalter dürfen <em>beliebige</em> Personen
ebenfalls zu Veranstaltern des Kurses machen.
Innerhalb des Kurses haben alle Kurs-Veranstalter die
gleichen Befugnisse und können insbesondere auch die
Liste der Veranstalter dieses Kurses bearbeiten.
<p>
<h4>Unterschied zu UniWorX:
In Uni2work gibt es die Rollen "Dozent"
und "Veranstalter":
Dozenten dürfen im Wesentlichen neue Kurse erstellen.
Veranstalter haben vollen Zugriff auf einen speziellen Kurs.
Die Dozenten Berechtigung wird nach Instituten unterschieden.
<p>
In UniWorX gab es die Rolle "Assistent",
d.h. alle "Veranstalter" mussten auch "Dozent" sein;
eine Unterscheidung nach Instituten gab es nicht.
<dt .deflist__dt> Kurs Teilnehmer
<dd .deflist__dd>
Anzeige und Benachrichtigung angemeldeter
Kurs-Teilnehmer ist leider noch nicht fertig implementiert.
Voraussichtlich vor Start des Sommersemesters 2019 verfügbar.
<section> <section>
<h2>Veranstaltungen <h2>Veranstaltungen
<dl .deflist> <dl .deflist>
<dt .deflist__dt> Kurskürzel <dt .deflist__dt> Kurskürzel
<dd .deflist__dd> <dd .deflist__dd>
Alle Veranstaltungen müssen ein Kürzel zur Identifikation besitzen, <p>
z.B. EiP, ProMo, SysPrak, etc. Alle Veranstaltungen müssen ein Kürzel zur Identifikation besitzen,
<br> z.B. EiP, ProMo, SysPrak, etc.
Das Kürzel muss innerhalb Institut und Semester eindeutig sein. <p>
Das Kürzel muss innerhalb Institut und Semester eindeutig sein.
<dt .deflist__dt> Kurse klonen <dt .deflist__dt> Kurse klonen
<dd .deflist__dd> <dd .deflist__dd>
Veranstalter können <em>alle</em> Kurse Ihres Instituts für das aktuelle Semesters klonen. <p>
<br> Veranstalter können <em>alle</em> Kurse Ihres Instituts für das aktuelle Semesters klonen.
Dabei werden vor allem Kurskürzel und die Kursbeschreibung übernommen;
nicht jedoch Übungsblätter, Klausuren oder Anmeldungen.
<br>
Die Kursbeschreibung kann in Html verfasst werden und
<em>sollte die Modulbeschreibung enthalten!
<dt .deflist__dt> Passwort Dabei werden vor allem Kurskürzel und die Kursbeschreibung übernommen;
<dd .deflist__dd> Die Anmeldung zum Kurs kann durch ein Passwort geschützt werden. nicht jedoch Übungsblätter, Klausuren oder Anmeldungen.
<pr>
Die Kursbeschreibung kann in Html verfasst werden und
<em>sollte die Modulbeschreibung enthalten!
<dt .deflist__dt> Materialzugriff <dt .deflist__dt> Materialzugriff
<dd .deflist__dd> <dd .deflist__dd>
Der Zugriff auf Übungsblätter, Folien und andere Materialien Der Zugriff auf Übungsblätter, Folien und andere Materialien
kann von der Anmeldung zum Kurs abhängig gemacht werden. kann von der Anmeldung zum Kurs abhängig gemacht werden.
<dt .deflist__dt> Teilnehmer <dt .deflist__dt> Kurs Passwort
<dd .deflist__dd> <dd .deflist__dd> Die Anmeldung zum Kurs kann durch ein Passwort geschützt werden.
Anzeige und Benachrichtigung angemeldeter
Teilnehmer ist leider noch nicht fertig implementiert.
Voraussichtlich noch vor Start des Sommersemesters 2019 verfügbar.
<section> <section>
<h2>Übungsbetrieb <h2>Übungsbetrieb
@ -53,7 +92,7 @@ hier die wichtigsten Neuerungen.
<dt .deflist__dt> Verteilung <dt .deflist__dt> Verteilung
<dd .deflist__dd> <dd .deflist__dd>
Korrektoren können pro Blatt auch als Abwesend oder Entschuldigt Korrektoren können pro Blatt auch als Abwesend oder Entschuldigt
markiert werden und bekommen dann keine Abgaben zugeteilt. markiert werden und bekommen dann keine Abgaben automatisch zugeteilt.
Abwesende Korrektoren bekommen in späteren Blättern Abwesende Korrektoren bekommen in späteren Blättern
mehr Abgaben zugeteilt, entsprechend ihres mehr Abgaben zugeteilt, entsprechend ihres
@ -75,15 +114,19 @@ hier die wichtigsten Neuerungen.
<dt .deflist__dt> Sichtbarkeit <dt .deflist__dt> Sichtbarkeit
<dd .deflist__dd> <dd .deflist__dd>
Übungsblätter können bis zu einem Datum vor den Teilnehmern versteckt werden. Übungsblätter können bis zu einem Datum vor den Teilnehmern versteckt werden.
<p>
Die Aufgabenstellung ist erst mit Eröffnung der Abgabe erhältlich,
so wie bisher in UniWorX auch.
<dt .deflist__dt> Zeitstempel <dt .deflist__dt> Zeitstempel
<dd .deflist__dd> <dd .deflist__dd>
Alle Dateien eines Übungsblattes sind mit einem <p>
für Teilnehmer sichtbaren Zeitstempel versehen. Alle Dateien eines Übungsblattes sind mit einem
<br> für Teilnehmer sichtbaren Zeitstempel versehen.
Eine visuelle Hervorhebung geänderter/neuer Dateien <p>
und entsprechende Benachrichtigungen sind geplant, Eine visuelle Hervorhebung geänderter/neuer Dateien
aber noch nicht verfügbar. und entsprechende Benachrichtigungen sind geplant,
aber noch nicht verfügbar.
<dt .deflist__dt> Übungsgruppen <dt .deflist__dt> Übungsgruppen
<dd .deflist__dd> <dd .deflist__dd>

View File

@ -18,4 +18,4 @@ $maybe points <- submissionRatingPoints
_{MsgNotPassed} _{MsgNotPassed}
, _{SheetTypeHeader sheetType} , _{SheetTypeHeader sheetType}
$nothing $nothing
#{tickmarkS} #{hasTickmark True}