Handler.Utils.Table.Convenience -> Cells; ProfileData clean refactored

This commit is contained in:
SJost 2018-09-11 16:40:41 +02:00
parent f7f8514f5e
commit b230ba870d
9 changed files with 99 additions and 111 deletions

View File

@ -21,7 +21,7 @@ import Control.Lens
import Utils.Lens import Utils.Lens
import Utils.TH import Utils.TH
import Handler.Utils import Handler.Utils
import Handler.Utils.Table.Convenience import Handler.Utils.Table.Cells
-- import Data.Time -- import Data.Time
import qualified Data.Text as T import qualified Data.Text as T

View File

@ -17,11 +17,12 @@ module Handler.Profile where
import Import import Import
import Handler.Utils import Handler.Utils
import Handler.Utils.Table.Convenience import Handler.Utils.Table.Cells
import Utils.Lens import Utils.Lens
-- import Colonnade hiding (fromMaybe, singleton) -- import Colonnade hiding (fromMaybe, singleton)
-- import Yesod.Colonnade -- import Yesod.Colonnade
import Data.Monoid (Any(..))
import qualified Data.Map as Map import qualified Data.Map as Map
import qualified Data.Set as Set import qualified Data.Set as Set
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
@ -150,7 +151,7 @@ postProfileR = do
---------------------------------------- ----------------------------------------
-- TODO: Are these really a good idea? -- TODO: Are these really a good idea?
-- If yes: Move to appropriate Place: Utils.Lens and Utils.Table.Convenience -- If yes: Move to appropriate Place: Utils.Lens and Utils.Table.Cells
-- --
-- Or Maybe make Course an instance of Data.Data and use biplate instead? -- Or Maybe make Course an instance of Data.Data and use biplate instead?
-- λ> ("a",7,"b",["c","d"],(9,"e",8),"f",True) ^.. biplate :: [String] -- λ> ("a",7,"b",["c","d"],(9,"e",8),"f",True) ^.. biplate :: [String]
@ -173,11 +174,15 @@ getProfileDataR = do
-- mr <- getMessageRender -- mr <- getMessageRender
-- Tabelle mit eigenen Kursen -- Tabelle mit eigenen Kursen
ownCourseTable <- do -- TODO: only display when non-empty (Any hasRows, ownCourseTable) <- do -- TODO: only display when non-empty
let withType :: ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity Lecturer)) -> a) let withType :: ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity Lecturer)) -> a)
-> ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity Lecturer)) -> a) -> ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity Lecturer)) -> a)
withType = id withType = id
dbTableWidget' def $ DBTable
validator = def
& defaultSorting [("term",SortDesc),("school",SortAsc),("course",SortAsc)]
dbTableWidget validator $ DBTable
{ dbtIdent = "courseOwnership" :: Text { dbtIdent = "courseOwnership" :: Text
, dbtStyle = def , dbtStyle = def
, dbtSQLQuery = \(course `E.InnerJoin` lecturer) -> do , dbtSQLQuery = \(course `E.InnerJoin` lecturer) -> do
@ -185,15 +190,20 @@ getProfileDataR = do
E.where_ $ lecturer E.^. LecturerUser E.==. E.val uid E.where_ $ lecturer E.^. LecturerUser E.==. E.val uid
return ( course E.^. CourseTerm return ( course E.^. CourseTerm
, course E.^. CourseSchool , course E.^. CourseSchool
, course E.^. CourseId
, course E.^. CourseShorthand , course E.^. CourseShorthand
) )
, dbtProj = \x -> return $ x & _dbrOutput %~ (\(E.Value tid, E.Value ssh, E.Value csh) -> (tid,ssh,csh))
, dbtColonnade = mconcat , dbtColonnade = mconcat
[ dbRow [ dbRow
, colsCourseLink' $ _dbrOutput , sortable (Just "term") (i18nCell MsgTerm & cellAttrs .~ [("priority","0")]) $ do
-- [ colsCourseLink $ (over each _unValue) . _dbrOutput -- different types in Tuple prevents "over each" tid <- view (_dbrOutput . _1)
return $ indicatorCell `mappend` termCell tid
, sortable (Just "school") (i18nCell MsgCourseSchool) $
schoolCell <$> view (_dbrOutput . _1 . re _Just)
<*> view (_dbrOutput . _2 )
, sortable (Just "course") (i18nCell MsgCourse) $
courseLinkCell <$> view (_dbrOutput)
] ]
, dbtProj = return
, dbtSorting = Map.fromList , dbtSorting = Map.fromList
[ ( "course", SortColumn $ withType $ \(crse `E.InnerJoin` _) -> crse E.^. CourseShorthand) -- consider PatternSynonyms. Drawback: not enclosed with table, since they must be at Top-Level. Maybe make Lenses for InnerJoins then? [ ( "course", SortColumn $ withType $ \(crse `E.InnerJoin` _) -> crse E.^. CourseShorthand) -- consider PatternSynonyms. Drawback: not enclosed with table, since they must be at Top-Level. Maybe make Lenses for InnerJoins then?
, ( "term" , SortColumn $ withType $ \(crse `E.InnerJoin` _) -> crse E.^. CourseTerm ) , ( "term" , SortColumn $ withType $ \(crse `E.InnerJoin` _) -> crse E.^. CourseTerm )
@ -208,39 +218,34 @@ getProfileDataR = do
-- Tabelle mit allen Teilnehmer: Kurs (link), Datum -- Tabelle mit allen Teilnehmer: Kurs (link), Datum
courseTable <- do courseTable <- do
let let withType :: ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity CourseParticipant)) -> a)
withType :: ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity CourseParticipant)) -> a)
-> ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity CourseParticipant)) -> a) -> ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity CourseParticipant)) -> a)
withType = id withType = id
-- should be inlined validator = def
-- courseCol :: IsDBTable m a => Colonnade Sortable (DBRow (Entity Course, E.Value UTCTime)) (DBCell m a) & defaultSorting [("time",SortDesc)]
-- courseCol = sortable (Just "course") (i18nCell MsgCourse) $ do -- (->) a Monad
-- course <- view $ _dbrOutput . _1 . _entityVal -- view == ^.
-- -- "preview _left" in order to match Either (result is Maybe)
-- return $ courseCell course
-- termCol = sortable (Just "school") (i18nCell MsgCourseSchool) $ do
-- Course{..} <- view $ _dbrOutput . _1 . _entityVal
-- return $ anchorCell (TermsSchoolCourseListR
-- courseData :: (E.InnerJoin (E.SqlExpr (Entity Course)) (E.SqlExpr (Entity CourseParticipant)))
-- -> E.SqlQuery (E.SqlExpr (Entity Course), E.SqlExpr (E.Value UTCTime))
courseData = \(course `E.InnerJoin` participant) -> do courseData = \(course `E.InnerJoin` participant) -> do
E.on $ course E.^. CourseId E.==. participant E.^. CourseParticipantCourse E.on $ course E.^. CourseId E.==. participant E.^. CourseParticipantCourse
E.where_ $ participant E.^. CourseParticipantUser E.==. E.val uid E.where_ $ participant E.^. CourseParticipantUser E.==. E.val uid
return (course, participant E.^. CourseParticipantRegistration) return (course, participant E.^. CourseParticipantRegistration)
dbTableWidget' def $ DBTable dbTableWidget' validator $ DBTable
{ dbtIdent = "courseMembership" :: Text { dbtIdent = "courseMembership" :: Text
, dbtSQLQuery = courseData , dbtSQLQuery = courseData
, dbtProj = \x -> return $ x & _dbrOutput . _2 %~ E.unValue
, dbtColonnade = mconcat , dbtColonnade = mconcat
[ dbRow [ dbRow
, colsCourseDescr $ _dbrOutput . _1 . _entityVal , sortable (Just "term") (i18nCell MsgTerm) $
termCell <$> view (_dbrOutput . _1 . _entityVal . _courseTerm)
, sortable (Just "school") (i18nCell MsgCourseSchool) . magnify (_dbrOutput . _1 . _entityVal) $
schoolCell <$> view ( _courseTerm . re _Just)
<*> view ( _courseSchool )
, sortable (Just "course") (i18nCell MsgCourse) $
courseCell <$> view (_dbrOutput . _1 . _entityVal)
, sortable (Just "time") (i18nCell MsgRegistered) $ do , sortable (Just "time") (i18nCell MsgRegistered) $ do
regTime <- view $ _dbrOutput . _2 . _unValue regTime <- view $ _dbrOutput . _2
return $ timeCell regTime return $ timeCell regTime
] ]
, dbtProj = return
, dbtSorting = Map.fromList , dbtSorting = Map.fromList
[ ( "course", SortColumn $ withType $ \(crse `E.InnerJoin` _) -> crse E.^. CourseName ) [ ( "course", SortColumn $ withType $ \(crse `E.InnerJoin` _) -> crse E.^. CourseName )
, ( "term" , SortColumn $ withType $ \(crse `E.InnerJoin` _) -> crse E.^. CourseTerm ) , ( "term" , SortColumn $ withType $ \(crse `E.InnerJoin` _) -> crse E.^. CourseTerm )
@ -261,14 +266,18 @@ getProfileDataR = do
let withType :: ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity Sheet) `E.InnerJoin` E.SqlExpr (Entity Submission)`E.InnerJoin` E.SqlExpr (Entity SubmissionUser) )->a) let withType :: ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity Sheet) `E.InnerJoin` E.SqlExpr (Entity Submission)`E.InnerJoin` E.SqlExpr (Entity SubmissionUser) )->a)
-> ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity Sheet) `E.InnerJoin` E.SqlExpr (Entity Submission)`E.InnerJoin` E.SqlExpr (Entity SubmissionUser) )->a) -> ((E.SqlExpr (Entity Course) `E.InnerJoin` E.SqlExpr (Entity Sheet) `E.InnerJoin` E.SqlExpr (Entity Submission)`E.InnerJoin` E.SqlExpr (Entity SubmissionUser) )->a)
withType = id withType = id
let validator = def -- DUPLICATED CODE: Handler.Corrections
validator = def -- DUPLICATED CODE: Handler.Corrections
& restrictFilter (\name _ -> name /= "corrector") -- We need to be careful to restrict allowed sorting/filter to not expose sensitive information & restrictFilter (\name _ -> name /= "corrector") -- We need to be careful to restrict allowed sorting/filter to not expose sensitive information
& restrictSorting (\name _ -> name /= "corrector") & restrictSorting (\name _ -> name /= "corrector")
& defaultSorting [("edit",SortDesc)]
lastSubEdit submission = -- latest Edit-Time of this user for submission lastSubEdit submission = -- latest Edit-Time of this user for submission
E.sub_select . E.from $ \subEdit -> do E.sub_select . E.from $ \subEdit -> do
E.where_ $ subEdit E.^. SubmissionEditSubmission E.==. submission E.^. SubmissionId E.where_ $ subEdit E.^. SubmissionEditSubmission E.==. submission E.^. SubmissionId
E.&&. subEdit E.^. SubmissionEditUser E.==. E.val uid E.&&. subEdit E.^. SubmissionEditUser E.==. E.val uid
return . E.max_ $ subEdit E.^. SubmissionEditTime return . E.max_ $ subEdit E.^. SubmissionEditTime
dbTableWidget' validator $ DBTable dbTableWidget' validator $ DBTable
{ dbtIdent = "submissions" :: Text { dbtIdent = "submissions" :: Text
, dbtStyle = def , dbtStyle = def
@ -279,41 +288,37 @@ getProfileDataR = do
E.where_ $ subUser E.^. SubmissionUserUser E.==. E.val uid E.where_ $ subUser E.^. SubmissionUserUser E.==. E.val uid
let crse = ( course E.^. CourseTerm let crse = ( course E.^. CourseTerm
, course E.^. CourseSchool , course E.^. CourseSchool
, course E.^. CourseId
, course E.^. CourseShorthand , course E.^. CourseShorthand
) )
let sht = ( sheet E.^. SheetName let sht = ( sheet E.^. SheetName
) )
return (crse, sht, submission, lastSubEdit submission) return (crse, sht, submission, lastSubEdit submission)
, dbtProj = \x -> return $ x
& _dbrOutput . _1 %~ (\(E.Value tid, E.Value ssh, E.Value csh) -> (tid,ssh,csh))
& _dbrOutput . _2 %~ E.unValue
& _dbrOutput . _4 %~ E.unValue
, dbtColonnade = mconcat , dbtColonnade = mconcat
[ dbRow [ dbRow
, colsCourseLink' $ _dbrOutput . _1 , sortable (Just "term") (i18nCell MsgTerm) $
, sortable (Just "sheet") (i18nCell MsgSheet) $ do termCell <$> view (_dbrOutput . _1 . _1)
shn <- view $ _dbrOutput . _2 . _unValue , sortable (Just "school") (i18nCell MsgCourseSchool) . magnify (_dbrOutput . _1 ) $
crse <- view $ _dbrOutput . _1 schoolCell <$> view ( _1. re _Just)
let tid = crse ^. _1 . _unValue <*> view ( _2 )
ssh = crse ^. _2 . _unValue , sortable (Just "course") (i18nCell MsgCourse) $
csh = crse ^. _4 . _unValue courseLinkCell <$> view (_dbrOutput . _1)
link= CSheetR tid ssh csh shn SShowR , sortable (Just "sheet") (i18nCell MsgSheet) . magnify _dbrOutput $
return $ anchorCell link $ display2widget shn sheetCell <$> view _1
<*> view _2
, sortable (toNothing "submission") (i18nCell MsgSubmission) $ do -- TODO: use submissionCell?! , sortable (toNothing "submission") (i18nCell MsgSubmission) . magnify _dbrOutput $
shn <- view $ _dbrOutput . _2 . _unValue submissionCell <$> view _1
sid <- view $ _dbrOutput . _3 . _entityKey <*> view _2
crse <- view $ _dbrOutput . _1 <*> view (_3 . _entityKey)
-- , sortable (Just "edit") (i18nCell MsgSubmissionEditUser) $ do
-- regTime <- view $ _dbrOutput . _4
let tid = crse ^. _1 . _unValue -- return $ maybe mempty timeCell regTime
ssh = crse ^. _2 . _unValue , sortable (Just "edit") (i18nCell MsgSubmissionEditUser) $
csh = crse ^. _4 . _unValue maybe mempty timeCell <$> view (_dbrOutput . _4)
mkCid = encrypt (sid :: SubmissionId) -- TODO: executed twice
mkRoute cid = CSubmissionR tid ssh csh shn cid SubShowR
return $ anchorCellM' mkCid mkRoute display2widget
, sortable (Just "edit") (i18nCell MsgSubmissionEditUser) $ do
regTime <- view $ _dbrOutput . _4 . _unValue
return $ maybe mempty timeCell regTime
] ]
, dbtProj = return
, dbtSorting = Map.fromList , dbtSorting = Map.fromList
[ ( "course", SortColumn $ withType $ \(crse `E.InnerJoin` _ `E.InnerJoin` _ `E.InnerJoin` _) -> crse E.^. CourseShorthand) [ ( "course", SortColumn $ withType $ \(crse `E.InnerJoin` _ `E.InnerJoin` _ `E.InnerJoin` _) -> crse E.^. CourseShorthand)
, ( "term" , SortColumn $ withType $ \(crse `E.InnerJoin` _ `E.InnerJoin` _ `E.InnerJoin` _) -> crse E.^. CourseTerm ) , ( "term" , SortColumn $ withType $ \(crse `E.InnerJoin` _ `E.InnerJoin` _ `E.InnerJoin` _) -> crse E.^. CourseTerm )

View File

@ -21,7 +21,7 @@ import Import
-- import Utils.Lens -- import Utils.Lens
-- import Utils.TH -- import Utils.TH
-- import Handler.Utils -- import Handler.Utils
-- import Handler.Utils.Table.Convenience -- import Handler.Utils.Table.Cells
-- --
-- -- import Data.Time -- -- import Data.Time
-- import qualified Data.Text as T -- import qualified Data.Text as T

View File

@ -23,7 +23,7 @@ import Import hiding (joinPath)
-- import Yesod.Form.Bootstrap3 -- import Yesod.Form.Bootstrap3
import Handler.Utils import Handler.Utils
import Handler.Utils.Table.Convenience import Handler.Utils.Table.Cells
import Network.Mime import Network.Mime

View File

@ -5,25 +5,26 @@
{-# LANGUAGE PartialTypeSignatures #-} {-# LANGUAGE PartialTypeSignatures #-}
{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleContexts #-}
module Handler.Utils.Table.Convenience where module Handler.Utils.Table.Cells where
import Import import Import
import Data.Monoid (Any(..))
import Control.Monad.Writer.Class (MonadWriter(..))
import Utils.Lens import Utils.Lens
import Handler.Utils import Handler.Utils
-- import Handler.Utils.Table.Pagination
import qualified Database.Esqueleto as E (Value(..))
-- newtype CourseLink = CourseLink (TermId, SchoolId, CourseId, CourseShorthand) -- cannot be in Types due to CourseId
type CourseLink = (TermId, SchoolId, CourseId, CourseShorthand) -- cannot be in Types due to CourseId
-- TODO: can we get rid of this type through lenses?
type CourseLink' = (E.Value TermId, E.Value SchoolId, E.Value CourseId, E.Value CourseShorthand) -- cannot be in Types due to CourseId
type CourseLink = (TermId, SchoolId, CourseShorthand) -- TODO: Refactor with WithHoles !
--------------------
-- Special cells -- Special cells
indicatorCell :: IsDBTable m Any => DBCell m Any -- For dbTables that return a Bool to indicate content
indicatorCell = mempty & cellContents %~ (tell (Any True) *>)
-- 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
@ -48,13 +49,7 @@ schoolCell Nothing ssh = anchorCell link name
name = text2widget $ display ssh name = text2widget $ display ssh
courseLinkCell :: IsDBTable m a => CourseLink -> DBCell m a courseLinkCell :: IsDBTable m a => CourseLink -> DBCell m a
courseLinkCell (tid,ssh,_cid,csh) = anchorCell link name courseLinkCell (tid,ssh,csh) = anchorCell link name
where
link = CourseR tid ssh csh CShowR
name = citext2widget csh
courseLinkCell' :: IsDBTable m a => CourseLink' -> DBCell m a
courseLinkCell' (E.Value tid, E.Value ssh,_cid,E.Value csh) = anchorCell link name
where where
link = CourseR tid ssh csh CShowR link = CourseR tid ssh csh CShowR
name = citext2widget csh name = citext2widget csh
@ -68,27 +63,27 @@ courseCell (Course {..}) = anchorCell link name `mappend` desc
Nothing -> mempty Nothing -> mempty
(Just descr) -> cell [whamlet| <span style="float:right"> ^{modalStatic descr} |] (Just descr) -> cell [whamlet| <span style="float:right"> ^{modalStatic descr} |]
sheetCell :: IsDBTable m a => (CourseLink', E.Value SheetName) -> DBCell m a sheetCell :: IsDBTable m a => CourseLink -> SheetName -> DBCell m a
sheetCell (crse, E.Value shn) = sheetCell crse shn =
let tid = crse ^. _1 . _unValue let tid = crse ^. _1
ssh = crse ^. _2 . _unValue ssh = crse ^. _2
csh = crse ^. _4 . _unValue csh = crse ^. _3
link= CSheetR tid ssh csh shn SShowR link= CSheetR tid ssh csh shn SShowR
in anchorCell link $ display2widget shn in anchorCell link $ display2widget shn
submissionCell :: IsDBTable m a => (CourseLink', E.Value SheetName, Entity Submission) -> DBCell m a submissionCell :: IsDBTable m a => CourseLink -> SheetName -> SubmissionId -> DBCell m a
submissionCell (crse, E.Value shn, submission) = submissionCell crse shn sid =
let tid = crse ^. _1 . _unValue let tid = crse ^. _1
ssh = crse ^. _2 . _unValue ssh = crse ^. _2
csh = crse ^. _4 . _unValue csh = crse ^. _3
sid = entityKey submission mkCid = encrypt sid
mkCid = encrypt (sid :: SubmissionId) -- TODO: executed twice -- FIXED here, but not everywhere!
mkRoute cid = CSubmissionR tid ssh csh shn cid SubShowR mkRoute cid = CSubmissionR tid ssh csh shn cid SubShowR
mkText cid = display2widget cid mkText cid = display2widget cid
in anchorCellM' mkCid mkRoute mkText in anchorCellM' mkCid mkRoute mkText
-- Generic Columns {-# DEPRECATED colCourseDescr, colsCourseDescr, colsCourseLink "Bad idea, write columns yourself you lazy bat!" #-}
-- Generic Columns -- We want to avoid these due to the literals occuring
colCourseDescr :: IsDBTable m a => Getting Course s Course -> Colonnade Sortable s (DBCell m a) colCourseDescr :: IsDBTable m a => Getting Course s Course -> Colonnade Sortable s (DBCell m a)
colCourseDescr getter = colCourseDescr getter =
sortable (Just "course") (i18nCell MsgCourse) $ do sortable (Just "course") (i18nCell MsgCourse) $ do
@ -120,18 +115,3 @@ colsCourseLink getter = mconcat
crs <- view getter crs <- view getter
return $ courseLinkCell crs return $ courseLinkCell crs
] ]
colsCourseLink' :: (IsDBTable m a) => Getting CourseLink' s CourseLink' -> Colonnade Sortable s (DBCell m a)
colsCourseLink' getter = mconcat
[ sortable (Just "term") (i18nCell MsgTerm) $ do
crs <- view getter
return $ termCell $ crs ^. _1 . _unValue
, sortable (Just "school") (i18nCell MsgCourseSchool) $ do
crs <- view getter
return $ schoolCell (Just $ crs ^. _1 . _unValue) (crs ^. _2 . _unValue)
, sortable (Just "course") (i18nCell MsgCourse) $ do
crs <- view getter
return $ courseLinkCell' crs
]

View File

@ -21,7 +21,7 @@
module Handler.Utils.Table.Pagination module Handler.Utils.Table.Pagination
( SortColumn(..), SortDirection(..) ( SortColumn(..), SortDirection(..)
, FilterColumn(..), IsFilterColumn , FilterColumn(..), IsFilterColumn
, DBRow(..), HasDBRow(..) , DBRow(..), _dbrOutput, _dbrIndex, _dbrCount
, DBStyle(..), DBEmptyStyle(..) , DBStyle(..), DBEmptyStyle(..)
, DBTable(..), IsDBTable(..), DBCell(..) , DBTable(..), IsDBTable(..), DBCell(..)
, cellAttrs, cellContents , cellAttrs, cellContents
@ -45,6 +45,7 @@ module Handler.Utils.Table.Pagination
) where ) where
import Handler.Utils.Table.Pagination.Types import Handler.Utils.Table.Pagination.Types
import Utils.Lens.TH
import Import hiding (Proxy(..)) import Import hiding (Proxy(..))
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
@ -134,7 +135,7 @@ data PaginationSettings = PaginationSettings
, psShortcircuit :: Bool , psShortcircuit :: Bool
} }
makeClassy_ ''PaginationSettings makeLenses_ ''PaginationSettings
instance Default PaginationSettings where instance Default PaginationSettings where
def = PaginationSettings def = PaginationSettings
@ -153,7 +154,7 @@ data PaginationInput = PaginationInput
, piShortcircuit :: Bool , piShortcircuit :: Bool
} }
makeClassy_ ''PaginationInput makeLenses_ ''PaginationInput
piIsUnset :: PaginationInput -> Bool piIsUnset :: PaginationInput -> Bool
piIsUnset PaginationInput{..} = and piIsUnset PaginationInput{..} = and
@ -169,7 +170,7 @@ data DBRow r = DBRow
, dbrIndex, dbrCount :: Int64 , dbrIndex, dbrCount :: Int64
} deriving (Show, Read, Eq, Ord) } deriving (Show, Read, Eq, Ord)
makeClassy_ ''DBRow makeLenses_ ''DBRow
instance Functor DBRow where instance Functor DBRow where
fmap f DBRow{..} = DBRow{ dbrOutput = f dbrOutput, .. } fmap f DBRow{..} = DBRow{ dbrOutput = f dbrOutput, .. }

View File

@ -15,7 +15,8 @@ import qualified Data.Set as Set
import qualified Database.Esqueleto as E import qualified Database.Esqueleto as E
-- import Database.Persist -- currently not needed here -- import Database.Persist -- currently not needed here
-- TODO: is this the right place?
emptyOrIn :: PersistField typ => emptyOrIn :: PersistField typ =>
E.SqlExpr (E.Value typ) -> Set typ -> E.SqlExpr (E.Value Bool) E.SqlExpr (E.Value typ) -> Set typ -> E.SqlExpr (E.Value Bool)
emptyOrIn criterion testSet emptyOrIn criterion testSet

View File

@ -75,7 +75,7 @@ Handler.Utils.Table.Pagination
Handler.Utils.Table.Pagination.Types Handler.Utils.Table.Pagination.Types
: `Sortable`-Headedness for colonnade : `Sortable`-Headedness for colonnade
Handler.Utils.Table.Convenience Handler.Utils.Table.Cells
: extends dbTable with UniWorX specific functions, such as special courseCell : extends dbTable with UniWorX specific functions, such as special courseCell
Handler.Utils.Templates Handler.Utils.Templates

View File

@ -8,10 +8,11 @@
<em> TODO: Hier alle Daten in Tabellen anzeigen! <em> TODO: Hier alle Daten in Tabellen anzeigen!
<div .container> $if hasRows
<h2> Eigene Kurse
<div .container> <div .container>
^{ownCourseTable} <h2> Eigene Kurse
<div .container>
^{ownCourseTable}
<div .container> <div .container>
<h2> Kursanmeldungen <h2> Kursanmeldungen