chore(lms): make model compile again, sort out model errors
This commit is contained in:
parent
aa73359893
commit
3d3ac9d77c
@ -3,65 +3,70 @@ Qualification
|
|||||||
shorthand (CI Text)
|
shorthand (CI Text)
|
||||||
name (CI Text)
|
name (CI Text)
|
||||||
description StoredMarkup Maybe -- user-defined large Html, ought to contain full description
|
description StoredMarkup Maybe -- user-defined large Html, ought to contain full description
|
||||||
validDuration Word Maybe -- qualification is valid for this number of months
|
validDuration Word Maybe -- qualification is valid for this number of months
|
||||||
auditDuration Word Maybe -- number of month to keep audit log
|
auditDuration Word Maybe -- number of month to keep audit log
|
||||||
refreshWithin CalendarDiffDays Maybe -- refresher is scheduled within this number of month before expiry
|
refreshWithin CalendarDiffDays Maybe -- refresher is scheduled within this number of month before expiry
|
||||||
-- refreshInvitation StoredMarkup -- fest verdrahtet I18N-MSGs, nur Anzeige auf Webseite
|
elearningOnly Bool -- successful E-learing automatically increases validity
|
||||||
-- expiryNotification StoredMarkup Maybe
|
-- refreshInvitation StoredMarkup -- hard-coded I18N-MSGs used instead, but displayed on qualification page
|
||||||
elearningOnly Bool -- successful E-learing automatically increases validity
|
-- expiryNotification StoredMarkup Maybe -- configurable user-profile-notifcations are used instead
|
||||||
UniqueSchoolShort school shorthand -- must be unique per school and shorthand
|
UniqueSchoolShort school shorthand -- must be unique per school and shorthand
|
||||||
UniqueSchoolName school name -- must be unique per school and name
|
UniqueSchoolName school name -- must be unique per school and name
|
||||||
deriving Generic
|
deriving Generic
|
||||||
|
|
||||||
-- Verknüpfung mit Exams fehlt only
|
|
||||||
|
|
||||||
QualificationUser
|
|
||||||
user User
|
|
||||||
qualification QualficationId
|
|
||||||
validUntil UTCTime
|
|
||||||
firstHeld UTCTime -- timestamp qualification earned
|
|
||||||
lastRefresh UTCTIme -- lastRefresh > validUntil possible, indicates E-Learning success, but needs more (e.g. an exam)
|
|
||||||
UniqueQualificationUser qualification user
|
|
||||||
|
|
||||||
QualificationEdit
|
QualificationEdit
|
||||||
user User
|
user User
|
||||||
time UTCTime
|
time UTCTime
|
||||||
qualification QualificationId OnDeleteCascade OnUpdateCascade
|
qualification QualificationId OnDeleteCascade OnUpdateCascade
|
||||||
deriving Generic
|
deriving Generic
|
||||||
|
|
||||||
|
-- TODO: connect Qualification with Exams!
|
||||||
|
|
||||||
|
QualificationUser
|
||||||
|
user User
|
||||||
|
qualification QualificationId
|
||||||
|
validUntil UTCTime
|
||||||
|
lastRefresh UTCTime -- lastRefresh > validUntil possible, if Qualification^elearningOnly == False
|
||||||
|
firstHeld UTCTime -- first time the qualification was earned, should never change
|
||||||
|
UniqueQualificationUser qualification user
|
||||||
|
deriving Generic
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- LMS Interface Tables, need regular processing by background jobs
|
-- LMS Interface Tables, need regular processing by background jobs
|
||||||
-- Logging?
|
|
||||||
LmsUser
|
LmsUser
|
||||||
qualification QualificationId
|
qualification QualificationId
|
||||||
user UserId
|
user UserId
|
||||||
ident LmsIdent
|
ident LmsIdent
|
||||||
pin Text
|
pin Text
|
||||||
resetPin Bool
|
resetPin Bool -- should the pin be reset?
|
||||||
deleted Bool
|
delete Bool -- should the ident be deleted? TODO: do we need this?
|
||||||
started UTCTime Maybe
|
started UTCTime Maybe
|
||||||
ended UTCTime Maybe
|
submitted UTCTime Maybe -- ident was sent to LMS (should happen only once)
|
||||||
|
ended UTCTime Maybe -- ident was deleted in LMS
|
||||||
UniqueLmsUser qualification ident
|
UniqueLmsUser qualification ident
|
||||||
deriving Generic
|
deriving Generic
|
||||||
|
|
||||||
LmsAudit
|
-- LmsUserlist stores LMS upload ofr later processing only
|
||||||
qualifaction QualifactionId
|
|
||||||
ident LmsIdent
|
|
||||||
lastSeen UTCTime
|
|
||||||
notificationType LmsNotification
|
|
||||||
|
|
||||||
LmsUserlist
|
LmsUserlist
|
||||||
qualification QualificationId
|
qualification QualificationId
|
||||||
ident LmsIdent
|
ident LmsIdent
|
||||||
failed Bool
|
failed Bool
|
||||||
timestamp UTCTime default=now()
|
timestamp UTCTime default=now()
|
||||||
UniqueLmsUserlist qualification ident
|
|
||||||
deriving Generic
|
deriving Generic
|
||||||
|
|
||||||
-- QualificationId is redundant here; but known due to external upload
|
-- LmsUserlist stores LMS upload ofr later processing only
|
||||||
LmsResult
|
LmsResult
|
||||||
qualification QualificationId
|
qualification QualificationId
|
||||||
ident LmsIdent
|
ident LmsIdent
|
||||||
success Day
|
success Day
|
||||||
timestamp UTCTime default=now()
|
timestamp UTCTime default=now()
|
||||||
UniqueLmsResult qualification ident
|
deriving Generic
|
||||||
|
|
||||||
|
-- Logs all processed rows from LmsUserlist and LmsResult
|
||||||
|
LmsAudit
|
||||||
|
qualification QualificationId
|
||||||
|
ident LmsIdent
|
||||||
|
notificationType LmsNotification
|
||||||
|
received UTCTime
|
||||||
|
processed UTCTime default=now()
|
||||||
deriving Generic
|
deriving Generic
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
{-# LANGUAGE UndecidableInstances #-}
|
||||||
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||||
|
|
||||||
module Data.Time.Clock.Instances
|
module Data.Time.Clock.Instances
|
||||||
@ -32,7 +33,7 @@ instance PersistField NominalDiffTime where
|
|||||||
instance PersistFieldSql NominalDiffTime where
|
instance PersistFieldSql NominalDiffTime where
|
||||||
sqlType _ = sqlType (Proxy @Rational)
|
sqlType _ = sqlType (Proxy @Rational)
|
||||||
|
|
||||||
|
deriving instance Generic Day
|
||||||
deriving instance Generic UTCTime
|
deriving instance Generic UTCTime
|
||||||
instance Hashable UTCTime
|
instance Hashable UTCTime
|
||||||
|
|
||||||
@ -40,14 +41,26 @@ instance PathPiece UTCTime where
|
|||||||
toPathPiece = pack . iso8601Show
|
toPathPiece = pack . iso8601Show
|
||||||
fromPathPiece = iso8601ParseM . unpack
|
fromPathPiece = iso8601ParseM . unpack
|
||||||
|
|
||||||
instance Csv.ToField UTCTime where
|
-- UTCTime, Day, etc.
|
||||||
toField = Csv.toField . iso8601Show
|
instance {-# OVERLAPPABLE #-} ISO8601 t => Csv.ToField t where -- Error: overlaps Csv.ToField String, but no instance ISO8601 String exists?!
|
||||||
|
toField = Csv.toField . iso8601Show
|
||||||
|
{-
|
||||||
|
• Overlapping instances for Csv.ToField String
|
||||||
|
arising from a use of ‘Csv.toField’
|
||||||
|
Matching instances:
|
||||||
|
instance ISO8601 t => Csv.ToField t
|
||||||
|
-- Defined at src/Data/Time/Clock/Instances.hs:45:11
|
||||||
|
instance Csv.ToField [Char]
|
||||||
|
-- Defined in ‘cassava-0.5.2.0:Data.Csv.Conversion’
|
||||||
|
• In the first argument of ‘(.)’, namely ‘Csv.toField’
|
||||||
|
In the expression: Csv.toField . iso8601Show
|
||||||
|
In an equation for ‘Csv.toField’:
|
||||||
|
Csv.toField = Csv.toField . iso8601Show
|
||||||
|
-}
|
||||||
|
|
||||||
instance Csv.FromField UTCTime where
|
instance {-# OVERLAPPABLE #-} ISO8601 t => Csv.FromField t where -- overlapped for ZonedTime in Handler.Utils.DateTime
|
||||||
parseField = iso8601ParseM <=< Csv.parseField
|
parseField = iso8601ParseM <=< Csv.parseField
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
-- CalendarDiffDays
|
-- CalendarDiffDays
|
||||||
--
|
--
|
||||||
-- CalendarDiffDays is basically a pair of Integers, we are stored in the DB as an Array of Word (Word8 probably suffices already)
|
-- CalendarDiffDays is basically a pair of Integers, we are stored in the DB as an Array of Word (Word8 probably suffices already)
|
||||||
|
|||||||
@ -150,7 +150,7 @@ mkUserlistTable qid = do
|
|||||||
dbtRowKey = (E.^. LmsUserlistId)
|
dbtRowKey = (E.^. LmsUserlistId)
|
||||||
dbtProj = dbtProjFilteredPostId -- TODO: or dbtProjSimple what is the difference?
|
dbtProj = dbtProjFilteredPostId -- TODO: or dbtProjSimple what is the difference?
|
||||||
dbtColonnade = dbColonnade $ mconcat
|
dbtColonnade = dbColonnade $ mconcat
|
||||||
[ sortable (Just "ident") (i18nCell MsgTableLmsIdent) $ \DBRow{ dbrOutput = Entity _ LmsUserlist{..} } -> textCell lmsUserlistIdent
|
[ sortable (Just "ident") (i18nCell MsgTableLmsIdent) $ \DBRow{ dbrOutput = Entity _ LmsUserlist{..} } -> textCell $ getLmsIdent lmsUserlistIdent
|
||||||
, sortable (Just "failed") (i18nCell MsgTableLmsFailed) $ \DBRow{ dbrOutput = Entity _ LmsUserlist{..} } -> isBadCell lmsUserlistFailed
|
, sortable (Just "failed") (i18nCell MsgTableLmsFailed) $ \DBRow{ dbrOutput = Entity _ LmsUserlist{..} } -> isBadCell lmsUserlistFailed
|
||||||
]
|
]
|
||||||
dbtSorting = Map.fromList
|
dbtSorting = Map.fromList
|
||||||
|
|||||||
@ -28,7 +28,7 @@ import Database.Esqueleto.Utils.TH
|
|||||||
|
|
||||||
|
|
||||||
type LmsResultTableExpr = ( E.SqlExpr (Entity Qualification)
|
type LmsResultTableExpr = ( E.SqlExpr (Entity Qualification)
|
||||||
`E.InnerJoin` E.SqlExpr (Entity LmsResult)
|
`E.InnerJoin` E.SqlExpr (Entity LmsResult)
|
||||||
) `E.LeftOuterJoin` E.SqlExpr (Maybe (Entity LmsUser))
|
) `E.LeftOuterJoin` E.SqlExpr (Maybe (Entity LmsUser))
|
||||||
`E.LeftOuterJoin` E.SqlExpr (Maybe (Entity User))
|
`E.LeftOuterJoin` E.SqlExpr (Maybe (Entity User))
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ queryUser = $(sqlLOJproj 3 3)
|
|||||||
|
|
||||||
type LmsResultTableData = DBRow (Entity Qualification, Entity LmsResult, Maybe (Entity LmsUser), Maybe (Entity User))
|
type LmsResultTableData = DBRow (Entity Qualification, Entity LmsResult, Maybe (Entity LmsUser), Maybe (Entity User))
|
||||||
|
|
||||||
instance HasEntity LmsResultTableData LmsResult where
|
instance HasEntity LmsResultTableData LmsResult where
|
||||||
hasEntity = _dbrOutput . _2
|
hasEntity = _dbrOutput . _2
|
||||||
|
|
||||||
{- MaybeHasUser only!
|
{- MaybeHasUser only!
|
||||||
@ -61,43 +61,43 @@ resultLmsResult :: Lens' LmsResultTableData (Entity LmsResult)
|
|||||||
resultLmsResult = _dbrOutput . _2
|
resultLmsResult = _dbrOutput . _2
|
||||||
|
|
||||||
resultLmsUser :: Traversal' LmsResultTableData (Entity LmsUser)
|
resultLmsUser :: Traversal' LmsResultTableData (Entity LmsUser)
|
||||||
resultLmsUser = _dbrOutput . _3 . _Just
|
resultLmsUser = _dbrOutput . _3 . _Just
|
||||||
|
|
||||||
resultUser :: Traversal' LmsResultTableData (Entity User)
|
resultUser :: Traversal' LmsResultTableData (Entity User)
|
||||||
resultUser = _dbrOutput . _4 . _Just
|
resultUser = _dbrOutput . _4 . _Just
|
||||||
|
|
||||||
-- required for import only
|
-- required for import only
|
||||||
data LmsResultTableCsv = LmsResultTableCsv
|
data LmsResultTableCsv = LmsResultTableCsv
|
||||||
{ csvLRTident :: LmsIdent
|
{ csvLRTident :: LmsIdent
|
||||||
, csvLRTsuccess :: UTCTime
|
, csvLRTsuccess :: Day
|
||||||
}
|
}
|
||||||
deriving Generic
|
deriving Generic
|
||||||
makeLenses_ ''LmsResultTableCsv
|
makeLenses_ ''LmsResultTableCsv
|
||||||
|
|
||||||
-- csv without headers
|
-- csv without headers
|
||||||
instance Csv.ToRecord LmsResultTableCsv -- default suffices
|
instance Csv.ToRecord LmsResultTableCsv -- default suffices
|
||||||
instance Csv.FromRecord LmsResultTableCsv -- default suffices
|
instance Csv.FromRecord LmsResultTableCsv -- default suffices
|
||||||
|
|
||||||
-- csv with headers
|
-- csv with headers
|
||||||
lmsResultTableCsvHeader :: Csv.Header
|
lmsResultTableCsvHeader :: Csv.Header
|
||||||
lmsResultTableCsvHeader = Csv.header [ "identification", "timestamp-success" ]
|
lmsResultTableCsvHeader = Csv.header [ "identification", "day-success" ]
|
||||||
|
|
||||||
instance ToNamedRecord LmsResultTableCsv where
|
instance ToNamedRecord LmsResultTableCsv where
|
||||||
toNamedRecord LmsResultTableCsv{..} = Csv.namedRecord
|
toNamedRecord LmsResultTableCsv{..} = Csv.namedRecord
|
||||||
[ "identification" Csv..= csvLRTident
|
[ "identification" Csv..= csvLRTident
|
||||||
, "timestamp-success" Csv..= csvLRTsuccess
|
, "day-success" Csv..= csvLRTsuccess
|
||||||
]
|
]
|
||||||
|
|
||||||
instance FromNamedRecord LmsResultTableCsv where
|
instance FromNamedRecord LmsResultTableCsv where
|
||||||
parseNamedRecord (lsfHeaderTranslate -> csv)
|
parseNamedRecord (lsfHeaderTranslate -> csv)
|
||||||
= LmsResultTableCsv
|
= LmsResultTableCsv
|
||||||
<$> csv Csv..: "identification"
|
<$> csv Csv..: "identification"
|
||||||
<*> csv Csv..: "timestamp-success"
|
<*> csv Csv..: "day-success"
|
||||||
|
|
||||||
|
|
||||||
instance CsvColumnsExplained LmsResultTableCsv where
|
instance CsvColumnsExplained LmsResultTableCsv where
|
||||||
csvColumnsExplanations _ = mconcat
|
csvColumnsExplanations _ = mconcat
|
||||||
[ single "identification" MsgCsvColumnLmsResultIdent
|
[ single "identification" MsgCsvColumnLmsResultIdent
|
||||||
, single "timestamp-success" MsgCsvColumnLmsResultSuccess
|
, single "timestamp-success" MsgCsvColumnLmsResultSuccess
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
@ -106,16 +106,16 @@ instance CsvColumnsExplained LmsResultTableCsv where
|
|||||||
|
|
||||||
|
|
||||||
mkResultTable :: QualificationId -> DB (Any, Widget)
|
mkResultTable :: QualificationId -> DB (Any, Widget)
|
||||||
mkResultTable qid = do
|
mkResultTable qid = do
|
||||||
let
|
let
|
||||||
resultDBTable = DBTable{..}
|
resultDBTable = DBTable{..}
|
||||||
where
|
where
|
||||||
dbtSQLQuery = runReaderT $ do
|
dbtSQLQuery = runReaderT $ do
|
||||||
qualification <- asks queryQualification
|
qualification <- asks queryQualification
|
||||||
lmsResult <- asks queryLmsResult
|
lmsResult <- asks queryLmsResult
|
||||||
lmsUser <- asks queryLmsUser
|
lmsUser <- asks queryLmsUser
|
||||||
user <- asks queryUser
|
user <- asks queryUser
|
||||||
lift $ do
|
lift $ do
|
||||||
E.on $ qualification E.^. QualificationId E.==. lmsResult E.^. LmsResultQualification
|
E.on $ qualification E.^. QualificationId E.==. lmsResult E.^. LmsResultQualification
|
||||||
E.on $ lmsUser E.?. LmsUserIdent E.==. E.just (lmsResult E.^. LmsResultIdent)
|
E.on $ lmsUser E.?. LmsUserIdent E.==. E.just (lmsResult E.^. LmsResultIdent)
|
||||||
E.on $ lmsUser E.?. LmsUserUser E.==. user E.?. UserId
|
E.on $ lmsUser E.?. LmsUserUser E.==. user E.?. UserId
|
||||||
@ -123,15 +123,15 @@ mkResultTable qid = do
|
|||||||
return (qualification, lmsResult, lmsUser, user)
|
return (qualification, lmsResult, lmsUser, user)
|
||||||
dbtRowKey = queryLmsResult >>> (E.^. LmsResultId)
|
dbtRowKey = queryLmsResult >>> (E.^. LmsResultId)
|
||||||
dbtProj = dbtProjFilteredPostId -- TODO: or dbtProjSimple what is the difference?
|
dbtProj = dbtProjFilteredPostId -- TODO: or dbtProjSimple what is the difference?
|
||||||
dbtColonnade = dbColonnade $ mconcat
|
dbtColonnade = dbColonnade $ mconcat
|
||||||
[ sortable (Just "ident") (i18nCell MsgTableLmsIdent) $ \(view $ resultLmsResult . _entityVal . _lmsResultIdent -> ident) -> textCell ident
|
[ sortable (Just "ident") (i18nCell MsgTableLmsIdent) $ \(view $ resultLmsResult . _entityVal . _lmsResultIdent . _getLmsIdent -> ident) -> textCell ident
|
||||||
, sortable (Just "sucess") (i18nCell MsgTableLmsSuccess) $ \(view $ resultLmsResult . _entityVal . _lmsResultSuccess -> success) -> dateTimeCell success
|
, sortable (Just "sucess") (i18nCell MsgTableLmsSuccess) $ \(view $ resultLmsResult . _entityVal . _lmsResultSuccess -> success) -> dayCell success
|
||||||
] -- TODO: add more columns for manual debugging view !!!
|
] -- TODO: add more columns for manual debugging view !!!
|
||||||
dbtSorting = Map.fromList
|
dbtSorting = Map.fromList
|
||||||
[ ("ident" , SortColumn $ queryLmsResult >>> (E.^. LmsResultIdent))
|
[ ("ident" , SortColumn $ queryLmsResult >>> (E.^. LmsResultIdent))
|
||||||
, ("success", SortColumn $ queryLmsResult >>> (E.^. LmsResultSuccess))
|
, ("success", SortColumn $ queryLmsResult >>> (E.^. LmsResultSuccess))
|
||||||
-- , ("success", SortColumn . views queryLmsResult (E.^. LmsResultSuccess))
|
-- , ("success", SortColumn . views queryLmsResult (E.^. LmsResultSuccess))
|
||||||
]
|
]
|
||||||
dbtFilter = Map.fromList
|
dbtFilter = Map.fromList
|
||||||
[ -- ("ident" , FilterColumn $ queryLmsResult >>> (E.^. LmsResultIdent))
|
[ -- ("ident" , FilterColumn $ queryLmsResult >>> (E.^. LmsResultIdent))
|
||||||
]
|
]
|
||||||
@ -144,14 +144,13 @@ mkResultTable qid = do
|
|||||||
dbtCsvDecode = Nothing -- TODO !!! continue here !!! CSV Import is the purpose of this page! Just save to DB, create Job to deal with it later!
|
dbtCsvDecode = Nothing -- TODO !!! continue here !!! CSV Import is the purpose of this page! Just save to DB, create Job to deal with it later!
|
||||||
dbtExtraReps = []
|
dbtExtraReps = []
|
||||||
|
|
||||||
resultDBTableValidator = def
|
resultDBTableValidator = def
|
||||||
& defaultSorting [SortAscBy "ident"]
|
& defaultSorting [SortAscBy "ident"]
|
||||||
dbTable resultDBTableValidator resultDBTable
|
dbTable resultDBTableValidator resultDBTable
|
||||||
|
|
||||||
getLmsResultR :: QualificationId -> Handler Html
|
getLmsResultR :: QualificationId -> Handler Html
|
||||||
getLmsResultR qid = do
|
getLmsResultR qid = do
|
||||||
lmsTable <- runDB $ view _2 <$> mkResultTable qid
|
lmsTable <- runDB $ view _2 <$> mkResultTable qid
|
||||||
siteLayoutMsg MsgMenuLmsResult $ do
|
siteLayoutMsg MsgMenuLmsResult $ do
|
||||||
setTitleI MsgMenuLmsResult
|
setTitleI MsgMenuLmsResult
|
||||||
$(widgetFile "lms-result")
|
$(widgetFile "lms-result")
|
||||||
|
|
||||||
@ -28,7 +28,7 @@ import Data.Time.Zones
|
|||||||
import qualified Data.Time.Zones as TZ
|
import qualified Data.Time.Zones as TZ
|
||||||
|
|
||||||
import qualified Data.Time.Format as Time
|
import qualified Data.Time.Format as Time
|
||||||
import Data.Time.Format.ISO8601 (iso8601Show)
|
-- import Data.Time.Format.ISO8601 (iso8601Show)
|
||||||
|
|
||||||
import qualified Data.Set as Set
|
import qualified Data.Set as Set
|
||||||
|
|
||||||
@ -317,10 +317,12 @@ formatTimeRangeMail = formatTimeRange' formatTimeMail
|
|||||||
formatGregorianW :: (YesodAuthPersist UniWorX, AuthEntity UniWorX ~ User, AuthId UniWorX ~ UserId) => Integer -> Int -> Int -> WidgetFor UniWorX ()
|
formatGregorianW :: (YesodAuthPersist UniWorX, AuthEntity UniWorX ~ User, AuthId UniWorX ~ UserId) => Integer -> Int -> Int -> WidgetFor UniWorX ()
|
||||||
formatGregorianW y m d = formatTimeW SelFormatDate $ fromGregorian y m d
|
formatGregorianW y m d = formatTimeW SelFormatDate $ fromGregorian y m d
|
||||||
|
|
||||||
instance Csv.ToField ZonedTime where
|
-- generic instance from Data.Time.Clock.Instances suffices
|
||||||
toField = Csv.toField . iso8601Show
|
--instance Csv.ToField ZonedTime where
|
||||||
|
-- toField = Csv.toField . iso8601Show
|
||||||
|
|
||||||
instance Csv.FromField ZonedTime where
|
-- overlaps instance from Data.Time.Clock.Instances
|
||||||
|
instance {-# OVERLAPS #-} Csv.FromField ZonedTime where
|
||||||
parseField = parse <=< Csv.parseField
|
parseField = parse <=< Csv.parseField
|
||||||
where
|
where
|
||||||
parse t = asum $ do
|
parse t = asum $ do
|
||||||
|
|||||||
@ -131,11 +131,15 @@ modalCell content = cell $ modal (toWidget $ hasComment True) (Right $ toWidget
|
|||||||
timeCell :: IsDBTable m a => UTCTime -> DBCell m a
|
timeCell :: IsDBTable m a => UTCTime -> DBCell m a
|
||||||
timeCell t = cell $ formatTime SelFormatTime t >>= toWidget
|
timeCell t = cell $ formatTime SelFormatTime t >>= toWidget
|
||||||
|
|
||||||
|
dateTimeCell :: IsDBTable m a => UTCTime -> DBCell m a
|
||||||
|
dateTimeCell t = cell $ formatTime SelFormatDateTime t >>= toWidget
|
||||||
|
|
||||||
dateCell :: IsDBTable m a => UTCTime -> DBCell m a
|
dateCell :: IsDBTable m a => UTCTime -> DBCell m a
|
||||||
dateCell t = cell $ formatTime SelFormatDate t >>= toWidget
|
dateCell t = cell $ formatTime SelFormatDate t >>= toWidget
|
||||||
|
|
||||||
dateTimeCell :: IsDBTable m a => UTCTime -> DBCell m a
|
dayCell :: IsDBTable m a => Day -> DBCell m a
|
||||||
dateTimeCell t = cell $ formatTime SelFormatDateTime t >>= toWidget
|
dayCell utctDay = cell $ formatTime SelFormatDate UTCTime{..} >>= toWidget
|
||||||
|
where utctDayTime = 0
|
||||||
|
|
||||||
-- | Show a date, and highlight date earlier than given watershed with an icon and cell class Warning
|
-- | Show a date, and highlight date earlier than given watershed with an icon and cell class Warning
|
||||||
--
|
--
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{-|
|
{-|
|
||||||
Module: Model.Types.Lms
|
Module: Model.Types.Lms
|
||||||
Description: Types for Lms
|
Description: Types for Learning Management System Interface operated by Know how! AG
|
||||||
|
|
||||||
-}
|
-}
|
||||||
module Model.Types.Lms
|
module Model.Types.Lms
|
||||||
@ -8,11 +8,23 @@ module Model.Types.Lms
|
|||||||
) where
|
) where
|
||||||
|
|
||||||
import Import.NoModel
|
import Import.NoModel
|
||||||
|
import Database.Persist.Sql
|
||||||
|
import qualified Data.Csv as Csv
|
||||||
|
import Utils.Lens.TH
|
||||||
|
|
||||||
|
newtype LmsIdent = LmsIdent { getLmsIdent :: Text }
|
||||||
|
deriving (Eq, Ord, Read, Show, Generic, Typeable)
|
||||||
|
deriving newtype (NFData, PersistField, PersistFieldSql, Csv.ToField, Csv.FromField)
|
||||||
|
|
||||||
type LmsIdent = Text
|
makeLenses_ ''LmsIdent
|
||||||
|
|
||||||
data LmsNotfication = Blocked | Successs | Alive
|
data LmsNotification = LmsAlive | LmsBlocked | LmsSuccesss Day
|
||||||
deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable)
|
deriving (Eq, Ord, Read, Show, Generic, Typeable, NFData)
|
||||||
deriving (Universe, Finite, NFData)
|
|
||||||
|
deriveJSON defaultOptions
|
||||||
|
{ constructorTagModifier = camelToPathPiece' 1
|
||||||
|
, fieldLabelModifier = camelToPathPiece' 1
|
||||||
|
, omitNothingFields = True
|
||||||
|
, sumEncoding = TaggedObject "lmsaudit" "lmsaction"
|
||||||
|
} ''LmsNotification
|
||||||
|
derivePersistFieldJSON ''LmsNotification
|
||||||
|
|||||||
Reference in New Issue
Block a user