Initial attempt; does not type

This commit is contained in:
SJost 2018-09-03 13:58:08 +02:00
parent 262a5dca2b
commit eda8289ce7
3 changed files with 177 additions and 209 deletions

View File

@ -1,6 +1,7 @@
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
@ -13,7 +14,7 @@ import Handler.Utils
-- import Colonnade hiding (fromMaybe, singleton)
-- import Yesod.Colonnade
import qualified Data.Map as Map
import qualified Database.Esqueleto as E
import Database.Esqueleto ((^.))
@ -139,11 +140,42 @@ postProfileR = do
getProfileR
getProfileDataR :: Handler Html
getProfileDataR = do
(_uid, User{..}) <- requireAuthPair
(uid, User{..}) <- requireAuthPair
-- mr <- getMessageRender
-- Tabelle mit allen Teilnehmer: Kurs (link), Datum
courseTable <- do
let courseCol :: IsDBTable m a => Colonnade Sortable (DBRow (Entity Course, Entity CourseParticipant)) (DBCell m a)
courseCol = sortable (Just "course") (i18nCell MsgCourse) $
\DBRow{ dbrOutput = (Entity {entityVal=Course{..}}, _participant) } ->
anchorCell (CourseR courseTerm courseSchool courseShorthand CShowR)
(toWidget courseName)
courseData :: (E.InnerJoin (E.SqlExpr (Entity Course)) (E.SqlExpr (Entity CourseParticipant)))
-> E.SqlQuery (E.SqlExpr (Entity Course), E.SqlExpr (Entity CourseParticipant))
courseData = \(course `E.InnerJoin` participant) -> do
E.on $ course E.^. CourseId E.==. participant E.^. CourseParticipantCourse
E.where_ $ participant E.^. CourseParticipantUser E.==. E.val uid
return (course, participant)
dbTable def $ DBTable
{ dbtIdent = "courseMembership" :: Text
, dbtSQLQuery = courseData
, dbtColonnade = mconcat
[ courseCol
]
, dbtProj = return
, dbtSorting = mempty -- Map.fromList []
, dbtFilter = mempty -- Map.fromList []
, dbtStyle = def
}
-- Tabelle mit allen Abgaben und Abgabe-Gruppen
-- Tabelle mit allen Korrektor-Aufgaben
-- Tabelle mit allen Tutorials
-- Tabelle mit allen Klausuren und Noten
defaultLayout $ do
$(widgetFile "profileData")
$(widgetFile "dsgvDisclaimer")

View File

@ -8,6 +8,11 @@
<em> TODO: Hier alle Daten in Tabellen anzeigen!
<div .container>
<h2> Kursanmeldungen
<div .container>
^{courseTable}
<h2>
<em> TODO: Knopf zum Löschen aller Daten erstellen
@ -19,7 +24,7 @@
Alle Daten des Systems werden nach Abschluss des Testbetriebs von Uni2work
unwiderruflich gelöscht werden! (Voraussichtlich ein paar Wochen vor Beginn des Wintersemesters 18/19, spätestens aber im Dezember 2018.)
<li>
Nicht aufgeführt sind Zeitstempel mit Benutzerinformationen, z.B. bei der Editierung und Korrekturen von Übungen, Übungsgruppenleiterschaft, Raumbuchungen, etc.
Nicht aufgeführt sind Zeitstempel mit Benutzerinformationen, z.B. bei der Editierung und Korrektur von Übungen, Übungsgruppenleiterschaft, Raumbuchungen, etc.
<li>
Benutzerdaten bleiben so lange gespeichert, bis ein Institutsadministrator über die Exmatrikulation informiert wurde. Dann wird der Account gelöscht.
Abgaben/Bonuspunkte werden unwiderruflich gelöscht.

View File

