feat(schools): implement cru
This commit is contained in:
parent
2afa338959
commit
18ae28abbc
@ -1031,6 +1031,8 @@ MenuExamAddMembers: Prüfungsteilnehmer hinzufügen
|
|||||||
MenuLecturerInvite: Dozenten hinzufügen
|
MenuLecturerInvite: Dozenten hinzufügen
|
||||||
MenuAllocationInfo: Hinweise zum Ablauf einer Zentralanmeldung
|
MenuAllocationInfo: Hinweise zum Ablauf einer Zentralanmeldung
|
||||||
MenuCourseApplicationsFiles: Dateien aller Bewerbungen
|
MenuCourseApplicationsFiles: Dateien aller Bewerbungen
|
||||||
|
MenuSchoolList: Institute
|
||||||
|
MenuSchoolNew: Neues Institut anlegen
|
||||||
|
|
||||||
AuthPredsInfo: Um eigene Veranstaltungen aus Sicht der Teilnehmer anzusehen, können Veranstalter und Korrektoren hier die Prüfung ihrer erweiterten Berechtigungen temporär deaktivieren. Abgewählte Prädikate schlagen immer fehl. Abgewählte Prädikate werden also nicht geprüft um Zugriffe zu gewähren, welche andernfalls nicht erlaubt wären. Diese Einstellungen gelten nur temporär bis Ihre Sitzung abgelaufen ist, d.h. bis ihr Browser-Cookie abgelaufen ist. Durch Abwahl von Prädikaten kann man sich höchstens temporär aussperren.
|
AuthPredsInfo: Um eigene Veranstaltungen aus Sicht der Teilnehmer anzusehen, können Veranstalter und Korrektoren hier die Prüfung ihrer erweiterten Berechtigungen temporär deaktivieren. Abgewählte Prädikate schlagen immer fehl. Abgewählte Prädikate werden also nicht geprüft um Zugriffe zu gewähren, welche andernfalls nicht erlaubt wären. Diese Einstellungen gelten nur temporär bis Ihre Sitzung abgelaufen ist, d.h. bis ihr Browser-Cookie abgelaufen ist. Durch Abwahl von Prädikaten kann man sich höchstens temporär aussperren.
|
||||||
AuthPredsActive: Aktive Authorisierungsprädikate
|
AuthPredsActive: Aktive Authorisierungsprädikate
|
||||||
@ -1562,4 +1564,13 @@ CourseApplicationNoRatingPoints: Keine Bewertung
|
|||||||
CourseApplicationNoRatingComment: Kein Kommentar
|
CourseApplicationNoRatingComment: Kein Kommentar
|
||||||
|
|
||||||
UserDisplayName: Voller Name
|
UserDisplayName: Voller Name
|
||||||
UserMatriculation: Matrikelnummer
|
UserMatriculation: Matrikelnummer
|
||||||
|
|
||||||
|
SchoolShort: Kürzel
|
||||||
|
SchoolName: Name
|
||||||
|
|
||||||
|
SchoolUpdated ssh@SchoolId: #{ssh} erfolgreich angepasst
|
||||||
|
SchoolTitle ssh@SchoolId: Institut „#{ssh}“
|
||||||
|
TitleSchoolNew: Neues Institut anlegen
|
||||||
|
SchoolCreated ssh@SchoolId: #{ssh} erfolgreich angelegt
|
||||||
|
SchoolExists ssh@SchoolId: Institut „#{ssh}“ existiert bereits
|
||||||
5
routes
5
routes
@ -78,8 +78,9 @@
|
|||||||
!/term/#TermId TermCourseListR GET !free
|
!/term/#TermId TermCourseListR GET !free
|
||||||
!/term/#TermId/#SchoolId TermSchoolCourseListR GET !free
|
!/term/#TermId/#SchoolId TermSchoolCourseListR GET !free
|
||||||
|
|
||||||
/school SchoolListR GET !development
|
/school SchoolListR GET
|
||||||
/school/#SchoolId SchoolShowR GET !development
|
!/school/new SchoolNewR GET POST
|
||||||
|
/school/#SchoolId SchoolShowR GET POST
|
||||||
|
|
||||||
/allocation/ AllocationListR GET !free
|
/allocation/ AllocationListR GET !free
|
||||||
/allocation/#TermId/#SchoolId/#AllocationShorthand AllocationR:
|
/allocation/#TermId/#SchoolId/#AllocationShorthand AllocationR:
|
||||||
|
|||||||
@ -1723,6 +1723,10 @@ instance YesodBreadcrumbs UniWorX where
|
|||||||
breadcrumb AdminFeaturesR = return ("Test" , Just AdminR)
|
breadcrumb AdminFeaturesR = return ("Test" , Just AdminR)
|
||||||
breadcrumb AdminTestR = return ("Test" , Just AdminR)
|
breadcrumb AdminTestR = return ("Test" , Just AdminR)
|
||||||
breadcrumb AdminErrMsgR = return ("Test" , Just AdminR)
|
breadcrumb AdminErrMsgR = return ("Test" , Just AdminR)
|
||||||
|
|
||||||
|
breadcrumb SchoolListR = return ("Institute" , Just AdminR)
|
||||||
|
breadcrumb (SchoolShowR ssh) = return (original (unSchoolKey ssh), Just SchoolListR)
|
||||||
|
breadcrumb SchoolNewR = return ("Neu" , Just SchoolListR)
|
||||||
|
|
||||||
breadcrumb InfoR = return ("Information" , Nothing)
|
breadcrumb InfoR = return ("Information" , Nothing)
|
||||||
breadcrumb InfoLecturerR = return ("Veranstalter" , Just InfoR)
|
breadcrumb InfoLecturerR = return ("Veranstalter" , Just InfoR)
|
||||||
@ -1996,6 +2000,14 @@ pageActions (HomeR) =
|
|||||||
]
|
]
|
||||||
pageActions (AdminR) =
|
pageActions (AdminR) =
|
||||||
[ MenuItem
|
[ MenuItem
|
||||||
|
{ menuItemType = PageActionPrime
|
||||||
|
, menuItemLabel = MsgMenuSchoolList
|
||||||
|
, menuItemIcon = Nothing
|
||||||
|
, menuItemRoute = SomeRoute SchoolListR
|
||||||
|
, menuItemModal = False
|
||||||
|
, menuItemAccessCallback' = return True
|
||||||
|
}
|
||||||
|
, MenuItem
|
||||||
{ menuItemType = PageActionPrime
|
{ menuItemType = PageActionPrime
|
||||||
, menuItemLabel = MsgAdminFeaturesHeading
|
, menuItemLabel = MsgAdminFeaturesHeading
|
||||||
, menuItemIcon = Nothing
|
, menuItemIcon = Nothing
|
||||||
@ -2028,6 +2040,16 @@ pageActions (AdminR) =
|
|||||||
, menuItemAccessCallback' = return True
|
, menuItemAccessCallback' = return True
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
pageActions (SchoolListR) =
|
||||||
|
[ MenuItem
|
||||||
|
{ menuItemType = PageActionPrime
|
||||||
|
, menuItemLabel = MsgMenuSchoolNew
|
||||||
|
, menuItemIcon = Nothing
|
||||||
|
, menuItemRoute = SomeRoute SchoolNewR
|
||||||
|
, menuItemModal = False
|
||||||
|
, menuItemAccessCallback' = return True
|
||||||
|
}
|
||||||
|
]
|
||||||
pageActions (UsersR) =
|
pageActions (UsersR) =
|
||||||
[ MenuItem
|
[ MenuItem
|
||||||
{ menuItemType = PageActionPrime
|
{ menuItemType = PageActionPrime
|
||||||
|
|||||||
@ -525,6 +525,7 @@ postCApplicationsR tid ssh csh = do
|
|||||||
|
|
||||||
psValidator :: PSValidator _ _
|
psValidator :: PSValidator _ _
|
||||||
psValidator = def
|
psValidator = def
|
||||||
|
& defaultSorting [SortAscBy "user-name"]
|
||||||
|
|
||||||
dbTableWidget' psValidator DBTable{..}
|
dbTableWidget' psValidator DBTable{..}
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,133 @@
|
|||||||
module Handler.School where
|
module Handler.School where
|
||||||
|
|
||||||
import Import
|
import Import
|
||||||
|
import Handler.Utils
|
||||||
|
import Handler.Utils.Table.Columns
|
||||||
|
|
||||||
|
import qualified Database.Esqueleto as E
|
||||||
|
|
||||||
getSchoolListR :: Handler Html
|
getSchoolListR :: Handler Html
|
||||||
getSchoolListR = error "getSchoolListR: Not implemented"
|
getSchoolListR = do
|
||||||
|
let
|
||||||
|
schoolLink :: SchoolId -> SomeRoute UniWorX
|
||||||
|
schoolLink ssh = SomeRoute $ SchoolShowR ssh
|
||||||
|
|
||||||
|
dbtSQLQuery :: E.SqlExpr (Entity School) -> E.SqlQuery _
|
||||||
|
dbtSQLQuery = return
|
||||||
|
|
||||||
getSchoolShowR :: SchoolId -> Handler Html
|
dbtProj :: DBRow _ -> MaybeT (YesodDB UniWorX) (DBRow (Entity School))
|
||||||
getSchoolShowR = error "getSchoolShowR: Not implemented"
|
dbtProj = return
|
||||||
|
|
||||||
|
dbtRowKey = (E.^. SchoolId)
|
||||||
|
|
||||||
|
dbtColonnade :: Colonnade Sortable _ _
|
||||||
|
dbtColonnade = mconcat
|
||||||
|
[ colSchoolShort $ _dbrOutput . _entityKey
|
||||||
|
, anchorColonnade (views (_dbrOutput . _entityKey) schoolLink) $ colSchoolName (_dbrOutput . _entityVal . _schoolName)
|
||||||
|
]
|
||||||
|
|
||||||
|
dbtSorting = mconcat
|
||||||
|
[ sortSchoolShort $ to (E.^. SchoolId)
|
||||||
|
, sortSchoolName $ to (E.^. SchoolName)
|
||||||
|
]
|
||||||
|
|
||||||
|
dbtFilter = mempty
|
||||||
|
dbtFilterUI = mempty
|
||||||
|
|
||||||
|
dbtStyle = def
|
||||||
|
dbtParams = def
|
||||||
|
|
||||||
|
dbtCsvEncode = noCsvEncode
|
||||||
|
dbtCsvDecode = Nothing
|
||||||
|
|
||||||
|
dbtIdent :: Text
|
||||||
|
dbtIdent = "schools"
|
||||||
|
|
||||||
|
psValidator = def
|
||||||
|
& defaultSorting [SortAscBy "school-name"]
|
||||||
|
|
||||||
|
|
||||||
|
table <- runDB $ dbTableWidget' psValidator DBTable{..}
|
||||||
|
|
||||||
|
let title = MsgMenuSchoolList
|
||||||
|
siteLayoutMsg title $ do
|
||||||
|
setTitleI title
|
||||||
|
table
|
||||||
|
|
||||||
|
data SchoolForm = SchoolForm
|
||||||
|
{ sfShorthand :: CI Text
|
||||||
|
, sfName :: CI Text
|
||||||
|
}
|
||||||
|
|
||||||
|
mkSchoolForm :: Maybe SchoolId -> Maybe SchoolForm -> Form SchoolForm
|
||||||
|
mkSchoolForm mSsh template = renderAForm FormStandard $ SchoolForm
|
||||||
|
<$> maybe (\f fs -> areq f fs (sfShorthand <$> template)) (\ssh f fs -> aforced f fs (unSchoolKey ssh)) mSsh ciField (fslI MsgSchoolShort)
|
||||||
|
<*> areq ciField (fslI MsgSchoolName) (sfName <$> template)
|
||||||
|
|
||||||
|
schoolToForm :: SchoolId -> DB (Form SchoolForm)
|
||||||
|
schoolToForm ssh = do
|
||||||
|
School{..} <- get404 ssh
|
||||||
|
return . mkSchoolForm (Just ssh) $ Just SchoolForm
|
||||||
|
{ sfShorthand = schoolShorthand
|
||||||
|
, sfName = schoolName
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getSchoolShowR, postSchoolShowR :: SchoolId -> Handler Html
|
||||||
|
getSchoolShowR = postSchoolShowR
|
||||||
|
postSchoolShowR ssh = do
|
||||||
|
sForm <- runDB $ schoolToForm ssh
|
||||||
|
|
||||||
|
((sfResult, sfView), sfEnctype) <- runFormPost sForm
|
||||||
|
|
||||||
|
formResult sfResult $ \SchoolForm{..} -> do
|
||||||
|
runDB $ do
|
||||||
|
update ssh [ SchoolName =. sfName ]
|
||||||
|
addMessageI Success $ MsgSchoolUpdated ssh
|
||||||
|
redirect $ SchoolShowR ssh
|
||||||
|
|
||||||
|
let sfView' = wrapForm sfView FormSettings
|
||||||
|
{ formMethod = POST
|
||||||
|
, formAction = Just . SomeRoute $ SchoolShowR ssh
|
||||||
|
, formEncoding = sfEnctype
|
||||||
|
, formAttrs = []
|
||||||
|
, formSubmit = FormSubmit
|
||||||
|
, formAnchor = Nothing :: Maybe Text
|
||||||
|
}
|
||||||
|
|
||||||
|
siteLayoutMsg (MsgSchoolTitle ssh) $ do
|
||||||
|
setTitleI $ MsgSchoolTitle ssh
|
||||||
|
sfView'
|
||||||
|
|
||||||
|
getSchoolNewR, postSchoolNewR :: Handler Html
|
||||||
|
getSchoolNewR = postSchoolNewR
|
||||||
|
postSchoolNewR = do
|
||||||
|
((sfResult, sfView), sfEnctype) <- runFormPost $ mkSchoolForm Nothing Nothing
|
||||||
|
|
||||||
|
formResult sfResult $ \SchoolForm{..} -> do
|
||||||
|
let ssh = SchoolKey sfShorthand
|
||||||
|
insertOkay <- runDB $ do
|
||||||
|
fmap (is _Just) $ insertUnique School
|
||||||
|
{ schoolShorthand = sfShorthand
|
||||||
|
, schoolName = sfName
|
||||||
|
}
|
||||||
|
|
||||||
|
if
|
||||||
|
| insertOkay -> do
|
||||||
|
addMessageI Success $ MsgSchoolCreated ssh
|
||||||
|
redirect $ SchoolShowR ssh
|
||||||
|
| otherwise
|
||||||
|
-> addMessageI Error $ MsgSchoolExists ssh
|
||||||
|
|
||||||
|
let sfView' = wrapForm sfView FormSettings
|
||||||
|
{ formMethod = POST
|
||||||
|
, formAction = Just $ SomeRoute SchoolNewR
|
||||||
|
, formEncoding = sfEnctype
|
||||||
|
, formAttrs = []
|
||||||
|
, formSubmit = FormSubmit
|
||||||
|
, formAnchor = Nothing :: Maybe Text
|
||||||
|
}
|
||||||
|
|
||||||
|
siteLayoutMsg MsgTitleSchoolNew $ do
|
||||||
|
setTitleI MsgTitleSchoolNew
|
||||||
|
sfView'
|
||||||
|
|||||||
@ -102,8 +102,8 @@ fltrTermUI mPrev = prismAForm (singletonFilter "term" . maybePrism _PathPiece) m
|
|||||||
-- Schools --
|
-- Schools --
|
||||||
-------------
|
-------------
|
||||||
|
|
||||||
colSchoolShort :: OpticColonnade SchoolId
|
colSchool :: OpticColonnade SchoolId
|
||||||
colSchoolShort resultSsh = Colonnade.singleton (fromSortable header) body
|
colSchool resultSsh = Colonnade.singleton (fromSortable header) body
|
||||||
where
|
where
|
||||||
header = Sortable (Just "school") (i18nCell MsgSchool)
|
header = Sortable (Just "school") (i18nCell MsgSchool)
|
||||||
body = i18nCell . unSchoolKey . view resultSsh
|
body = i18nCell . unSchoolKey . view resultSsh
|
||||||
@ -111,6 +111,24 @@ colSchoolShort resultSsh = Colonnade.singleton (fromSortable header) body
|
|||||||
sortSchool :: OpticSortColumn SchoolId
|
sortSchool :: OpticSortColumn SchoolId
|
||||||
sortSchool querySsh = singletonMap "school" . SortColumn $ view querySsh
|
sortSchool querySsh = singletonMap "school" . SortColumn $ view querySsh
|
||||||
|
|
||||||
|
colSchoolShort :: OpticColonnade SchoolId
|
||||||
|
colSchoolShort resultSsh = Colonnade.singleton (fromSortable header) body
|
||||||
|
where
|
||||||
|
header = Sortable (Just "school-short") (i18nCell MsgSchoolShort)
|
||||||
|
body = i18nCell . unSchoolKey . view resultSsh
|
||||||
|
|
||||||
|
sortSchoolShort :: OpticSortColumn SchoolId
|
||||||
|
sortSchoolShort querySsh = singletonMap "school-short" . SortColumn $ view querySsh
|
||||||
|
|
||||||
|
colSchoolName :: OpticColonnade SchoolName
|
||||||
|
colSchoolName resultSn = Colonnade.singleton (fromSortable header) body
|
||||||
|
where
|
||||||
|
header = Sortable (Just "school-name") (i18nCell MsgSchoolName)
|
||||||
|
body = i18nCell . view resultSn
|
||||||
|
|
||||||
|
sortSchoolName :: OpticSortColumn SchoolName
|
||||||
|
sortSchoolName querySn = singletonMap "school-name" . SortColumn $ view querySn
|
||||||
|
|
||||||
fltrSchool :: OpticFilterColumn t SchoolId
|
fltrSchool :: OpticFilterColumn t SchoolId
|
||||||
fltrSchool querySsh = singletonMap "school" . FilterColumn $ mkExactFilter (view querySsh)
|
fltrSchool querySsh = singletonMap "school" . FilterColumn $ mkExactFilter (view querySsh)
|
||||||
|
|
||||||
|
|||||||
@ -167,6 +167,8 @@ makeLenses_ ''Allocation
|
|||||||
|
|
||||||
makeLenses_ ''File
|
makeLenses_ ''File
|
||||||
|
|
||||||
|
makeLenses_ ''School
|
||||||
|
|
||||||
|
|
||||||
-- makeClassy_ ''Load
|
-- makeClassy_ ''Load
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user