module Handler.School where import Import import Handler.Utils import qualified Database.Esqueleto as E import qualified Data.Set as Set import qualified Data.CaseInsensitive as CI import qualified Data.Text as Text getSchoolListR :: Handler Html getSchoolListR = do let schoolLink :: SchoolId -> SomeRoute UniWorX schoolLink ssh = SomeRoute $ SchoolR ssh SchoolEditR dbtSQLQuery :: E.SqlExpr (Entity School) -> E.SqlQuery _ dbtSQLQuery = return dbtProj :: DBRow _ -> DB (DBRow (Entity School)) 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 , sfOrgUnits :: Set (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 (textField & cfStrip & cfCI) (fslI MsgSchoolShort) <*> areq (textField & cfStrip & cfCI) (fslI MsgSchoolName) (sfName <$> template) <*> (Set.fromList . mapMaybe (fmap CI.mk . assertM' (not . Text.null) . Text.strip . CI.original) <$> massInputListA (ciField & addDatalist ldapOrgs) (const "") MsgSchoolLdapOrganisationMissing (const Nothing) ("ldap-organisations" :: Text) (fslI MsgSchoolLdapOrganisations & setTooltip MsgSchoolLdapOrganisationsTip) False (Set.toList . sfOrgUnits <$> template)) where ldapOrgs :: HandlerFor UniWorX (OptionList (CI Text)) ldapOrgs = fmap (mkOptionList . map (\t -> Option (CI.original t) t (CI.original t)) . Set.toAscList) . runDB $ setOf (folded . _entityVal . _schoolLdapOrgUnit) <$> selectList [] [] schoolToForm :: SchoolId -> DB (Form SchoolForm) schoolToForm ssh = do School{..} <- get404 ssh ldapFrags <- selectList [SchoolLdapSchool ==. Just ssh] [] return . mkSchoolForm (Just ssh) $ Just SchoolForm { sfShorthand = schoolShorthand , sfName = schoolName , sfOrgUnits = setOf (folded . _entityVal . _schoolLdapOrgUnit) ldapFrags } getSchoolEditR, postSchoolEditR :: SchoolId -> Handler Html getSchoolEditR = postSchoolEditR postSchoolEditR ssh = do sForm <- runDB $ schoolToForm ssh ((sfResult, sfView), sfEnctype) <- runFormPost sForm formResult sfResult $ \SchoolForm{..} -> do runDB $ do update ssh [ SchoolName =. sfName ] forM_ sfOrgUnits $ \schoolLdapOrgUnit -> void $ upsert SchoolLdap { schoolLdapSchool = Just ssh , .. } [ SchoolLdapSchool =. Just ssh ] deleteWhere [SchoolLdapSchool ==. Just ssh, SchoolLdapOrgUnit /<-. Set.toList sfOrgUnits] addMessageI Success $ MsgSchoolUpdated ssh redirect $ SchoolR ssh SchoolEditR let sfView' = wrapForm sfView FormSettings { formMethod = POST , formAction = Just . SomeRoute $ SchoolR ssh SchoolEditR , 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 uid <- requireAuthId ((sfResult, sfView), sfEnctype) <- runFormPost $ mkSchoolForm Nothing Nothing formResult sfResult $ \SchoolForm{..} -> do let ssh = SchoolKey sfShorthand insertOkay <- runDB $ do didInsert <- is _Just <$> insertUnique School { schoolShorthand = sfShorthand , schoolName = sfName } when didInsert $ do insert_ UserFunction { userFunctionUser = uid , userFunctionSchool = ssh , userFunctionFunction = SchoolAdmin } forM_ sfOrgUnits $ \schoolLdapOrgUnit -> void $ upsert SchoolLdap { schoolLdapSchool = Just ssh , .. } [ SchoolLdapSchool =. Just ssh ] return didInsert if | insertOkay -> do addMessageI Success $ MsgSchoolCreated ssh redirect $ SchoolR ssh SchoolEditR | 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'