@ -23,7 +23,7 @@
"file": "src/Application.hs",
"settings":
{
"buffer_size": 7271,
"buffer_size": 8177,
"line_ending": "Unix"
}
},
@ -31,7 +31,7 @@
"file": "src/Foundation.hs",
"settings":
{
"buffer_size": 11626,
"buffer_size": 55270,
"encoding": "UTF-8",
"line_ending": "Unix"
}
@ -40,27 +40,7 @@
"file": "src/Import.hs",
"settings":
{
"buffer_size": 125,
"line_ending": "Unix"
}
},
{
"file": "src/Model.hs",
"settings":
{
"buffer_size": 886,
"line_ending": "Unix"
}
},
{
"contents": "{-# LANGUAGE RecordWildCards #-}\n{-# LANGUAGE PatternGuards #-}\n{-# LANGUAGE TemplateHaskell #-}\n{-# LANGUAGE NoImplicitPrelude #-}\n{-# LANGUAGE OverloadedStrings #-}\n{-# LANGUAGE DeriveGeneric, DeriveDataTypeable #-}\nmodule Model.Types where\n\nimport ClassyPrelude\n\nimport Database.Persist.TH\nimport Database.Persist.Class\nimport Database.Persist.Sql\n\nimport Web.HttpApiData\n\nimport Data.Text (Text)\nimport qualified Data.Text as Text\n\nimport Text.Read (readMaybe)\n\n-- import Data.CaseInsensitive (CI)\nimport qualified Data.CaseInsensitive as CI\n\nimport Yesod.Core.Dispatch (PathPiece(..))\nimport Data.Aeson (FromJSON(..), ToJSON(..), withText, Value(..))\n\nimport GHC.Generics (Generic)\nimport Data.Typeable (Typeable)\n\n\ndata SheetType = Regular | Bonus | Extra \n deriving (Show, Read, Eq, Ord, Enum, Bounded) \nderivePersistField \"SheetType\"\n\ndata ExamStatus = Attended | NoShow | Voided\n deriving (Show, Read, Eq, Ord, Enum, Bounded) \nderivePersistField \"ExamStatus\"\n\n\ndata Season = Summer | Winter\n deriving (Show, Read, Eq, Ord, Enum, Bounded, Generic, Typeable)\n\nseasonToChar :: Season -> Char\nseasonToChar Summer = 'S'\nseasonToChar Winter = 'W'\n\nseasonFromChar :: Char -> Either Text Season\nseasonFromChar c\n | c ~= 'S' = Right Summer\n | c ~= 'W' = Right Winter\n | otherwise = Left $ \"Invalid season character: \" <> tshow c <> \"\"\n where\n (~=) = (==) `on` CI.mk\n\ndata TermIdentifier = TermIdentifier\n { year :: Integer -- ^ Using 'Integer' to model years is consistent with 'Data.Time.Calendar'\n , season :: Season\n } deriving (Show, Read, Eq, Ord, Generic, Typeable)\n\ntermToText :: TermIdentifier -> Text\ntermToText TermIdentifier{..} = Text.pack $ seasonToChar season : show year\n\ntermFromText :: Text -> Either Text TermIdentifier\ntermFromText t\n | (s:ys) <- Text.unpack t\n , Just year <- readMaybe ys\n , Right season <- seasonFromChar s\n = Right TermIdentifier{..}\n | otherwise = Left $ \"Invalid TermIdentifier: “\" <> t <> \"”\"\n\ninstance PersistField TermIdentifier where\n toPersistValue = PersistText . termToText\n fromPersistValue (PersistText t) = termFromText t\n fromPersistValue x = Left $ \"Expected TermIdentifier, received: \" <> tshow x\n\ninstance PersistFieldSql TermIdentifier where\n sqlType _ = SqlString\n\ninstance ToHttpApiData TermIdentifier where\n toUrlPiece = termToText\n\ninstance FromHttpApiData TermIdentifier where\n parseUrlPiece = termFromText\n\ninstance PathPiece TermIdentifier where\n fromPathPiece = either (const Nothing) Just . termFromText\n toPathPiece = termToText\n\ninstance ToJSON TermIdentifier where\n toJSON = String . termToText\n\ninstance FromJSON TermIdentifier where\n parseJSON = withText \"Term\" $ either (fail . Text.unpack) return . termFromText\n\ninstance Class Data where\n func = \n",
"file": "src/Model/Types.hs",
"file_size": 2724,
"file_write_time": 131516115030281923,
"settings":
{
"buffer_size": 2753,
"encoding": "UTF-8",
"buffer_size": 126,
"line_ending": "Unix"
}
},
@ -68,7 +48,7 @@
"file": "src/Settings.hs",
"settings":
{
"buffer_size": 5994,
"buffer_size": 9044,
"line_ending": "Unix"
}
},
@ -84,25 +64,7 @@
"file": "src/Handler/Home.hs",
"settings":
{
"buffer_size": 2324,
"line_ending": "Unix"
}
},
{
"file": "src/Handler/Assist.hs",
"settings":
{
"buffer_size": 2858,
"encoding": "UTF-8",
"line_ending": "Unix"
}
},
{
"file": "templates/newcourse.hamlet",
"settings":
{
"buffer_size": 606,
"encoding": "UTF-8",
"buffer_size": 11101,
"line_ending": "Unix"
}
},
@ -110,7 +72,7 @@
"file": "src/Handler/Profile.hs",
"settings":
{
"buffer_size": 411,
"buffer_size": 6956,
"line_ending": "Unix"
}
},
@ -118,7 +80,7 @@
"file": "models",
"settings":
{
"buffer_size": 4388,
"buffer_size": 6708,
"encoding": "UTF-8",
"line_ending": "Unix"
}
@ -127,7 +89,24 @@
"file": "stack.yaml",
"settings":
{
"buffer_size": 2233,
"buffer_size": 706,
"line_ending": "Unix"
}
},
{
"file": "src/Model.hs",
"settings":
{
"buffer_size": 1432,
"line_ending": "Unix"
}
},
{
"file": "src/Model/Types.hs",
"settings":
{
"buffer_size": 13229,
"encoding": "UTF-8",
"line_ending": "Unix"
}
}
@ -166,11 +145,13 @@
},
"file_history":
[
"/home/jost/programming/Haskell/Yesod/uniworx/templates/newcourse.hamlet",
"/home/jost/programming/Haskell/Yesod/uniworx/src/Handler/Assist.hs",
"/home/jost/programming/Haskell/Yesod/uniworx/src/Handler/Comment.hs"
],
"find":
{
"height": 52.0
"height": 35.2588147037
},
"find_in_files":
{
@ -210,7 +191,7 @@
"groups":
[
{
"selected": 8,
"selected": 10,
"sheets":
[
{
@ -219,7 +200,7 @@
"semi_transient": false,
"settings":
{
"buffer_size": 7271,
"buffer_size": 8177,
"regions":
{
},
@ -240,7 +221,7 @@
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 12,
"stack_index": 10,
"type": "text"
},
{
@ -249,15 +230,15 @@
"semi_transient": false,
"settings":
{
"buffer_size": 11626,
"buffer_size": 55270,
"regions":
{
},
"selection":
[
[
9330,
9330
0,
0
]
],
"settings":
@ -267,10 +248,10 @@
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 5125.0,
"translation.y": 5125.28132033,
"zoom_level": 1.0
},
"stack_index": 6,
"stack_index": 5,
"type": "text"
},
{
@ -279,7 +260,7 @@
"semi_transient": false,
"settings":
{
"buffer_size": 125,
"buffer_size": 126,
"regions":
{
},
@ -298,82 +279,24 @@
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 5,
"type": "text"
},
{
"buffer": 3,
"file": "src/Model.hs",
"semi_transient": false,
"settings":
{
"buffer_size": 886,
"regions":
{
},
"selection":
[
[
0,
0
]
],
"settings":
{
"syntax": "Packages/Haskell/Haskell.sublime-syntax"
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 2,
"type": "text"
},
{
"buffer": 4,
"file": "src/Model/Types.hs",
"semi_transient": false,
"settings":
{
"buffer_size": 2753,
"regions":
{
},
"selection":
[
[
2726,
2731
]
],
"settings":
{
"syntax": "Packages/Haskell/Haskell.sublime-syntax",
"tab_size": 2,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 1380.0,
"zoom_level": 1.0
},
"stack_index": 1,
"type": "text"
},
{
"buffer": 5,
"buffer": 3,
"file": "src/Settings.hs",
"semi_transient": false,
"settings":
{
"buffer_size": 5994,
"buffer_size": 9044,
"regions":
{
},
"selection":
[
[
104,
104
0,
0
]
],
"settings":
@ -386,11 +309,11 @@
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 11,
"stack_index": 9,
"type": "text"
},
{
"buffer": 6,
"buffer": 4,
"file": "src/Handler/Common.hs",
"semi_transient": false,
"settings":
@ -414,24 +337,24 @@
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 10,
"stack_index": 8,
"type": "text"
},
{
"buffer": 7,
"buffer": 5,
"file": "src/Handler/Home.hs",
"semi_transient": false,
"settings":
{
"buffer_size": 2324,
"buffer_size": 11101,
"regions":
{
},
"selection":
[
[
404,
404
0,
0
]
],
"settings":
@ -441,49 +364,47 @@
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 138.0,
"translation.y": 138.034508627,
"zoom_level": 1.0
},
"stack_index": 7,
"stack_index": 3,
"type": "text"
},
{
"buffer": 8,
"file": "src/Handler/Assist.hs",
"buffer": 6,
"file": "src/Handler/Profile.hs",
"semi_transient": false,
"settings":
{
"buffer_size": 2858,
"buffer_size": 6956,
"regions":
{
},
"selection":
[
[
454,
454
0,
0
]
],
"settings":
{
"syntax": "Packages/Haskell/Haskell.sublime-syntax",
"tab_size": 4,
"translate_tabs_to_spaces": true
"syntax": "Packages/Haskell/Haskell.sublime-syntax"
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 0,
"stack_index": 6,
"type": "text"
},
{
"buffer": 9,
"file": "templates/newcourse.hamlet",
"buffer": 7,
"file": "models",
"semi_transient": false,
"settings":
{
"buffer_size": 606,
"buffer_size": 6708,
"regions":
{
},
@ -497,89 +418,31 @@
"settings":
{
"syntax": "Packages/Text/Plain text.tmLanguage",
"tab_size": 4,
"tab_size": 2,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 0.0,
"translation.y": 138.034508627,
"zoom_level": 1.0
},
"stack_index": 4,
"type": "text"
},
{
"buffer": 10,
"file": "src/Handler/Profile.hs",
"semi_transient": false,
"settings":
{
"buffer_size": 411,
"regions":
{
},
"selection":
[
[
213,
213
]
],
"settings":
{
"syntax": "Packages/Haskell/Haskell.sublime-syntax"
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 8,
"type": "text"
},
{
"buffer": 11,
"file": "models",
"semi_transient": false,
"settings":
{
"buffer_size": 4388,
"regions":
{
},
"selection":
[
[
747,
747
]
],
"settings":
{
"syntax": "Packages/Text/Plain text.tmLanguage",
"tab_size": 2,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 138.0,
"zoom_level": 1.0
},
"stack_index": 3,
"type": "text"
},
{
"buffer": 12,
"buffer": 8,
"file": "stack.yaml",
"semi_transient": false,
"settings":
{
"buffer_size": 2233,
"buffer_size": 706,
"regions":
{
},
"selection":
[
[
663,
663
0,
0
]
],
"settings":
@ -590,7 +453,65 @@
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 9,
"stack_index": 7,
"type": "text"
},
{
"buffer": 9,
"file": "src/Model.hs",
"semi_transient": false,
"settings":
{
"buffer_size": 1432,
"regions":
{
},
"selection":
[
[
0,
0
]
],
"settings":
{
"syntax": "Packages/Haskell/Haskell.sublime-syntax"
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 2,
"type": "text"
},
{
"buffer": 10,
"file": "src/Model/Types.hs",
"semi_transient": false,
"settings":
{
"buffer_size": 13229,
"regions":
{
},
"selection":
[
[
0,
0
]
],
"settings":
{
"syntax": "Packages/Haskell/Haskell.sublime-syntax",
"tab_size": 2,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 1380.34508627,
"zoom_level": 1.0
},
"stack_index": 0,
"type": "text"
}
]
@ -598,7 +519,7 @@
],
"incremental_find":
{
"height": 33.0
"height": 35.2588147037
},
"input":
{
@ -635,7 +556,7 @@
"project": "uniworx.sublime-project",
"replace":
{
"height": 61.0
"height": 63.0157539385
},
"save_all_on_build": true,
"select_file":
@ -688,6 +609,15 @@
"selected_group": 0,
"settings":
{
"last_automatic_layout":
[
[
0,
0,
1,
1
]
]
},
"show_minimap": true,
"show_open_files": false,
@ -697,5 +627,6 @@
"status_bar_visible": true,
"template_settings":
{
"max_columns": 2
}
}