Merge branch 'feat/exercises' into feat/pagination
This commit is contained in:
commit
3c8f13b4dc
@ -1,4 +1,4 @@
|
|||||||
SummerTerm year@Integer: Sommersemester #{tshow year}
|
SummerTerm year@Integer: Sommersemester #{tshow year}
|
||||||
WinterTerm year@Integer: Wintersemester #{tshow year}/#{tshow $ succ year}
|
WinterTerm year@Integer: Wintersemester #{tshow year}/#{tshow $ succ year}
|
||||||
PSLimitNonPositive: “pagesize” muss größer als null sein
|
PSLimitNonPositive: “pagesize” muss größer als null sein
|
||||||
Page n@Int64: #{tshow n}
|
Page n@Int64: #{tshow n}
|
||||||
@ -9,12 +9,13 @@ Term: Semester
|
|||||||
TermPlaceholder: W/S + vierstellige Jahreszahl
|
TermPlaceholder: W/S + vierstellige Jahreszahl
|
||||||
TermEditHeading: Semester editieren/anlegen
|
TermEditHeading: Semester editieren/anlegen
|
||||||
|
|
||||||
|
LectureStart: Beginn Vorlesungen
|
||||||
|
|
||||||
Course: Kurs
|
Course: Kurs
|
||||||
CourseNewOk tid@TermIdentifier courseShortHand@Text: Kurs #{termToText tid}-#{courseShortHand} wurde erfolgreich erstellt.
|
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.
|
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.
|
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.
|
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.
|
||||||
FFSheetName: Name
|
|
||||||
TermCourseListHeading tid@TermIdentifier: Kursübersicht #{termToText tid}
|
TermCourseListHeading tid@TermIdentifier: Kursübersicht #{termToText tid}
|
||||||
TermCourseListTitle tid@TermIdentifier: Kurse #{termToText tid}
|
TermCourseListTitle tid@TermIdentifier: Kurse #{termToText tid}
|
||||||
CourseEditHeading: Kurs editieren/anlegen
|
CourseEditHeading: Kurs editieren/anlegen
|
||||||
@ -51,6 +52,7 @@ DeprecatedRoute: Diese Ansicht ist obsolet und könnte in Zukunft entfallen.
|
|||||||
UnfreeMaterials: Die Materialien für diese Veranstaltung sind nicht allgemein freigegeben.
|
UnfreeMaterials: Die Materialien für diese Veranstaltung sind nicht allgemein freigegeben.
|
||||||
UnauthorizedWrite: Sie haben hierfür keine Schreibberechtigung
|
UnauthorizedWrite: Sie haben hierfür keine Schreibberechtigung
|
||||||
|
|
||||||
|
Submission: Abgabenummer
|
||||||
SubmissionWrongSheet: Abgabenummer gehört nicht zum angegebenen Übungsblatt.
|
SubmissionWrongSheet: Abgabenummer gehört nicht zum angegebenen Übungsblatt.
|
||||||
SubmissionAlreadyExists: Sie haben bereits eine Abgabe zu diesem Übungsblatt.
|
SubmissionAlreadyExists: Sie haben bereits eine Abgabe zu diesem Übungsblatt.
|
||||||
SubmissionTitle tid@TermIdentifier courseShortHand@Text sheetName@Text: #{termToText tid}-#{courseShortHand} #{sheetName}: Abgabe editieren/anlegen
|
SubmissionTitle tid@TermIdentifier courseShortHand@Text sheetName@Text: #{termToText tid}-#{courseShortHand} #{sheetName}: Abgabe editieren/anlegen
|
||||||
@ -59,6 +61,10 @@ SubmissionArchive: Zip-Archiv der Abgabedatei(en)
|
|||||||
SubmissionFile: Datei zur Abgabe
|
SubmissionFile: Datei zur Abgabe
|
||||||
SubmissionAlreadyExistsFor user@Text: #{user} hat bereits eine Abgabe zu diesem bÜbungsblatt.
|
SubmissionAlreadyExistsFor user@Text: #{user} hat bereits eine Abgabe zu diesem bÜbungsblatt.
|
||||||
|
|
||||||
|
CorrectionsTitle: Zugewiesene Korrekturen
|
||||||
|
CourseCorrectionsTitle: Korrekturen für diesen Kurs
|
||||||
|
Corrector: Korrektor
|
||||||
|
|
||||||
EMail: E-Mail
|
EMail: E-Mail
|
||||||
EMailUnknown email@Text: E-Mail #{email} gehört zu keinem bekannten Benutzer.
|
EMailUnknown email@Text: E-Mail #{email} gehört zu keinem bekannten Benutzer.
|
||||||
NotAParticipant user@Text tid@TermIdentifier csh@Text: #{user} ist nicht im Kurs #{termToText tid}-#{csh} angemeldet.
|
NotAParticipant user@Text tid@TermIdentifier csh@Text: #{user} ist nicht im Kurs #{termToText tid}-#{csh} angemeldet.
|
||||||
@ -86,3 +92,5 @@ SheetSolution: Lösung
|
|||||||
SheetMarking: Korrekturhinweise
|
SheetMarking: Korrekturhinweise
|
||||||
|
|
||||||
MultiFileUploadInfo: (Mehrere Dateien mit Shift oder Strg auswählen)
|
MultiFileUploadInfo: (Mehrere Dateien mit Shift oder Strg auswählen)
|
||||||
|
|
||||||
|
NrColumn: Nr
|
||||||
2
routes
2
routes
@ -49,6 +49,7 @@
|
|||||||
/course/#TermId/#Text CourseR !lecturer:
|
/course/#TermId/#Text CourseR !lecturer:
|
||||||
/show CShowR GET POST !free
|
/show CShowR GET POST !free
|
||||||
/edit CEditR GET POST
|
/edit CEditR GET POST
|
||||||
|
/corrections CourseCorrectionsR GET
|
||||||
/ex SheetListR GET !registered !materials
|
/ex SheetListR GET !registered !materials
|
||||||
!/ex/new SheetNewR GET POST
|
!/ex/new SheetNewR GET POST
|
||||||
/ex/#Text SheetR:
|
/ex/#Text SheetR:
|
||||||
@ -60,6 +61,7 @@
|
|||||||
!/sub/own SubmissionOwnR GET !free
|
!/sub/own SubmissionOwnR GET !free
|
||||||
!/sub/#CryptoFileNameSubmission SubmissionR GET POST !owner !corrector
|
!/sub/#CryptoFileNameSubmission SubmissionR GET POST !owner !corrector
|
||||||
|
|
||||||
|
/corrections CorrectionsR GET !free
|
||||||
|
|
||||||
-- TODO below
|
-- TODO below
|
||||||
!/#{ZIPArchiveName SubmissionId} SubmissionDownloadArchiveR GET !deprecated
|
!/#{ZIPArchiveName SubmissionId} SubmissionDownloadArchiveR GET !deprecated
|
||||||
|
|||||||
@ -48,6 +48,7 @@ import Handler.Term
|
|||||||
import Handler.Course
|
import Handler.Course
|
||||||
import Handler.Sheet
|
import Handler.Sheet
|
||||||
import Handler.Submission
|
import Handler.Submission
|
||||||
|
import Handler.Corrections
|
||||||
import Handler.CryptoIDDispatch
|
import Handler.CryptoIDDispatch
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,8 @@ import Data.ByteArray (convert)
|
|||||||
import Crypto.Hash (Digest, SHAKE256)
|
import Crypto.Hash (Digest, SHAKE256)
|
||||||
import Crypto.Hash.Conduit (sinkHash)
|
import Crypto.Hash.Conduit (sinkHash)
|
||||||
|
|
||||||
|
import qualified Data.CryptoID (CryptoID) -- for DisplayAble instance only
|
||||||
|
|
||||||
import qualified Data.ByteString.Base64.URL as Base64 (encode)
|
import qualified Data.ByteString.Base64.URL as Base64 (encode)
|
||||||
|
|
||||||
import Data.ByteString (ByteString)
|
import Data.ByteString (ByteString)
|
||||||
@ -73,13 +75,19 @@ import Handler.Utils.DateTime
|
|||||||
import Control.Lens
|
import Control.Lens
|
||||||
import Utils.Lens
|
import Utils.Lens
|
||||||
|
|
||||||
-- -- TODO: Move me to appropriate Place
|
|
||||||
|
-- -- TODO: Move the following to the appropriate place, if DisplayAble is kept
|
||||||
instance DisplayAble TermId where
|
instance DisplayAble TermId where
|
||||||
display = termToText . unTermKey
|
display = termToText . unTermKey
|
||||||
|
|
||||||
instance DisplayAble UTCTime where
|
instance DisplayAble UTCTime where
|
||||||
display = pack . formatTimeGerDT2 -- default Time Format to be used: 00.00.00 00:00
|
display = pack . formatTimeGerDT2 -- default Time Format to be used: 00.00.00 00:00
|
||||||
|
|
||||||
|
instance (PathPiece b) => DisplayAble (Data.CryptoID.CryptoID a b) where
|
||||||
|
display = toPathPiece -- requires import of Data.CryptoID here
|
||||||
|
-- -- MOVE ABOVE
|
||||||
|
|
||||||
|
|
||||||
-- infixl 9 :$:
|
-- infixl 9 :$:
|
||||||
-- pattern a :$: b = a b
|
-- pattern a :$: b = a b
|
||||||
|
|
||||||
@ -693,6 +701,8 @@ pageHeading (CourseR tid csh CShowR)
|
|||||||
= Just $ do
|
= Just $ do
|
||||||
Entity _ Course{..} <- handlerToWidget . runDB . getBy404 $ CourseTermShort tid csh
|
Entity _ Course{..} <- handlerToWidget . runDB . getBy404 $ CourseTermShort tid csh
|
||||||
toWidget courseName
|
toWidget courseName
|
||||||
|
pageHeading CorrectionsR
|
||||||
|
= Just $ i18nHeading MsgCorrectionsTitle
|
||||||
-- TODO: add headings for more single course- and single term-pages
|
-- TODO: add headings for more single course- and single term-pages
|
||||||
pageHeading _
|
pageHeading _
|
||||||
= Nothing
|
= Nothing
|
||||||
|
|||||||
164
src/Handler/Corrections.hs
Normal file
164
src/Handler/Corrections.hs
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
{-# LANGUAGE NoImplicitPrelude #-}
|
||||||
|
{-# LANGUAGE MultiWayIf #-}
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
{-# LANGUAGE OverloadedLists #-}
|
||||||
|
{-# LANGUAGE PartialTypeSignatures #-}
|
||||||
|
{-# LANGUAGE RecordWildCards #-}
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
{-# LANGUAGE MultiParamTypeClasses #-}
|
||||||
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
|
{-# LANGUAGE RankNTypes #-}
|
||||||
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
|
{-# LANGUAGE TypeOperators #-}
|
||||||
|
|
||||||
|
module Handler.Corrections where
|
||||||
|
|
||||||
|
import Import
|
||||||
|
-- import System.FilePath (takeFileName)
|
||||||
|
|
||||||
|
import Handler.Utils
|
||||||
|
-- import Handler.Utils.Zip
|
||||||
|
|
||||||
|
-- import qualified Data.Set as Set
|
||||||
|
-- import qualified Data.Map as Map
|
||||||
|
|
||||||
|
-- import Data.Time
|
||||||
|
-- import qualified Data.Text as T
|
||||||
|
-- import Data.Function ((&))
|
||||||
|
--
|
||||||
|
import Colonnade hiding (fromMaybe, singleton)
|
||||||
|
-- import Yesod.Colonnade
|
||||||
|
--
|
||||||
|
-- import qualified Data.UUID.Cryptographic as UUID
|
||||||
|
-- import qualified Data.Conduit.List as C
|
||||||
|
|
||||||
|
import qualified Database.Esqueleto as E
|
||||||
|
-- import qualified Database.Esqueleto.Internal.Sql as E
|
||||||
|
|
||||||
|
import Control.Lens
|
||||||
|
-- import Control.Monad.Writer (MonadWriter(..), execWriterT)
|
||||||
|
|
||||||
|
-- import Network.Mime
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type CorrectionsWhere = forall query expr backend . (E.Esqueleto query expr backend) =>
|
||||||
|
(expr (Entity Course), expr (Entity Sheet), expr (Entity Submission))
|
||||||
|
-> expr (E.Value Bool)
|
||||||
|
|
||||||
|
ratedBy :: Key User -> CorrectionsWhere
|
||||||
|
ratedBy uid (_course,_sheet,submission) = submission E.^. SubmissionRatingBy E.==. E.just (E.val uid)
|
||||||
|
|
||||||
|
courseIs :: Key Course -> CorrectionsWhere
|
||||||
|
courseIs cid (course,_sheet,_submission) = course E.^. CourseId E.==. E.val cid
|
||||||
|
|
||||||
|
|
||||||
|
type CorrectionTableData = DBRow (Entity Submission, Entity Sheet, (E.Value Text, E.Value Text, E.Value (Key Term), E.Value (Key School)))
|
||||||
|
|
||||||
|
colTerm :: Colonnade _ CorrectionTableData _
|
||||||
|
colTerm = widgetColonnade $ sortable (Just "term") (i18nCell MsgTerm)
|
||||||
|
$ \DBRow{ dbrOutput=(_, _, course) } ->
|
||||||
|
-- cell [whamlet| _{untermKey $ course ^. _3}|] -- lange, internationale Semester
|
||||||
|
textCell $ termToText $ unTermKey $ E.unValue $ course ^. _3 -- kurze Semsterkürzel
|
||||||
|
|
||||||
|
colCourse :: Colonnade _ CorrectionTableData _
|
||||||
|
colCourse = widgetColonnade $ sortable (Just "course") (i18nCell MsgCourse)
|
||||||
|
$ \DBRow{ dbrOutput=(_, _, course) } -> cell $
|
||||||
|
let tid = E.unValue $ course ^. _3
|
||||||
|
csh = E.unValue $ course ^. _2
|
||||||
|
in [whamlet|<a href=@{CourseR tid csh CShowR}>#{display csh}|]
|
||||||
|
|
||||||
|
colSheet :: Colonnade _ CorrectionTableData _
|
||||||
|
colSheet = widgetColonnade $ sortable (Just "sheet") (i18nCell MsgSheet)
|
||||||
|
$ \DBRow{ dbrOutput=(_, sheet, course) } -> cell $
|
||||||
|
let tid = E.unValue $ course ^. _3
|
||||||
|
csh = E.unValue $ course ^. _2
|
||||||
|
shn = sheetName $ entityVal sheet
|
||||||
|
in [whamlet|<a href=@{CSheetR tid csh shn SShowR}>#{display shn}|]
|
||||||
|
-- textCell $ sheetName $ entityVal sheet
|
||||||
|
|
||||||
|
colCorrector :: Colonnade _ CorrectionTableData _
|
||||||
|
colCorrector = widgetColonnade $ sortable (Just "corrector") (i18nCell MsgCorrector)
|
||||||
|
$ \DBRow{ dbrOutput=(submission, _, _) } ->
|
||||||
|
textCell $ display $ submissionRatingBy $ entityVal submission
|
||||||
|
|
||||||
|
colSubmissionLink :: Colonnade _ CorrectionTableData _
|
||||||
|
colSubmissionLink = widgetColonnade $ sortable Nothing (i18nCell MsgSubmission)
|
||||||
|
$ \DBRow{ dbrOutput=(submission, sheet, course) } -> cell $ do
|
||||||
|
let tid = E.unValue $ course ^. _3
|
||||||
|
csh = E.unValue $ course ^. _2
|
||||||
|
shn = sheetName $ entityVal sheet
|
||||||
|
cid <- encrypt (entityKey submission :: SubmissionId)
|
||||||
|
[whamlet|<a href=@{CSheetR tid csh shn (SubmissionR cid)}>#{display cid}|]
|
||||||
|
|
||||||
|
makeCorrectionsTable whereClause colChoices = do
|
||||||
|
let tableData :: E.InnerJoin (E.InnerJoin (E.SqlExpr (Entity Course))
|
||||||
|
(E.SqlExpr (Entity Sheet )))
|
||||||
|
(E.SqlExpr (Entity Submission))
|
||||||
|
-> E.SqlQuery _
|
||||||
|
tableData (course `E.InnerJoin` sheet `E.InnerJoin` submission) = do
|
||||||
|
E.on $ sheet E.^. SheetId E.==. submission E.^. SubmissionSheet
|
||||||
|
E.on $ course E.^. CourseId E.==. sheet E.^. SheetCourse
|
||||||
|
E.where_ $ whereClause (course,sheet,submission)
|
||||||
|
let crse = ( course E.^. CourseName :: E.SqlExpr (E.Value Text)
|
||||||
|
, course E.^. CourseShorthand
|
||||||
|
, course E.^. CourseTerm
|
||||||
|
, course E.^. CourseSchool :: E.SqlExpr (E.Value SchoolId)
|
||||||
|
)
|
||||||
|
return (submission, sheet, crse)
|
||||||
|
dbTable def $ DBTable
|
||||||
|
{ dbtSQLQuery = tableData
|
||||||
|
, dbtColonnade = colChoices
|
||||||
|
, dbtSorting = [ ( "term"
|
||||||
|
, SortColumn $ \(course `E.InnerJoin` _ `E.InnerJoin` _ ) -> course E.^. CourseTerm
|
||||||
|
)
|
||||||
|
, ( "course"
|
||||||
|
, SortColumn $ \(course `E.InnerJoin` _ `E.InnerJoin` _ ) -> course E.^. CourseShorthand
|
||||||
|
)
|
||||||
|
-- TODO
|
||||||
|
]
|
||||||
|
, dbtFilter = mempty {- [ ( "term"
|
||||||
|
, FilterColumn $ \(course `E.InnerJoin` _ `E.InnerJoin` _ ) tids -> if
|
||||||
|
| Set.null tids -> E.val True :: E.SqlExpr (E.Value Bool)
|
||||||
|
| otherwise -> course E.^. CourseTerm `E.in_` E.valList (Set.toList tids)
|
||||||
|
)
|
||||||
|
] -}
|
||||||
|
, dbtAttrs = tableDefault
|
||||||
|
, dbtIdent = "corrections" :: Text
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getCorrectionsR :: Handler Html
|
||||||
|
getCorrectionsR = do
|
||||||
|
uid <- requireAuthId
|
||||||
|
let whereClause = ratedBy uid
|
||||||
|
displayColumns = mconcat
|
||||||
|
[ dbRow
|
||||||
|
, colTerm
|
||||||
|
, colCourse
|
||||||
|
, colSheet
|
||||||
|
, colSubmissionLink
|
||||||
|
] -- Continue here
|
||||||
|
table <- makeCorrectionsTable whereClause displayColumns
|
||||||
|
defaultLayout $ do
|
||||||
|
setTitleI MsgCourseCorrectionsTitle
|
||||||
|
$(widgetFile "corrections")
|
||||||
|
|
||||||
|
getCourseCorrectionsR :: TermId -> Text -> Handler Html
|
||||||
|
getCourseCorrectionsR tid csh = do
|
||||||
|
cid <- runDB $ getBy404 $ CourseTermShort tid csh
|
||||||
|
let whereClause = courseIs $ entityKey cid
|
||||||
|
displayColumns = mconcat
|
||||||
|
[ dbRow
|
||||||
|
, colSheet
|
||||||
|
, colCorrector
|
||||||
|
, colSubmissionLink
|
||||||
|
] -- Continue here
|
||||||
|
table <- makeCorrectionsTable whereClause displayColumns
|
||||||
|
defaultLayout $ do
|
||||||
|
setTitleI MsgCorrectionsTitle
|
||||||
|
$(widgetFile "corrections")
|
||||||
|
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ getTermShowR = do
|
|||||||
$else
|
$else
|
||||||
#{termToText termName}
|
#{termToText termName}
|
||||||
|]
|
|]
|
||||||
, sortable (Just "lecture-start") "Beginn Vorlesungen" $ \(Entity _ Term{..},_) ->
|
, sortable (Just "lecture-start") (i18nCell MsgLectureStart) $ \(Entity _ Term{..},_) ->
|
||||||
stringCell $ formatTimeGerWD termLectureStart
|
stringCell $ formatTimeGerWD termLectureStart
|
||||||
, sortable (Just "lecture-end") "Ende Vorlesungen" $ \(Entity _ Term{..},_) ->
|
, sortable (Just "lecture-end") "Ende Vorlesungen" $ \(Entity _ Term{..},_) ->
|
||||||
stringCell $ formatTimeGerWD termLectureEnd
|
stringCell $ formatTimeGerWD termLectureEnd
|
||||||
|
|||||||
@ -35,9 +35,6 @@ numberColonnade = headed "Nr" (fromString.show)
|
|||||||
pairColonnade :: (Functor h) => Colonnade h a c -> Colonnade h b c -> Colonnade h (a,b) c
|
pairColonnade :: (Functor h) => Colonnade h a c -> Colonnade h b c -> Colonnade h (a,b) c
|
||||||
pairColonnade a b = mconcat [ lmap fst a, lmap snd b]
|
pairColonnade a b = mconcat [ lmap fst a, lmap snd b]
|
||||||
|
|
||||||
i18nCell :: RenderMessage site a => a -> Cell site
|
|
||||||
i18nCell msg = cell [whamlet|_{msg}|]
|
|
||||||
|
|
||||||
|
|
||||||
-- Table Modification
|
-- Table Modification
|
||||||
encodeHeadedWidgetTableNumbered :: Attribute -> Colonnade Headed a (WidgetT site IO ()) -> [a] -> WidgetT site IO ()
|
encodeHeadedWidgetTableNumbered :: Attribute -> Colonnade Headed a (WidgetT site IO ()) -> [a] -> WidgetT site IO ()
|
||||||
@ -94,3 +91,5 @@ headedRowSelector toExternal fromExternal attrs colonnade tdata = do
|
|||||||
return ( catMaybes <$> collectResult selectionResults
|
return ( catMaybes <$> collectResult selectionResults
|
||||||
, encodeCellTable attrs (pairColonnade selColonnade colonnade) (zip [0..] tdata)
|
, encodeCellTable attrs (pairColonnade selColonnade colonnade) (zip [0..] tdata)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
{-# LANGUAGE NoImplicitPrelude
|
{-# LANGUAGE NoImplicitPrelude
|
||||||
, ExistentialQuantification
|
, ExistentialQuantification
|
||||||
, RecordWildCards
|
, RecordWildCards
|
||||||
|
, NamedFieldPuns
|
||||||
, OverloadedStrings
|
, OverloadedStrings
|
||||||
, TemplateHaskell
|
, TemplateHaskell
|
||||||
, QuasiQuotes
|
, QuasiQuotes
|
||||||
@ -18,14 +19,14 @@
|
|||||||
module Handler.Utils.Table.Pagination
|
module Handler.Utils.Table.Pagination
|
||||||
( SortColumn(..), SortDirection(..)
|
( SortColumn(..), SortDirection(..)
|
||||||
, FilterColumn(..), IsFilterColumn
|
, FilterColumn(..), IsFilterColumn
|
||||||
, DBRow(..), DBOutput
|
, DBRow(..), dbRow, DBOutput
|
||||||
, DBTable(..), IsDBTable(..)
|
, DBTable(..), IsDBTable(..)
|
||||||
, PaginationSettings(..)
|
, PaginationSettings(..)
|
||||||
, PSValidator(..)
|
, PSValidator(..)
|
||||||
, Sortable(..), sortable
|
, Sortable(..), sortable
|
||||||
, dbTable
|
, dbTable
|
||||||
, widgetColonnade, formColonnade
|
, widgetColonnade, formColonnade
|
||||||
, textCell, stringCell, anchorCell
|
, textCell, stringCell, i18nCell, anchorCell
|
||||||
, formCell, DBFormResult, getDBFormResult
|
, formCell, DBFormResult, getDBFormResult
|
||||||
) where
|
) where
|
||||||
|
|
||||||
@ -55,6 +56,7 @@ import qualified Data.Map as Map
|
|||||||
import Data.Profunctor (lmap)
|
import Data.Profunctor (lmap)
|
||||||
|
|
||||||
import Colonnade hiding (bool, fromMaybe, singleton)
|
import Colonnade hiding (bool, fromMaybe, singleton)
|
||||||
|
import qualified Colonnade (singleton)
|
||||||
import Colonnade.Encode
|
import Colonnade.Encode
|
||||||
|
|
||||||
import Text.Hamlet (hamletFile)
|
import Text.Hamlet (hamletFile)
|
||||||
@ -112,6 +114,9 @@ data DBRow r = DBRow
|
|||||||
, dbrOutput :: r
|
, dbrOutput :: r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dbRow :: (Headedness h, IsDBTable m a) => Colonnade h (DBRow r) (DBCell m a)
|
||||||
|
dbRow = Colonnade.singleton (headednessPure $ textCell MsgNrColumn) $ \DBRow{ dbrIndex } -> textCell $ tshow dbrIndex
|
||||||
|
|
||||||
class DBOutput r r' where
|
class DBOutput r r' where
|
||||||
dbProj :: r -> r'
|
dbProj :: r -> r'
|
||||||
|
|
||||||
@ -331,8 +336,9 @@ formColonnade :: (Headedness h, Monoid a)
|
|||||||
-> Colonnade h r (DBCell (RWST (Maybe (Env, FileEnv), UniWorX, [Lang]) Enctype Ints (HandlerT UniWorX IO)) (FormResult a))
|
-> Colonnade h r (DBCell (RWST (Maybe (Env, FileEnv), UniWorX, [Lang]) Enctype Ints (HandlerT UniWorX IO)) (FormResult a))
|
||||||
formColonnade = id
|
formColonnade = id
|
||||||
|
|
||||||
textCell, stringCell :: (RenderMessage UniWorX msg, IsDBTable m a) => msg -> DBCell m a
|
textCell, stringCell, i18nCell :: (RenderMessage UniWorX msg, IsDBTable m a) => msg -> DBCell m a
|
||||||
stringCell = textCell
|
stringCell = textCell
|
||||||
|
i18nCell = textCell
|
||||||
textCell msg = cell [whamlet|_{msg}|]
|
textCell msg = cell [whamlet|_{msg}|]
|
||||||
|
|
||||||
anchorCell :: IsDBTable m a
|
anchorCell :: IsDBTable m a
|
||||||
|
|||||||
@ -16,7 +16,7 @@ import Language.Haskell.TH
|
|||||||
-- Tuples --
|
-- Tuples --
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
-- Alternatively uses lenses: "^. _3" projects the 3rd component of an n-tuple for any n >=3, requires import Control.Lens
|
||||||
projNI :: Int -> Int -> ExpQ -- generic projection gives I-th element of N-tuple, i.e. snd3 = $(projNI 3 2) --ghci -fth
|
projNI :: Int -> Int -> ExpQ -- generic projection gives I-th element of N-tuple, i.e. snd3 = $(projNI 3 2) --ghci -fth
|
||||||
-- $(projN n m) :: (t1,..,tn) -> tm (for m<=n)
|
-- $(projN n m) :: (t1,..,tn) -> tm (for m<=n)
|
||||||
projNI n i = lamE [pat] rhs
|
projNI n i = lamE [pat] rhs
|
||||||
|
|||||||
2
templates/corrections.hamlet
Normal file
2
templates/corrections.hamlet
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<div .container>
|
||||||
|
^{table}
|
||||||
@ -4,7 +4,8 @@ $newline never
|
|||||||
<thead>
|
<thead>
|
||||||
<tr .table__row.table__row--head>
|
<tr .table__row.table__row--head>
|
||||||
$forall widget <- wHeaders'
|
$forall widget <- wHeaders'
|
||||||
^{widget} $# cell/header.hamlet
|
$# cell/header.hamlet
|
||||||
|
^{widget}
|
||||||
$nothing
|
$nothing
|
||||||
<tbody>
|
<tbody>
|
||||||
$if null wRows
|
$if null wRows
|
||||||
@ -15,4 +16,5 @@ $newline never
|
|||||||
$forall row <- wRows
|
$forall row <- wRows
|
||||||
<tr .table__row>
|
<tr .table__row>
|
||||||
$forall widget <- row
|
$forall widget <- row
|
||||||
^{widget} $# cell/body.hamlet
|
$# cell/body.hamlet
|
||||||
|
^{widget}
|
||||||
|
|||||||
Reference in New Issue
Block a user