feat: add user-system-function
This commit is contained in:
parent
1b172e4b48
commit
abc37aca9c
@ -765,6 +765,9 @@ CorrectorsFor n@Int: #{pluralDE n "Korrektor" "Korrektoren"}
|
|||||||
UserListTitle: Komprehensive Benutzerliste
|
UserListTitle: Komprehensive Benutzerliste
|
||||||
AccessRightsSaved: Berechtigungen erfolgreich verändert
|
AccessRightsSaved: Berechtigungen erfolgreich verändert
|
||||||
AccessRightsNotChanged: Berechtigungen wurden nicht verändert
|
AccessRightsNotChanged: Berechtigungen wurden nicht verändert
|
||||||
|
UserSystemFunctions: Systemweite Rollen
|
||||||
|
UserSystemFunctionsSaved: Systemweite Rollen gespeichert
|
||||||
|
UserSystemFunctionsNotChanged: Es wurden keine systemweiten Rollen angepasst
|
||||||
|
|
||||||
LecturersForN n@Int: #{pluralDE n "Dozent" "Dozenten"}
|
LecturersForN n@Int: #{pluralDE n "Dozent" "Dozenten"}
|
||||||
|
|
||||||
@ -1014,6 +1017,10 @@ MailUserRightsIntro name@Text email@UserEmail: #{name} <#{email}> hat folgende U
|
|||||||
MailNoLecturerRights: Sie haben derzeit keine Dozenten-Rechte.
|
MailNoLecturerRights: Sie haben derzeit keine Dozenten-Rechte.
|
||||||
MailLecturerRights n@Int: Als Dozent dürfen Sie Veranstaltungen innerhalb #{pluralDE n "Ihres Instituts" "Ihrer Institute"} anlegen.
|
MailLecturerRights n@Int: Als Dozent dürfen Sie Veranstaltungen innerhalb #{pluralDE n "Ihres Instituts" "Ihrer Institute"} anlegen.
|
||||||
|
|
||||||
|
MailSubjectUserSystemFunctionsUpdate name@Text: Berechtigungen für #{name} aktualisiert
|
||||||
|
MailUserSystemFunctionsIntro name@Text email@UserEmail: #{name} <#{email}> hat folgende Uni2work nicht-institutsbezogene Berechtigungen:
|
||||||
|
MailUserSystemFunctionsNoFunctions: Keine
|
||||||
|
|
||||||
MailSubjectUserAuthModeUpdate: Ihr Uni2work-Login
|
MailSubjectUserAuthModeUpdate: Ihr Uni2work-Login
|
||||||
UserAuthModePWHashChangedToLDAP: Sie können sich nun mit Ihrer Campus-Kennung in Uni2work einloggen
|
UserAuthModePWHashChangedToLDAP: Sie können sich nun mit Ihrer Campus-Kennung in Uni2work einloggen
|
||||||
UserAuthModeLDAPChangedToPWHash: Sie können sich nun mit einer Uni2work-internen Kennung in Uni2work einloggen
|
UserAuthModeLDAPChangedToPWHash: Sie können sich nun mit einer Uni2work-internen Kennung in Uni2work einloggen
|
||||||
@ -2750,3 +2757,6 @@ SheetPersonalisedFilesUsersList: Liste von Teilnehmern mit personalisierten Übu
|
|||||||
AdminCrontabNotGenerated: (Noch) keine Crontab generiert
|
AdminCrontabNotGenerated: (Noch) keine Crontab generiert
|
||||||
CronMatchAsap: ASAP
|
CronMatchAsap: ASAP
|
||||||
CronMatchNone: Nie
|
CronMatchNone: Nie
|
||||||
|
|
||||||
|
SystemExamOffice: Prüfungsverwaltung
|
||||||
|
SystemFaculty: Fakultätsmitglied
|
||||||
@ -762,6 +762,9 @@ CorrectorsFor n: #{pluralEN n "Corrector" "Correctors"}
|
|||||||
UserListTitle: Comprehensive list of users
|
UserListTitle: Comprehensive list of users
|
||||||
AccessRightsSaved: Successfully updated permissions
|
AccessRightsSaved: Successfully updated permissions
|
||||||
AccessRightsNotChanged: Permissions left unchanged
|
AccessRightsNotChanged: Permissions left unchanged
|
||||||
|
UserSystemFunctions: System wide roles
|
||||||
|
UserSystemFunctionsSaved: Successfully saved system wide roles
|
||||||
|
UserSystemFunctionsNotChanged: No system wide roles were changed
|
||||||
|
|
||||||
LecturersForN n: #{pluralEN n "Lecturer" "Lecturers"}
|
LecturersForN n: #{pluralEN n "Lecturer" "Lecturers"}
|
||||||
|
|
||||||
@ -1014,6 +1017,10 @@ MailUserRightsIntro name email: #{name} <#{email}> now has the following permiss
|
|||||||
MailNoLecturerRights: You don't currently have lecturer permissions for any department.
|
MailNoLecturerRights: You don't currently have lecturer permissions for any department.
|
||||||
MailLecturerRights n: As a lecturer you may create new courses within your #{pluralEN n "department" "departments"}.
|
MailLecturerRights n: As a lecturer you may create new courses within your #{pluralEN n "department" "departments"}.
|
||||||
|
|
||||||
|
MailSubjectUserSystemFunctionsUpdate name: Permissions for #{name} changed
|
||||||
|
MailUserSystemFunctionsIntro name email: #{name} <#{email}> now has the following, not school restricted, permissions:
|
||||||
|
MailUserSystemFunctionsNoFunctions: None
|
||||||
|
|
||||||
MailSubjectUserAuthModeUpdate: Your Uni2work login
|
MailSubjectUserAuthModeUpdate: Your Uni2work login
|
||||||
UserAuthModePWHashChangedToLDAP: You can now log in to Uni2work using your Campus-account
|
UserAuthModePWHashChangedToLDAP: You can now log in to Uni2work using your Campus-account
|
||||||
UserAuthModeLDAPChangedToPWHash: You can now log in to Uni2work using your Uni2work-internal account
|
UserAuthModeLDAPChangedToPWHash: You can now log in to Uni2work using your Uni2work-internal account
|
||||||
@ -2751,3 +2758,6 @@ SheetPersonalisedFilesUsersList: List of course participants who have personalis
|
|||||||
AdminCrontabNotGenerated: Crontab not (yet) generated
|
AdminCrontabNotGenerated: Crontab not (yet) generated
|
||||||
CronMatchAsap: ASAP
|
CronMatchAsap: ASAP
|
||||||
CronMatchNone: Never
|
CronMatchNone: Never
|
||||||
|
|
||||||
|
SystemExamOffice: Exam office
|
||||||
|
SystemFaculty: Faculty member
|
||||||
|
|||||||
@ -42,6 +42,10 @@ UserFunction -- Administratively assigned functions (lecturer, admin, evaluation
|
|||||||
school SchoolId
|
school SchoolId
|
||||||
function SchoolFunction
|
function SchoolFunction
|
||||||
UniqueUserFunction user school function
|
UniqueUserFunction user school function
|
||||||
|
UserSystemFunction
|
||||||
|
user UserId
|
||||||
|
function SystemFunction
|
||||||
|
UniqueUserSystemFunction user function
|
||||||
UserExamOffice
|
UserExamOffice
|
||||||
user UserId
|
user UserId
|
||||||
field StudyTermsId
|
field StudyTermsId
|
||||||
|
|||||||
@ -219,6 +219,7 @@ embedRenderMessage ''UniWorX ''UploadModeDescr id
|
|||||||
embedRenderMessage ''UniWorX ''SecretJSONFieldException id
|
embedRenderMessage ''UniWorX ''SecretJSONFieldException id
|
||||||
embedRenderMessage ''UniWorX ''AFormMessage $ concat . drop 2 . splitCamel
|
embedRenderMessage ''UniWorX ''AFormMessage $ concat . drop 2 . splitCamel
|
||||||
embedRenderMessage ''UniWorX ''SchoolFunction id
|
embedRenderMessage ''UniWorX ''SchoolFunction id
|
||||||
|
embedRenderMessage ''UniWorX ''SystemFunction id
|
||||||
embedRenderMessage ''UniWorX ''CsvPreset id
|
embedRenderMessage ''UniWorX ''CsvPreset id
|
||||||
embedRenderMessage ''UniWorX ''Quoting ("Csv" <>)
|
embedRenderMessage ''UniWorX ''Quoting ("Csv" <>)
|
||||||
embedRenderMessage ''UniWorX ''FavouriteReason id
|
embedRenderMessage ''UniWorX ''FavouriteReason id
|
||||||
|
|||||||
@ -277,7 +277,7 @@ getAdminUserR = postAdminUserR
|
|||||||
postAdminUserR uuid = do
|
postAdminUserR uuid = do
|
||||||
adminId <- requireAuthId
|
adminId <- requireAuthId
|
||||||
uid <- decrypt uuid
|
uid <- decrypt uuid
|
||||||
(user@User{..}, adminSchools, functions, schools) <- runDB $ do
|
(user@User{..}, adminSchools, functions, schools, systemFunctions) <- runDB $ do
|
||||||
user <- get404 uid
|
user <- get404 uid
|
||||||
|
|
||||||
schools <- E.select . E.from $ \(school `E.LeftOuterJoin` userFunction) -> do
|
schools <- E.select . E.from $ \(school `E.LeftOuterJoin` userFunction) -> do
|
||||||
@ -289,10 +289,14 @@ postAdminUserR uuid = do
|
|||||||
E.&&. adminFunction E.^. UserFunctionFunction E.==. E.val SchoolAdmin
|
E.&&. adminFunction E.^. UserFunctionFunction E.==. E.val SchoolAdmin
|
||||||
return (school, userFunction E.?. UserFunctionFunction, isAdmin)
|
return (school, userFunction E.?. UserFunctionFunction, isAdmin)
|
||||||
|
|
||||||
|
systemFunctionsF <- Set.fromList . map (userSystemFunctionFunction . entityVal) <$> selectList [UserSystemFunctionUser ==. uid] []
|
||||||
|
let systemFunctions = (`Set.member` systemFunctionsF)
|
||||||
|
|
||||||
return ( user
|
return ( user
|
||||||
, setOf (folded . filtered (view $ _3 . _Value) . _1 . _entityKey) schools
|
, setOf (folded . filtered (view $ _3 . _Value) . _1 . _entityKey) schools
|
||||||
, setOf (folded . folding (\x -> (,) <$> preview (_2 . _Value . _Just) x <*> preview (_1 . _entityKey) x)) schools
|
, setOf (folded . folding (\x -> (,) <$> preview (_2 . _Value . _Just) x <*> preview (_1 . _entityKey) x)) schools
|
||||||
, setOf (folded . _1) schools
|
, setOf (folded . _1) schools
|
||||||
|
, systemFunctions
|
||||||
)
|
)
|
||||||
let allFunctions = Set.fromList universeF
|
let allFunctions = Set.fromList universeF
|
||||||
allSchools = Set.mapMonotonic entityKey schools
|
allSchools = Set.mapMonotonic entityKey schools
|
||||||
@ -311,6 +315,8 @@ postAdminUserR uuid = do
|
|||||||
userAuthenticationForm = buttonForm' $ if
|
userAuthenticationForm = buttonForm' $ if
|
||||||
| userAuthentication == AuthLDAP -> [BtnAuthPWHash]
|
| userAuthentication == AuthLDAP -> [BtnAuthPWHash]
|
||||||
| otherwise -> [BtnAuthLDAP, BtnPasswordReset]
|
| otherwise -> [BtnAuthLDAP, BtnPasswordReset]
|
||||||
|
systemFunctionsForm' = funcForm systemFuncForm (fslI MsgUserSystemFunctions) False
|
||||||
|
where systemFuncForm func = apopt checkBoxField (fslI func) . Just $ systemFunctions func
|
||||||
let userRightsAction changes = do
|
let userRightsAction changes = do
|
||||||
let symDiff = (changes `Set.difference` functions) `Set.union` (functions `Set.difference` changes)
|
let symDiff = (changes `Set.difference` functions) `Set.union` (functions `Set.difference` changes)
|
||||||
updates = (allFunctions `setProduct` adminSchools) `Set.intersection` symDiff
|
updates = (allFunctions `setProduct` adminSchools) `Set.intersection` symDiff
|
||||||
@ -367,8 +373,24 @@ postAdminUserR uuid = do
|
|||||||
queueJob' $ JobSendPasswordReset uid
|
queueJob' $ JobSendPasswordReset uid
|
||||||
addMessageI Success MsgPasswordResetQueued
|
addMessageI Success MsgPasswordResetQueued
|
||||||
redirect $ AdminUserR uuid
|
redirect $ AdminUserR uuid
|
||||||
|
|
||||||
|
userSystemFunctionsAction newFuncs = do
|
||||||
|
let symmDiff = setFromFunc newFuncs `setSymmDiff` setFromFunc systemFunctions
|
||||||
|
if
|
||||||
|
| not $ Set.null symmDiff -> runDBJobs $ do
|
||||||
|
forM_ symmDiff $ \func -> if
|
||||||
|
| newFuncs func
|
||||||
|
-> void . insertUnique $ UserSystemFunction uid func
|
||||||
|
| otherwise
|
||||||
|
-> deleteBy $ UniqueUserSystemFunction uid func
|
||||||
|
queueDBJob . JobQueueNotification . NotificationUserSystemFunctionsUpdate uid $ setFromFunc systemFunctions
|
||||||
|
addMessageI Success MsgUserSystemFunctionsSaved
|
||||||
|
| otherwise
|
||||||
|
-> addMessageI Info MsgUserSystemFunctionsNotChanged
|
||||||
|
redirect $ AdminUserR uuid
|
||||||
((rightsResult, rightsFormWidget),rightsFormEnctype) <- runFormPost userRightsForm
|
((rightsResult, rightsFormWidget),rightsFormEnctype) <- runFormPost userRightsForm
|
||||||
((authResult, authFormWidget),authFormEnctype) <- runFormPost userAuthenticationForm
|
((authResult, authFormWidget),authFormEnctype) <- runFormPost userAuthenticationForm
|
||||||
|
((systemFunctionsResult, systemFunctionsWidget),systemFunctionsEnctype) <- runFormPost . identifyForm FIDUserSystemFunctions $ renderAForm FormStandard systemFunctionsForm'
|
||||||
let rightsForm = wrapForm rightsFormWidget def
|
let rightsForm = wrapForm rightsFormWidget def
|
||||||
{ formAction = Just . SomeRoute $ AdminUserR uuid
|
{ formAction = Just . SomeRoute $ AdminUserR uuid
|
||||||
, formEncoding = rightsFormEnctype
|
, formEncoding = rightsFormEnctype
|
||||||
@ -378,8 +400,13 @@ postAdminUserR uuid = do
|
|||||||
, formEncoding = authFormEnctype
|
, formEncoding = authFormEnctype
|
||||||
, formSubmit = FormNoSubmit
|
, formSubmit = FormNoSubmit
|
||||||
}
|
}
|
||||||
|
systemFunctionsForm = wrapForm systemFunctionsWidget def
|
||||||
|
{ formAction = Just . SomeRoute $ AdminUserR uuid
|
||||||
|
, formEncoding = systemFunctionsEnctype
|
||||||
|
}
|
||||||
formResult rightsResult userRightsAction
|
formResult rightsResult userRightsAction
|
||||||
formResult authResult userAuthenticationAction
|
formResult authResult userAuthenticationAction
|
||||||
|
formResult systemFunctionsResult userSystemFunctionsAction
|
||||||
let heading =
|
let heading =
|
||||||
[whamlet|_{MsgAdminUserHeadingFor} ^{nameEmailWidget userEmail userDisplayName userSurname}|]
|
[whamlet|_{MsgAdminUserHeadingFor} ^{nameEmailWidget userEmail userDisplayName userSurname}|]
|
||||||
-- Delete Button needed in data-delete
|
-- Delete Button needed in data-delete
|
||||||
|
|||||||
@ -113,6 +113,8 @@ determineNotificationCandidates = awaitForever $ \notif -> do
|
|||||||
E.&&. admin E.^. UserFunctionFunction E.==. E.val SchoolAdmin
|
E.&&. admin E.^. UserFunctionFunction E.==. E.val SchoolAdmin
|
||||||
return user
|
return user
|
||||||
withNotif . yieldMany . nub $ affectedUser <> affectedAdmins
|
withNotif . yieldMany . nub $ affectedUser <> affectedAdmins
|
||||||
|
NotificationUserSystemFunctionsUpdate{..}
|
||||||
|
-> withNotif $ selectSource [UserId ==. nUser] []
|
||||||
NotificationUserAuthModeUpdate{..}
|
NotificationUserAuthModeUpdate{..}
|
||||||
-> withNotif $ selectSource [UserId ==. nUser] []
|
-> withNotif $ selectSource [UserId ==. nUser] []
|
||||||
NotificationExamRegistrationActive{..}
|
NotificationExamRegistrationActive{..}
|
||||||
@ -295,6 +297,7 @@ classifyNotification NotificationSheetInactive{} = return NTShe
|
|||||||
classifyNotification NotificationCorrectionsAssigned{} = return NTCorrectionsAssigned
|
classifyNotification NotificationCorrectionsAssigned{} = return NTCorrectionsAssigned
|
||||||
classifyNotification NotificationCorrectionsNotDistributed{} = return NTCorrectionsNotDistributed
|
classifyNotification NotificationCorrectionsNotDistributed{} = return NTCorrectionsNotDistributed
|
||||||
classifyNotification NotificationUserRightsUpdate{} = return NTUserRightsUpdate
|
classifyNotification NotificationUserRightsUpdate{} = return NTUserRightsUpdate
|
||||||
|
classifyNotification NotificationUserSystemFunctionsUpdate{} = return NTUserRightsUpdate
|
||||||
classifyNotification NotificationUserAuthModeUpdate{} = return NTUserAuthModeUpdate
|
classifyNotification NotificationUserAuthModeUpdate{} = return NTUserAuthModeUpdate
|
||||||
classifyNotification NotificationExamRegistrationActive{} = return NTExamRegistrationActive
|
classifyNotification NotificationExamRegistrationActive{} = return NTExamRegistrationActive
|
||||||
classifyNotification NotificationExamRegistrationSoonInactive{} = return NTExamRegistrationSoonInactive
|
classifyNotification NotificationExamRegistrationSoonInactive{} = return NTExamRegistrationSoonInactive
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
module Jobs.Handler.SendNotification.UserRightsUpdate
|
module Jobs.Handler.SendNotification.UserRightsUpdate
|
||||||
( dispatchNotificationUserRightsUpdate
|
( dispatchNotificationUserRightsUpdate
|
||||||
|
, dispatchNotificationUserSystemFunctionsUpdate
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Import
|
import Import
|
||||||
@ -27,3 +28,16 @@ dispatchNotificationUserRightsUpdate nUser _originalRights jRecipient = userMai
|
|||||||
editNotifications <- mkEditNotifications jRecipient
|
editNotifications <- mkEditNotifications jRecipient
|
||||||
addHtmlMarkdownAlternatives ($(ihamletFile "templates/mail/userRightsUpdate.hamlet") :: HtmlUrlI18n (SomeMessage UniWorX) (Route UniWorX))
|
addHtmlMarkdownAlternatives ($(ihamletFile "templates/mail/userRightsUpdate.hamlet") :: HtmlUrlI18n (SomeMessage UniWorX) (Route UniWorX))
|
||||||
|
|
||||||
|
|
||||||
|
dispatchNotificationUserSystemFunctionsUpdate :: UserId -> Set SystemFunction -> UserId -> Handler ()
|
||||||
|
dispatchNotificationUserSystemFunctionsUpdate nUser _originalSystemFunctions jRecipient = userMailT jRecipient $ do
|
||||||
|
(User{..}, functions) <- liftHandler . runDB $ do
|
||||||
|
user <- getJust nUser
|
||||||
|
functions <- map (userSystemFunctionFunction . entityVal) <$> selectList [UserSystemFunctionUser ==. nUser] []
|
||||||
|
return (user, Set.fromList functions)
|
||||||
|
replaceMailHeader "Auto-Submitted" $ Just "auto-generated"
|
||||||
|
setSubjectI $ MsgMailSubjectUserSystemFunctionsUpdate userDisplayName
|
||||||
|
-- MsgRenderer mr <- getMailMsgRenderer
|
||||||
|
editNotifications <- mkEditNotifications jRecipient
|
||||||
|
addHtmlMarkdownAlternatives ($(ihamletFile "templates/mail/userSystemFunctionsUpdate.hamlet") :: HtmlUrlI18n (SomeMessage UniWorX) (Route UniWorX))
|
||||||
|
|
||||||
|
|||||||
@ -99,6 +99,7 @@ data Notification = NotificationSubmissionRated { nSubmission :: SubmissionId }
|
|||||||
| NotificationCorrectionsAssigned { nUser :: UserId, nSheet :: SheetId }
|
| NotificationCorrectionsAssigned { nUser :: UserId, nSheet :: SheetId }
|
||||||
| NotificationCorrectionsNotDistributed { nSheet :: SheetId }
|
| NotificationCorrectionsNotDistributed { nSheet :: SheetId }
|
||||||
| NotificationUserRightsUpdate { nUser :: UserId, nOriginalRights :: Set (SchoolFunction, SchoolShorthand) }
|
| NotificationUserRightsUpdate { nUser :: UserId, nOriginalRights :: Set (SchoolFunction, SchoolShorthand) }
|
||||||
|
| NotificationUserSystemFunctionsUpdate { nUser :: UserId, nOriginalSystemFunctions :: Set SystemFunction }
|
||||||
| NotificationUserAuthModeUpdate { nUser :: UserId, nOriginalAuthMode :: AuthenticationMode }
|
| NotificationUserAuthModeUpdate { nUser :: UserId, nOriginalAuthMode :: AuthenticationMode }
|
||||||
| NotificationExamRegistrationActive { nExam :: ExamId }
|
| NotificationExamRegistrationActive { nExam :: ExamId }
|
||||||
| NotificationExamRegistrationSoonInactive { nExam :: ExamId }
|
| NotificationExamRegistrationSoonInactive { nExam :: ExamId }
|
||||||
|
|||||||
@ -16,3 +16,4 @@ import Model.Types.School as Types
|
|||||||
import Model.Types.Allocation as Types
|
import Model.Types.Allocation as Types
|
||||||
import Model.Types.Languages as Types
|
import Model.Types.Languages as Types
|
||||||
import Model.Types.File as Types
|
import Model.Types.File as Types
|
||||||
|
import Model.Types.User as Types
|
||||||
|
|||||||
16
src/Model/Types/User.hs
Normal file
16
src/Model/Types/User.hs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
module Model.Types.User where
|
||||||
|
|
||||||
|
import Import.NoModel
|
||||||
|
import Model.Types.TH.PathPiece
|
||||||
|
|
||||||
|
|
||||||
|
data SystemFunction
|
||||||
|
= SystemExamOffice
|
||||||
|
| SystemFaculty
|
||||||
|
deriving (Eq, Ord, Read, Show, Enum, Bounded, Generic, Typeable)
|
||||||
|
deriving anyclass (Universe, Finite, Hashable, NFData)
|
||||||
|
|
||||||
|
nullaryPathPiece ''SystemFunction $ camelToPathPiece' 1
|
||||||
|
pathPieceJSON ''SystemFunction
|
||||||
|
pathPieceJSONKey ''SystemFunction
|
||||||
|
derivePersistFieldPathPiece ''SystemFunction
|
||||||
@ -483,6 +483,9 @@ setProduct (Set.toAscList -> as) (Set.toAscList -> bs) = Set.fromDistinctAscList
|
|||||||
setPartitionEithers :: (Ord a, Ord b) => Set (Either a b) -> (Set a, Set b)
|
setPartitionEithers :: (Ord a, Ord b) => Set (Either a b) -> (Set a, Set b)
|
||||||
setPartitionEithers = (,) <$> setMapMaybe (preview _Left) <*> setMapMaybe (preview _Right)
|
setPartitionEithers = (,) <$> setMapMaybe (preview _Left) <*> setMapMaybe (preview _Right)
|
||||||
|
|
||||||
|
setFromFunc :: (Finite k, Ord k) => (k -> Bool) -> Set k
|
||||||
|
setFromFunc = Set.fromList . flip filter universeF
|
||||||
|
|
||||||
----------
|
----------
|
||||||
-- Maps --
|
-- Maps --
|
||||||
----------
|
----------
|
||||||
|
|||||||
@ -215,6 +215,7 @@ data FormIdentifier
|
|||||||
| FIDDelete
|
| FIDDelete
|
||||||
| FIDCourseRegister
|
| FIDCourseRegister
|
||||||
| FIDuserRights
|
| FIDuserRights
|
||||||
|
| FIDUserSystemFunctions
|
||||||
| FIDcUserNote
|
| FIDcUserNote
|
||||||
| FIDcRegField
|
| FIDcRegField
|
||||||
| FIDcRegButton
|
| FIDcRegButton
|
||||||
|
|||||||
@ -4,6 +4,7 @@ $newline never
|
|||||||
<section>
|
<section>
|
||||||
<h3>
|
<h3>
|
||||||
_{MsgAdminUserRightsHeading}
|
_{MsgAdminUserRightsHeading}
|
||||||
|
^{systemFunctionsForm}
|
||||||
^{rightsForm}
|
^{rightsForm}
|
||||||
<section>
|
<section>
|
||||||
<h3>
|
<h3>
|
||||||
|
|||||||
21
templates/mail/userSystemFunctionsUpdate.hamlet
Normal file
21
templates/mail/userSystemFunctionsUpdate.hamlet
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
$newline never
|
||||||
|
\<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<style>
|
||||||
|
h1 {
|
||||||
|
font-size: 1.25em;
|
||||||
|
font-variant: small-caps;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
<body>
|
||||||
|
<h1>
|
||||||
|
_{SomeMessage $ MsgMailUserSystemFunctionsIntro userDisplayName userEmail}
|
||||||
|
<ul>
|
||||||
|
$forall function <- Set.toList functions
|
||||||
|
<li>_{SomeMessage function}
|
||||||
|
$if onull functions
|
||||||
|
<li>_{SomeMessage MsgMailUserSystemFunctionsNoFunctions}
|
||||||
|
|
||||||
|
^{ihamletSomeMessage editNotifications}
|
||||||
Reference in New Issue
Block a user