chore(lms): reorder routes and (wip) overview table
This commit is contained in:
parent
f6e1959ad4
commit
01d9916520
@ -123,6 +123,7 @@ MenuCourseEventNew: Neuer Kurstermin
|
|||||||
MenuCourseEventEdit: Kurstermin bearbeiten
|
MenuCourseEventEdit: Kurstermin bearbeiten
|
||||||
MenuLanguage: Sprache
|
MenuLanguage: Sprache
|
||||||
|
|
||||||
|
MenuQualification: Qualifkationen
|
||||||
MenuLms: Schnittstelle E-Lernen
|
MenuLms: Schnittstelle E-Lernen
|
||||||
MenuLmsUsers: Empfang E-Lernen Benutzer
|
MenuLmsUsers: Empfang E-Lernen Benutzer
|
||||||
MenuLmsUserlist: Melden E-Lernen Benutzer
|
MenuLmsUserlist: Melden E-Lernen Benutzer
|
||||||
|
|||||||
@ -124,6 +124,7 @@ MenuCourseEventNew: New course occurrence
|
|||||||
MenuCourseEventEdit: Edit course occurrence
|
MenuCourseEventEdit: Edit course occurrence
|
||||||
MenuLanguage: Language
|
MenuLanguage: Language
|
||||||
|
|
||||||
|
MenuQualification: Qualifcations
|
||||||
MenuLms: Interface E-Learning
|
MenuLms: Interface E-Learning
|
||||||
MenuLmsUsers: Download E-Learning Users
|
MenuLmsUsers: Download E-Learning Users
|
||||||
MenuLmsUserlist: Upload E-Learning Users
|
MenuLmsUserlist: Upload E-Learning Users
|
||||||
|
|||||||
@ -10,8 +10,8 @@ Qualification
|
|||||||
-- elearningOnly Bool -- successful E-learing automatically increases validity. NO!
|
-- elearningOnly Bool -- successful E-learing automatically increases validity. NO!
|
||||||
-- refreshInvitation StoredMarkup -- hard-coded I18N-MSGs used instead, but displayed on qualification page NO!
|
-- refreshInvitation StoredMarkup -- hard-coded I18N-MSGs used instead, but displayed on qualification page NO!
|
||||||
-- expiryNotification StoredMarkup Maybe -- configurable user-profile-notifcations are used instead NO!
|
-- expiryNotification StoredMarkup Maybe -- configurable user-profile-notifcations are used instead NO!
|
||||||
UniqueQualificationSchoolShort school shorthand -- must be unique per school and shorthand
|
SchoolQualificationShort school shorthand -- must be unique per school and shorthand
|
||||||
UniqueQualificationSchoolName school name -- must be unique per school and name
|
SchoolQualificationName school name -- must be unique per school and name
|
||||||
deriving Generic
|
deriving Generic
|
||||||
|
|
||||||
-- TODOs:
|
-- TODOs:
|
||||||
|
|||||||
@ -6,7 +6,7 @@ School json
|
|||||||
examMinimumRegisterBeforeStart NominalDiffTime Maybe
|
examMinimumRegisterBeforeStart NominalDiffTime Maybe
|
||||||
examMinimumRegisterDuration NominalDiffTime Maybe
|
examMinimumRegisterDuration NominalDiffTime Maybe
|
||||||
examRequireModeForRegistration Bool default=false
|
examRequireModeForRegistration Bool default=false
|
||||||
examDiscouragedModes ExamModeDNF default='{"dnf-terms":[]}'
|
examDiscouragedModes ExamModeDNF default='{"dnf-terms":[]}' -- This comment fixes syntax highlighting error only "
|
||||||
examCloseMode ExamCloseMode default='separate'
|
examCloseMode ExamCloseMode default='separate'
|
||||||
sheetAuthorshipStatementMode SchoolAuthorshipStatementMode default='optional'
|
sheetAuthorshipStatementMode SchoolAuthorshipStatementMode default='optional'
|
||||||
sheetAuthorshipStatementDefinition AuthorshipStatementDefinitionId Maybe
|
sheetAuthorshipStatementDefinition AuthorshipStatementDefinitionId Maybe
|
||||||
|
|||||||
2
routes
2
routes
@ -255,6 +255,8 @@
|
|||||||
!/*WellKnownFileName WellKnownR GET !free
|
!/*WellKnownFileName WellKnownR GET !free
|
||||||
|
|
||||||
-- OSIS CSV Export Demo
|
-- OSIS CSV Export Demo
|
||||||
|
/lms LmsAllR GET
|
||||||
|
/lms/#SchoolId LmsSchoolR GET
|
||||||
/lms/#SchoolId/#QualificationShorthand LmsR GET POST
|
/lms/#SchoolId/#QualificationShorthand LmsR GET POST
|
||||||
/lms/#SchoolId/#QualificationShorthand/users LmsUsersR GET
|
/lms/#SchoolId/#QualificationShorthand/users LmsUsersR GET
|
||||||
/lms/#SchoolId/#QualificationShorthand/users/direct LmsUsersDirectR GET
|
/lms/#SchoolId/#QualificationShorthand/users/direct LmsUsersDirectR GET
|
||||||
|
|||||||
@ -133,15 +133,21 @@ breadcrumb HealthR = i18nCrumb MsgMenuHealth Nothing
|
|||||||
breadcrumb InstanceR = i18nCrumb MsgMenuInstance Nothing
|
breadcrumb InstanceR = i18nCrumb MsgMenuInstance Nothing
|
||||||
breadcrumb StatusR = i18nCrumb MsgMenuHealth Nothing -- never displayed
|
breadcrumb StatusR = i18nCrumb MsgMenuHealth Nothing -- never displayed
|
||||||
|
|
||||||
breadcrumb (LmsR _sid _qsh) = i18nCrumb MsgMenuLms Nothing
|
breadcrumb LmsAllR = i18nCrumb MsgMenuQualification Nothing
|
||||||
breadcrumb (LmsUsersR sid qsh) = i18nCrumb MsgMenuLmsUsers $ Just $ LmsR sid qsh
|
breadcrumb (LmsSchoolR ssh ) = useRunDB . maybeT (i18nCrumb MsgBreadcrumbSchool . Just $ SchoolListR) $ do -- redirect only, used in other breadcrumbs
|
||||||
breadcrumb (LmsUsersDirectR sid qsh) = i18nCrumb MsgMenuLmsUsers $ Just $ LmsUsersR sid qsh -- never displayed, TypedContent
|
guardM . lift . existsBy . UniqueSchoolShorthand $ unSchoolKey ssh
|
||||||
breadcrumb (LmsUserlistR sid qsh) = i18nCrumb MsgMenuLmsUserlist $ Just $ LmsR sid qsh
|
return (CI.original $ unSchoolKey ssh, Just LmsAllR)
|
||||||
breadcrumb (LmsUserlistUploadR sid qsh) = i18nCrumb MsgMenuLmsUpload $ Just $ LmsUserlistR sid qsh
|
breadcrumb (LmsR ssh qsh) =useRunDB . maybeT (i18nCrumb MsgBreadcrumbCourse . Just $ LmsSchoolR ssh) $ do
|
||||||
breadcrumb (LmsUserlistDirectR sid qsh) = i18nCrumb MsgMenuLmsUpload $ Just $ LmsUserlistR sid qsh -- never displayed
|
guardM . lift . existsBy $ SchoolQualificationShort ssh qsh
|
||||||
breadcrumb (LmsResultR sid qsh) = i18nCrumb MsgMenuLmsResult $ Just $ LmsR sid qsh
|
return (CI.original qsh, Just $ LmsSchoolR ssh)
|
||||||
breadcrumb (LmsResultUploadR sid qsh) = i18nCrumb MsgMenuLmsUpload $ Just $ LmsResultR sid qsh
|
breadcrumb (LmsUsersR ssh qsh) = i18nCrumb MsgMenuLmsUsers $ Just $ LmsR ssh qsh
|
||||||
breadcrumb (LmsResultDirectR sid qsh) = i18nCrumb MsgMenuLmsUpload $ Just $ LmsResultR sid qsh -- never displayed
|
breadcrumb (LmsUsersDirectR ssh qsh) = i18nCrumb MsgMenuLmsUsers $ Just $ LmsUsersR ssh qsh -- never displayed, TypedContent
|
||||||
|
breadcrumb (LmsUserlistR ssh qsh) = i18nCrumb MsgMenuLmsUserlist $ Just $ LmsR ssh qsh
|
||||||
|
breadcrumb (LmsUserlistUploadR ssh qsh) = i18nCrumb MsgMenuLmsUpload $ Just $ LmsUserlistR ssh qsh
|
||||||
|
breadcrumb (LmsUserlistDirectR ssh qsh) = i18nCrumb MsgMenuLmsUpload $ Just $ LmsUserlistR ssh qsh -- never displayed
|
||||||
|
breadcrumb (LmsResultR ssh qsh) = i18nCrumb MsgMenuLmsResult $ Just $ LmsR ssh qsh
|
||||||
|
breadcrumb (LmsResultUploadR ssh qsh) = i18nCrumb MsgMenuLmsUpload $ Just $ LmsResultR ssh qsh
|
||||||
|
breadcrumb (LmsResultDirectR ssh qsh) = i18nCrumb MsgMenuLmsUpload $ Just $ LmsResultR ssh qsh -- never displayed
|
||||||
|
|
||||||
|
|
||||||
breadcrumb ProfileR = i18nCrumb MsgBreadcrumbProfile Nothing
|
breadcrumb ProfileR = i18nCrumb MsgBreadcrumbProfile Nothing
|
||||||
|
|||||||
@ -5,7 +5,9 @@
|
|||||||
|
|
||||||
|
|
||||||
module Handler.LMS
|
module Handler.LMS
|
||||||
( getLmsR , postLmsR
|
( getLmsAllR
|
||||||
|
, getLmsSchoolR
|
||||||
|
, getLmsR , postLmsR
|
||||||
, getLmsUsersR , getLmsUsersDirectR
|
, getLmsUsersR , getLmsUsersDirectR
|
||||||
, getLmsUserlistR , postLmsUserlistR
|
, getLmsUserlistR , postLmsUserlistR
|
||||||
, getLmsUserlistUploadR , postLmsUserlistUploadR, postLmsUserlistDirectR
|
, getLmsUserlistUploadR , postLmsUserlistUploadR, postLmsUserlistDirectR
|
||||||
@ -31,6 +33,19 @@ import Handler.LMS.Users as Handler.LMS
|
|||||||
import Handler.LMS.Userlist as Handler.LMS
|
import Handler.LMS.Userlist as Handler.LMS
|
||||||
import Handler.LMS.Result as Handler.LMS
|
import Handler.LMS.Result as Handler.LMS
|
||||||
|
|
||||||
|
getLmsAllR :: Handler Html
|
||||||
|
getLmsAllR = error "TODO"
|
||||||
|
|
||||||
|
getLmsSchoolR :: SchoolId -> Handler Html
|
||||||
|
getLmsSchoolR ssh = redirect (LmsAllR, [("qualification-school", toPathPiece ssh)])
|
||||||
|
|
||||||
|
{- --redirect with filering
|
||||||
|
getLmsR :: SchoolId -> QualificationShorthand -> Handler Html
|
||||||
|
getLmsR ssh qsh = redirect (LmsAllR, [("qualification-school" , toPathPiece ssh)
|
||||||
|
,("qualification-shorthand", toPathPiece qsh)
|
||||||
|
])
|
||||||
|
-}
|
||||||
|
|
||||||
{-
|
{-
|
||||||
data LmsUserTableCsv = LmsUserTableCsv -- for csv export only
|
data LmsUserTableCsv = LmsUserTableCsv -- for csv export only
|
||||||
{ csvLmsUserIdent :: LmsIdent
|
{ csvLmsUserIdent :: LmsIdent
|
||||||
@ -63,7 +78,7 @@ resultUser = _dbrOutput . _2
|
|||||||
getLmsR, postLmsR:: SchoolId -> QualificationShorthand -> Handler Html
|
getLmsR, postLmsR:: SchoolId -> QualificationShorthand -> Handler Html
|
||||||
getLmsR = postLmsR
|
getLmsR = postLmsR
|
||||||
postLmsR sid qsh = do
|
postLmsR sid qsh = do
|
||||||
_qid <- runDB . getKeyBy404 $ UniqueQualificationSchoolShort sid qsh
|
_qid <- runDB . getKeyBy404 $ SchoolQualificationShort sid qsh
|
||||||
-- TODO !!! filter table by qid !!!
|
-- TODO !!! filter table by qid !!!
|
||||||
|
|
||||||
dbtCsvName <- csvLmsUserFilename
|
dbtCsvName <- csvLmsUserFilename
|
||||||
@ -169,74 +184,12 @@ 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
|
|
||||||
data LmsResultTableCsv = LmsResultTableCsv
|
|
||||||
{ csvLRTident :: LmsIdent
|
|
||||||
, csvLRTsuccess :: Day
|
|
||||||
}
|
|
||||||
deriving Generic
|
|
||||||
makeLenses_ ''LmsResultTableCsv
|
|
||||||
|
|
||||||
-- csv without headers
|
mkLmsTable :: QualificationId -> DB (Any, Widget)
|
||||||
instance Csv.ToRecord LmsResultTableCsv -- default suffices
|
mkLmsTable qid = do
|
||||||
instance Csv.FromRecord LmsResultTableCsv -- default suffices
|
|
||||||
|
|
||||||
-- csv with headers -- TODO not yet supported
|
|
||||||
lmsResultTableCsvHeader :: Csv.Header
|
|
||||||
lmsResultTableCsvHeader = Csv.header [ csvLmsIdent, csvLmsSuccess ]
|
|
||||||
|
|
||||||
instance ToNamedRecord LmsResultTableCsv where
|
|
||||||
toNamedRecord LmsResultTableCsv{..} = Csv.namedRecord
|
|
||||||
[ csvLmsIdent Csv..= csvLRTident
|
|
||||||
, csvLmsSuccess Csv..= csvLRTsuccess
|
|
||||||
]
|
|
||||||
|
|
||||||
instance FromNamedRecord LmsResultTableCsv where
|
|
||||||
parseNamedRecord (lsfHeaderTranslate -> csv)
|
|
||||||
= LmsResultTableCsv
|
|
||||||
<$> csv Csv..: csvLmsIdent
|
|
||||||
<*> csv Csv..: csvLmsSuccess
|
|
||||||
|
|
||||||
instance CsvColumnsExplained LmsResultTableCsv where
|
|
||||||
csvColumnsExplanations _ = mconcat
|
|
||||||
[ single csvLmsIdent MsgCsvColumnLmsIdent
|
|
||||||
, single csvLmsSuccess MsgCsvColumnLmsSuccess
|
|
||||||
]
|
|
||||||
where
|
|
||||||
single :: RenderMessage UniWorX msg => Csv.Name -> msg -> Map Csv.Name Widget
|
|
||||||
single k v = singletonMap k [whamlet|_{v}|]
|
|
||||||
|
|
||||||
data LmsResultCsvActionClass = LmsResultInsert
|
|
||||||
deriving (Eq, Ord, Read, Show, Generic, Typeable, Enum, Bounded)
|
|
||||||
embedRenderMessage ''UniWorX ''LmsResultCsvActionClass id
|
|
||||||
|
|
||||||
-- By coincidence the action type is identical to LmsResultTableCsv
|
|
||||||
data LmsResultCsvAction = LmsResultInsertData { lmsResultInsertIdent :: LmsIdent, lmsResultInsertSuccess :: Day }
|
|
||||||
deriving (Eq, Ord, Read, Show, Generic, Typeable)
|
|
||||||
|
|
||||||
deriveJSON defaultOptions
|
|
||||||
{ constructorTagModifier = camelToPathPiece'' 2 1 -- LmsResultInsertData -> insert
|
|
||||||
, fieldLabelModifier = camelToPathPiece' 2 -- lmsResultInsertIdent -> insert-ident | lmsResultInsertSuccess -> insert-success
|
|
||||||
, sumEncoding = TaggedObject "action" "data"
|
|
||||||
} ''LmsResultCsvAction
|
|
||||||
|
|
||||||
data LmsResultCsvException
|
|
||||||
= LmsResultCsvExceptionDuplicatedKey -- TODO: this is not used anywhere?!
|
|
||||||
deriving (Show, Generic, Typeable)
|
|
||||||
|
|
||||||
instance Exception LmsResultCsvException
|
|
||||||
embedRenderMessage ''UniWorX ''LmsResultCsvException id
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mkLmsTable :: SchoolId -> QualificationShorthand -> QualificationId -> DB (Any, Widget)
|
|
||||||
mkLmsTable sid qsh qid = do
|
|
||||||
dbtCsvName <- csvFilenameLmsResult qsh
|
|
||||||
let dbtCsvSheetName = dbtCsvName
|
|
||||||
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
|
||||||
@ -251,80 +204,32 @@ mkLmsTable sid qsh qid = do
|
|||||||
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 csvLmsIdent) (i18nCell MsgTableLmsIdent) $ \(view $ resultLmsResult . _entityVal . _lmsResultIdent . _getLmsIdent -> ident) -> textCell ident
|
[ sortable (Just "school") (i18nCell MsgTableSchool) $ \(view $ resultQualification . _entityVal . _qualificationSchool -> schoolShorthand) -> wgtCell $ toWgt schoolShorthand
|
||||||
, sortable (Just csvLmsSuccess) (i18nCell MsgTableLmsSuccess) $ \(view $ resultLmsResult . _entityVal . _lmsResultSuccess -> success) -> dayCell success
|
, sortable (Just csvLmsIdent) (i18nCell MsgTableLmsIdent) $ \(view $ resultLmsResult . _entityVal . _lmsResultIdent . _getLmsIdent -> ident) -> textCell ident
|
||||||
|
, sortable (Just csvLmsSuccess) (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
|
||||||
[ (csvLmsIdent , SortColumn $ queryLmsResult >>> (E.^. LmsResultIdent))
|
[ ("school" , SortColumn $ queryQualification >>> (E.^. QualificationSchool))
|
||||||
|
, (csvLmsIdent , SortColumn $ queryLmsResult >>> (E.^. LmsResultIdent))
|
||||||
-- , (csvLmsSuccess, SortColumn $ queryLmsResult >>> (E.^. LmsResultSuccess))
|
-- , (csvLmsSuccess, SortColumn $ queryLmsResult >>> (E.^. LmsResultSuccess))
|
||||||
, (csvLmsSuccess, SortColumn $ views (to queryLmsResult) (E.^. LmsResultSuccess))
|
, (csvLmsSuccess, SortColumn $ views (to queryLmsResult) (E.^. LmsResultSuccess))
|
||||||
]
|
]
|
||||||
dbtFilter = Map.fromList
|
dbtFilter = Map.fromList
|
||||||
[ (csvLmsIdent , FilterColumn . E.mkContainsFilterWith LmsIdent $ views (to queryLmsResult) (E.^. LmsResultIdent))
|
[ ("school" , FilterColumn . E.mkExactFilter $ views (to queryQualification) (E.^. QualificationSchool))
|
||||||
, (csvLmsSuccess, FilterColumn . E.mkExactFilter $ views (to queryLmsResult) (E.^. LmsResultSuccess))
|
, (csvLmsIdent , FilterColumn . E.mkContainsFilterWith LmsIdent $ views (to queryLmsResult) (E.^. LmsResultIdent))
|
||||||
|
, (csvLmsSuccess, FilterColumn . E.mkExactFilter $ views (to queryLmsResult) (E.^. LmsResultSuccess))
|
||||||
]
|
]
|
||||||
dbtFilterUI = \mPrev -> mconcat
|
dbtFilterUI = \mPrev -> mconcat
|
||||||
[ prismAForm (singletonFilter csvLmsIdent . maybePrism _PathPiece) mPrev $ aopt (hoistField lift textField) (fslI MsgTableLmsIdent)
|
[ prismAForm (singletonFilter "school" . maybePrism (_PathPiece . from _SchoolId)) mPrev $ aopt (hoistField lift schoolField) (fslI MsgTableCourseSchool)
|
||||||
, prismAForm (singletonFilter csvLmsSuccess . maybePrism _PathPiece) mPrev $ aopt (hoistField lift checkBoxField) (fslI MsgTableLmsSuccess)
|
, prismAForm (singletonFilter csvLmsIdent . maybePrism _PathPiece) mPrev $ aopt (hoistField lift textField) (fslI MsgTableLmsIdent)
|
||||||
|
, prismAForm (singletonFilter csvLmsSuccess . maybePrism _PathPiece) mPrev $ aopt (hoistField lift checkBoxField) (fslI MsgTableLmsSuccess)
|
||||||
]
|
]
|
||||||
dbtStyle = def { dbsFilterLayout = defaultDBSFilterLayout }
|
dbtStyle = def { dbsFilterLayout = defaultDBSFilterLayout }
|
||||||
dbtParams = def
|
dbtParams = def
|
||||||
dbtIdent :: Text
|
dbtIdent :: Text
|
||||||
dbtIdent = "lms-result"
|
dbtIdent = "qualification"
|
||||||
dbtCsvEncode = Just DBTCsvEncode
|
dbtCsvEncode = noCsvEncode
|
||||||
{ dbtCsvExportForm = pure ()
|
dbtCsvDecode = Nothing
|
||||||
, dbtCsvDoEncode = \() -> C.map (doEncode' . view _2)
|
|
||||||
, dbtCsvName
|
|
||||||
, dbtCsvSheetName
|
|
||||||
, dbtCsvNoExportData = Just id
|
|
||||||
, dbtCsvHeader = const $ return lmsResultTableCsvHeader
|
|
||||||
, dbtCsvExampleData = Nothing
|
|
||||||
}
|
|
||||||
where
|
|
||||||
doEncode' = LmsResultTableCsv
|
|
||||||
<$> view (resultLmsResult . _entityVal . _lmsResultIdent)
|
|
||||||
<*> view (resultLmsResult . _entityVal . _lmsResultSuccess)
|
|
||||||
|
|
||||||
dbtCsvDecode = Just DBTCsvDecode -- Just save to DB; Job will process data later
|
|
||||||
{ dbtCsvRowKey = \LmsResultTableCsv{..} ->
|
|
||||||
fmap E.Value . MaybeT . getKeyBy $ UniqueLmsResult qid csvLRTident
|
|
||||||
, dbtCsvComputeActions = \case -- purpose is to show a diff to the user first
|
|
||||||
DBCsvDiffNew{dbCsvNewKey = Nothing, dbCsvNew} -> do
|
|
||||||
yield $ LmsResultInsertData
|
|
||||||
{ lmsResultInsertIdent = csvLRTident dbCsvNew
|
|
||||||
, lmsResultInsertSuccess = csvLRTsuccess dbCsvNew
|
|
||||||
}
|
|
||||||
DBCsvDiffNew{dbCsvNewKey = Just _, dbCsvNew = _} -> error "UniqueLmsResult was found, but the key no longer exists." -- TODO: how can this ever happen? Check Pagination-Code
|
|
||||||
DBCsvDiffMissing{} -> return () -- no deletion
|
|
||||||
DBCsvDiffExisting{} -> return () -- no merge TODO!!! ADD MERGE DUE TO Uniqueness!
|
|
||||||
, dbtCsvClassifyAction = \LmsResultInsertData{} -> LmsResultInsert
|
|
||||||
, dbtCsvCoarsenActionClass = \LmsResultInsert -> DBCsvActionNew -- there is only one action: insert into table
|
|
||||||
, dbtCsvValidateActions = return () -- no validation, since this is an automatic upload, i.e. no user to review error
|
|
||||||
, dbtCsvExecuteActions = do
|
|
||||||
C.mapM_ $ \LmsResultInsertData{..} -> do
|
|
||||||
now <- liftIO getCurrentTime
|
|
||||||
void $ upsert
|
|
||||||
LmsResult
|
|
||||||
{ lmsResultQualification = qid
|
|
||||||
, lmsResultIdent = lmsResultInsertIdent
|
|
||||||
, lmsResultSuccess = lmsResultInsertSuccess
|
|
||||||
, lmsResultTimestamp = now -- lmsResultInsertTimestamp -- does it matter which one to choose?
|
|
||||||
}
|
|
||||||
[ LmsResultSuccess =. lmsResultInsertSuccess
|
|
||||||
, LmsResultTimestamp =. now
|
|
||||||
]
|
|
||||||
-- queueDBJob?? -- todo
|
|
||||||
-- audit
|
|
||||||
return $ LmsResultR sid qsh
|
|
||||||
, dbtCsvRenderKey = \_ LmsResultInsertData{..} -> do -- TODO: i18n
|
|
||||||
[whamlet|
|
|
||||||
$newline never
|
|
||||||
Ident #{getLmsIdent lmsResultInsertIdent} #
|
|
||||||
had success on ^{formatTimeW SelFormatDate lmsResultInsertSuccess}
|
|
||||||
|]
|
|
||||||
, dbtCsvRenderActionClass = toWidget <=< ap getMessageRender . pure
|
|
||||||
, dbtCsvRenderException = ap getMessageRender . pure :: LmsResultCsvException -> DB Text
|
|
||||||
}
|
|
||||||
dbtExtraReps = []
|
dbtExtraReps = []
|
||||||
|
|
||||||
resultDBTableValidator = def
|
resultDBTableValidator = def
|
||||||
@ -335,8 +240,8 @@ getLmsR, postLmsR :: SchoolId -> QualificationShorthand -> Handler Html
|
|||||||
getLmsR = postLmsR
|
getLmsR = postLmsR
|
||||||
postLmsR sid qsh = do
|
postLmsR sid qsh = do
|
||||||
lmsTable <- runDB $ do
|
lmsTable <- runDB $ do
|
||||||
qid <- getKeyBy404 $ UniqueQualificationSchoolShort sid qsh
|
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
||||||
view _2 <$> mkLmsTable sid qsh qid
|
view _2 <$> mkLmsTable qid
|
||||||
siteLayoutMsg MsgMenuLmsResult $ do
|
siteLayoutMsg MsgMenuLmsResult $ do
|
||||||
setTitleI MsgMenuLmsResult
|
setTitleI MsgMenuLmsResult
|
||||||
$(widgetFile "lms")
|
$(widgetFile "lms")
|
||||||
|
|||||||
@ -197,7 +197,7 @@ getLmsResultR = postLmsResultR
|
|||||||
postLmsResultR sid qsh = do
|
postLmsResultR sid qsh = do
|
||||||
let directUploadLink = LmsResultUploadR sid qsh
|
let directUploadLink = LmsResultUploadR sid qsh
|
||||||
lmsTable <- runDB $ do
|
lmsTable <- runDB $ do
|
||||||
qid <- getKeyBy404 $ UniqueQualificationSchoolShort sid qsh
|
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
||||||
view _2 <$> mkResultTable sid qsh qid
|
view _2 <$> mkResultTable sid qsh qid
|
||||||
siteLayoutMsg MsgMenuLmsResult $ do
|
siteLayoutMsg MsgMenuLmsResult $ do
|
||||||
setTitleI MsgMenuLmsResult
|
setTitleI MsgMenuLmsResult
|
||||||
@ -235,7 +235,7 @@ postLmsResultUploadR sid qsh = do
|
|||||||
-- content <- fileSourceByteString file
|
-- content <- fileSourceByteString file
|
||||||
-- return $ Just (fileName file, content)
|
-- return $ Just (fileName file, content)
|
||||||
nr <- runDB $ do
|
nr <- runDB $ do
|
||||||
qid <- getKeyBy404 $ UniqueQualificationSchoolShort sid qsh
|
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
||||||
runConduit $ fileSource file
|
runConduit $ fileSource file
|
||||||
.| decodeCsv
|
.| decodeCsv
|
||||||
.| foldMC (saveResultCsv qid) 0
|
.| foldMC (saveResultCsv qid) 0
|
||||||
@ -261,7 +261,7 @@ postLmsResultDirectR sid qsh = do
|
|||||||
case files of
|
case files of
|
||||||
[(fhead,file)] -> do
|
[(fhead,file)] -> do
|
||||||
nr <- runDB $ do
|
nr <- runDB $ do
|
||||||
qid <- getKeyBy404 $ UniqueQualificationSchoolShort sid qsh
|
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
||||||
runConduit $ fileSource file
|
runConduit $ fileSource file
|
||||||
.| decodeCsv
|
.| decodeCsv
|
||||||
.| foldMC (saveResultCsv qid) 0
|
.| foldMC (saveResultCsv qid) 0
|
||||||
|
|||||||
@ -197,7 +197,7 @@ getLmsUserlistR, postLmsUserlistR :: SchoolId -> QualificationShorthand -> Handl
|
|||||||
getLmsUserlistR = postLmsUserlistR
|
getLmsUserlistR = postLmsUserlistR
|
||||||
postLmsUserlistR sid qsh = do
|
postLmsUserlistR sid qsh = do
|
||||||
lmsTable <- runDB $ do
|
lmsTable <- runDB $ do
|
||||||
qid <- getKeyBy404 $ UniqueQualificationSchoolShort sid qsh
|
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
||||||
view _2 <$> mkUserlistTable sid qsh qid
|
view _2 <$> mkUserlistTable sid qsh qid
|
||||||
siteLayoutMsg MsgMenuLmsUserlist $ do
|
siteLayoutMsg MsgMenuLmsUserlist $ do
|
||||||
setTitleI MsgMenuLmsUserlist
|
setTitleI MsgMenuLmsUserlist
|
||||||
@ -233,7 +233,7 @@ postLmsUserlistUploadR sid qsh = do
|
|||||||
case result of
|
case result of
|
||||||
FormSuccess file -> do
|
FormSuccess file -> do
|
||||||
nr <- runDB $ do
|
nr <- runDB $ do
|
||||||
qid <- getKeyBy404 $ UniqueQualificationSchoolShort sid qsh
|
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
||||||
runConduit $ fileSource file
|
runConduit $ fileSource file
|
||||||
.| decodeCsv
|
.| decodeCsv
|
||||||
.| foldMC (saveUserlistCsv qid) 0
|
.| foldMC (saveUserlistCsv qid) 0
|
||||||
@ -259,7 +259,7 @@ postLmsUserlistDirectR sid qsh = do
|
|||||||
case files of
|
case files of
|
||||||
[(fhead,file)] -> do
|
[(fhead,file)] -> do
|
||||||
nr <- runDB $ do
|
nr <- runDB $ do
|
||||||
qid <- getKeyBy404 $ UniqueQualificationSchoolShort sid qsh
|
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
||||||
runConduit $ fileSource file
|
runConduit $ fileSource file
|
||||||
.| decodeCsv
|
.| decodeCsv
|
||||||
.| foldMC (saveUserlistCsv qid) 0
|
.| foldMC (saveUserlistCsv qid) 0
|
||||||
|
|||||||
@ -140,7 +140,7 @@ mkUserTable _sid qsh qid = do
|
|||||||
getLmsUsersR :: SchoolId -> QualificationShorthand -> Handler Html
|
getLmsUsersR :: SchoolId -> QualificationShorthand -> Handler Html
|
||||||
getLmsUsersR sid qsh = do
|
getLmsUsersR sid qsh = do
|
||||||
lmsTable <- runDB $ do
|
lmsTable <- runDB $ do
|
||||||
qid <- getKeyBy404 $ UniqueQualificationSchoolShort sid qsh
|
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
||||||
view _2 <$> mkUserTable sid qsh qid
|
view _2 <$> mkUserTable sid qsh qid
|
||||||
siteLayoutMsg MsgMenuLmsUsers $ do
|
siteLayoutMsg MsgMenuLmsUsers $ do
|
||||||
setTitleI MsgMenuLmsUsers
|
setTitleI MsgMenuLmsUsers
|
||||||
@ -149,7 +149,7 @@ getLmsUsersR sid qsh = do
|
|||||||
getLmsUsersDirectR :: SchoolId -> QualificationShorthand -> Handler TypedContent
|
getLmsUsersDirectR :: SchoolId -> QualificationShorthand -> Handler TypedContent
|
||||||
getLmsUsersDirectR sid qsh = do
|
getLmsUsersDirectR sid qsh = do
|
||||||
lms_users <- runDB $ do
|
lms_users <- runDB $ do
|
||||||
qid <- getKeyBy404 $ UniqueQualificationSchoolShort sid qsh
|
qid <- getKeyBy404 $ SchoolQualificationShort sid qsh
|
||||||
selectList [LmsUserQualification ==. qid, LmsUserEnded ==. Nothing] [Asc LmsUserStarted, Asc LmsUserIdent]
|
selectList [LmsUserQualification ==. qid, LmsUserEnded ==. Nothing] [Asc LmsUserStarted, Asc LmsUserIdent]
|
||||||
{- To avoid exporting unneeded columns, we would need an SqlSelect instance for LmsUserTableCsv; probably not worth it
|
{- To avoid exporting unneeded columns, we would need an SqlSelect instance for LmsUserTableCsv; probably not worth it
|
||||||
Ex.select $ do
|
Ex.select $ do
|
||||||
|
|||||||
@ -85,6 +85,7 @@ data Icon
|
|||||||
| IconMenuCorrections
|
| IconMenuCorrections
|
||||||
| IconMenuExams
|
| IconMenuExams
|
||||||
| IconMenuAdmin
|
| IconMenuAdmin
|
||||||
|
| IconMenuLms
|
||||||
| IconPageActionPrimaryExpand | IconPageActionSecondary
|
| IconPageActionPrimaryExpand | IconPageActionSecondary
|
||||||
| IconBreadcrumbSeparator
|
| IconBreadcrumbSeparator
|
||||||
| IconMissingAllocationPriority
|
| IconMissingAllocationPriority
|
||||||
@ -169,6 +170,7 @@ iconText = \case
|
|||||||
IconMenuCorrections -> "check"
|
IconMenuCorrections -> "check"
|
||||||
IconMenuExams -> "poll-h"
|
IconMenuExams -> "poll-h"
|
||||||
IconMenuAdmin -> "screwdriver"
|
IconMenuAdmin -> "screwdriver"
|
||||||
|
IconMenuLms -> "chalkboard-teacher" -- From fontawesome v6 onwards: "chalkboard-user" / or "desktop" for both
|
||||||
IconPageActionPrimaryExpand -> "bars"
|
IconPageActionPrimaryExpand -> "bars"
|
||||||
IconPageActionSecondary -> "ellipsis-h"
|
IconPageActionSecondary -> "ellipsis-h"
|
||||||
IconBreadcrumbSeparator -> "angle-right"
|
IconBreadcrumbSeparator -> "angle-right"
|
||||||
|
|||||||
Reference in New Issue
Block a user