termField stub created, needs to be moved to common utils

This commit is contained in:
SJost 2017-10-06 11:22:43 +02:00
parent 1d8e10566e
commit fcec208936
5 changed files with 324 additions and 79 deletions

3
models
View File

@ -1,6 +1,7 @@
User
plugin Text
ident Text
matrikelnummer Text
UniqueAuthentication plugin ident
Term json
name TermIdentifier
@ -27,6 +28,8 @@ DegreeCourse json
Course json
name Text
shorthand Text
description Textarea
linkexternal Text
owner UserId
schoolId SchoolId
termId TermId -- TermId ist jetzt Text als Typ

View File

@ -245,6 +245,7 @@ instance YesodAuth UniWorX where
Nothing -> Authenticated <$> insert User
{ userPlugin = credsPlugin
, userIdent = credsIdent
, userMatrikelnummer = "DummyMatrikel"
}
-- You can add other plugins like Google Email, email or OAuth here

View File

@ -1,36 +1,64 @@
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
module Handler.Assist where
import Import
import qualified Data.Text as T
import Yesod.Form.Bootstrap3 (BootstrapFormLayout (..), renderBootstrap3)
-- import Text.Julius (RawJS (..))
data NewCourseForm = NewCourseForm
{ ncf_name :: Text
, ncf_short :: Text
, ncf_capacity :: Maybe Int
}
{ ncf_user :: UserId
, ncf_term :: TermIdentifier
, ncf_name :: Text
, ncf_short :: Text
, ncf_description :: Textarea
, ncf_homepage :: Maybe Text
, ncf_html :: Html
, ncf_capacity :: Maybe Int
}
-- Handler for Assistants
getShowCourseR :: CourseId -> Handler Html
getShowCourseR courseId = do
defaultLayout $ do
[whamlet|
TODO unfinished
|]
getNewCourseR :: Handler Html
getNewCourseR = do
(formWidget, formEnctype) <- generateFormPost newCourseForm
aid <- requireAuthId
(formWidget, formEnctype) <- generateFormPost $ newCourseForm aid
defaultLayout $ do
setTitle "Neuen Kurs anlegen"
[whamlet|
User: #{show aid}
|]
$(widgetFile "newcourse")
postNewCourseR :: Handler Html
postNewCourseR = do
((result, formWidget), formEnctype) <- runFormPost newCourseForm
aid <- requireAuthId
((result, formWidget), formEnctype) <- runFormPost $ newCourseForm aid
case result of
FormSuccess res -> do
FormSuccess res -> defaultLayout $ do
setMessage "Got something!"
redirect NewCourseR
_ -> redirect NewCourseR
$(widgetFile "newcourse")
FormMissing -> defaultLayout $ do
setMessage "Keine Daten erhalten."
$(widgetFile "newcourse")
FormFailure errorMsgs -> defaultLayout $ do
setMessage [shamlet| <span .error>Fehler:
<ul>
$forall errmsg <- errorMsgs
<li> #{errmsg}
|]
$(widgetFile "newcourse")
{-
defaultLayout $ do
@ -41,11 +69,20 @@ postNewCourseR = do
-}
-- TODO: Move elsewhere
termField :: Field (HandlerT UniWorX IO) TermIdentifier
termField = checkMMap (return . termFromText) termToText textField
newCourseForm :: Form NewCourseForm
newCourseForm = renderBootstrap3 BootstrapBasicForm $ NewCourseForm
<$> areq textField (set "Name des Kurses") Nothing
newCourseForm :: UserId -> Form NewCourseForm
newCourseForm uid = renderBootstrap3 BootstrapBasicForm $ NewCourseForm
<$> pure uid
<*> areq termField (set "Semester") Nothing
-- <*> areq textField (set "Semester") Nothing
<*> areq textField (set "Name des Kurses") Nothing
<*> areq textField (set "Kurs Kürzel (3-4 Zeichen)") Nothing
<*> areq textareaField (set "Beschreibung des Kurses") Nothing
<*> aopt urlField (set "Externe Kurshomepage") Nothing
<*> areq htmlField (set "Beschreibung in HTML") Nothing
<*> aopt intField (set "Maximale Teilnehmer") Nothing
-- Add attributes like the placeholder and CSS classes.
where set txt = FieldSettings

View File

@ -92,3 +92,9 @@ instance ToJSON TermIdentifier where
instance FromJSON TermIdentifier where
parseJSON = withText "Term" $ either (fail . Text.unpack) return . termFromText
{- Must be defined in a later module:
termField :: Field (HandlerT UniWorX IO) TermIdentifier
termField = checkMMap (return . termFromText) termToText textField
-- TODO: this is too simple and inconvenient, use selector and year picker
-}

View File

@ -3,6 +3,18 @@
{
"selected_items":
[
[
"get",
"getShowCourseR"
],
[
"err",
"errorMsgs"
],
[
"set",
"setMessage"
]
]
},
"buffers":
@ -11,7 +23,7 @@
"file": "src/Application.hs",
"settings":
{
"buffer_size": 7191,
"buffer_size": 7271,
"line_ending": "Unix"
}
},
@ -19,7 +31,8 @@
"file": "src/Foundation.hs",
"settings":
{
"buffer_size": 10198,
"buffer_size": 11626,
"encoding": "UTF-8",
"line_ending": "Unix"
}
},
@ -35,7 +48,19 @@
"file": "src/Model.hs",
"settings":
{
"buffer_size": 781,
"buffer_size": 886,
"line_ending": "Unix"
}
},
{
"contents": "{-# LANGUAGE RecordWildCards #-}\n{-# LANGUAGE PatternGuards #-}\n{-# LANGUAGE TemplateHaskell #-}\n{-# LANGUAGE NoImplicitPrelude #-}\n{-# LANGUAGE OverloadedStrings #-}\n{-# LANGUAGE DeriveGeneric, DeriveDataTypeable #-}\nmodule Model.Types where\n\nimport ClassyPrelude\n\nimport Database.Persist.TH\nimport Database.Persist.Class\nimport Database.Persist.Sql\n\nimport Web.HttpApiData\n\nimport Data.Text (Text)\nimport qualified Data.Text as Text\n\nimport Text.Read (readMaybe)\n\n-- import Data.CaseInsensitive (CI)\nimport qualified Data.CaseInsensitive as CI\n\nimport Yesod.Core.Dispatch (PathPiece(..))\nimport Data.Aeson (FromJSON(..), ToJSON(..), withText, Value(..))\n\nimport GHC.Generics (Generic)\nimport Data.Typeable (Typeable)\n\n\ndata SheetType = Regular | Bonus | Extra \n deriving (Show, Read, Eq, Ord, Enum, Bounded) \nderivePersistField \"SheetType\"\n\ndata ExamStatus = Attended | NoShow | Voided\n deriving (Show, Read, Eq, Ord, Enum, Bounded) \nderivePersistField \"ExamStatus\"\n\n\ndata Season = Summer | Winter\n deriving (Show, Read, Eq, Ord, Enum, Bounded, Generic, Typeable)\n\nseasonToChar :: Season -> Char\nseasonToChar Summer = 'S'\nseasonToChar Winter = 'W'\n\nseasonFromChar :: Char -> Either Text Season\nseasonFromChar c\n | c ~= 'S' = Right Summer\n | c ~= 'W' = Right Winter\n | otherwise = Left $ \"Invalid season character: \" <> tshow c <> \"\"\n where\n (~=) = (==) `on` CI.mk\n\ndata TermIdentifier = TermIdentifier\n { year :: Integer -- ^ Using 'Integer' to model years is consistent with 'Data.Time.Calendar'\n , season :: Season\n } deriving (Show, Read, Eq, Ord, Generic, Typeable)\n\ntermToText :: TermIdentifier -> Text\ntermToText TermIdentifier{..} = Text.pack $ seasonToChar season : show year\n\ntermFromText :: Text -> Either Text TermIdentifier\ntermFromText t\n | (s:ys) <- Text.unpack t\n , Just year <- readMaybe ys\n , Right season <- seasonFromChar s\n = Right TermIdentifier{..}\n | otherwise = Left $ \"Invalid TermIdentifier: “\" <> t <> \"”\"\n\ninstance PersistField TermIdentifier where\n toPersistValue = PersistText . termToText\n fromPersistValue (PersistText t) = termFromText t\n fromPersistValue x = Left $ \"Expected TermIdentifier, received: \" <> tshow x\n\ninstance PersistFieldSql TermIdentifier where\n sqlType _ = SqlString\n\ninstance ToHttpApiData TermIdentifier where\n toUrlPiece = termToText\n\ninstance FromHttpApiData TermIdentifier where\n parseUrlPiece = termFromText\n\ninstance PathPiece TermIdentifier where\n fromPathPiece = either (const Nothing) Just . termFromText\n toPathPiece = termToText\n\ninstance ToJSON TermIdentifier where\n toJSON = String . termToText\n\ninstance FromJSON TermIdentifier where\n parseJSON = withText \"Term\" $ either (fail . Text.unpack) return . termFromText\n\ninstance Class Data where\n func = \n",
"file": "src/Model/Types.hs",
"file_size": 2724,
"file_write_time": 131516115030281923,
"settings":
{
"buffer_size": 2753,
"encoding": "UTF-8",
"line_ending": "Unix"
}
},
@ -47,19 +72,11 @@
"line_ending": "Unix"
}
},
{
"file": "src/Handler/Comment.hs",
"settings":
{
"buffer_size": 661,
"line_ending": "Unix"
}
},
{
"file": "src/Handler/Common.hs",
"settings":
{
"buffer_size": 777,
"buffer_size": 781,
"line_ending": "Unix"
}
},
@ -71,6 +88,24 @@
"line_ending": "Unix"
}
},
{
"file": "src/Handler/Assist.hs",
"settings":
{
"buffer_size": 2858,
"encoding": "UTF-8",
"line_ending": "Unix"
}
},
{
"file": "templates/newcourse.hamlet",
"settings":
{
"buffer_size": 606,
"encoding": "UTF-8",
"line_ending": "Unix"
}
},
{
"file": "src/Handler/Profile.hs",
"settings":
@ -78,6 +113,23 @@
"buffer_size": 411,
"line_ending": "Unix"
}
},
{
"file": "models",
"settings":
{
"buffer_size": 4388,
"encoding": "UTF-8",
"line_ending": "Unix"
}
},
{
"file": "stack.yaml",
"settings":
{
"buffer_size": 2233,
"line_ending": "Unix"
}
}
],
"build_system": "",
@ -87,7 +139,7 @@
"build_varint": "",
"command_palette":
{
"height": 523.0,
"height": 121.0,
"last_filter": "",
"selected_items":
[
@ -96,9 +148,11 @@
},
"console":
{
"height": 0.0,
"height": 192.0,
"history":
[
"help",
"ll"
]
},
"distraction_free":
@ -112,16 +166,18 @@
},
"file_history":
[
"/home/jost/programming/Haskell/Yesod/uniworx/src/Handler/Comment.hs"
],
"find":
{
"height": 31.0
"height": 52.0
},
"find_in_files":
{
"height": 0.0,
"height": 128.0,
"where_history":
[
""
]
},
"find_state":
@ -129,6 +185,12 @@
"case_sensitive": false,
"find_history":
[
"Html",
"setMessage",
"Text",
"Integer",
"matrikel",
"AuthId",
"FileInfo",
"fileInfo"
],
@ -148,7 +210,7 @@
"groups":
[
{
"selected": 7,
"selected": 8,
"sheets":
[
{
@ -157,7 +219,7 @@
"semi_transient": false,
"settings":
{
"buffer_size": 7191,
"buffer_size": 7271,
"regions":
{
},
@ -178,7 +240,7 @@
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 8,
"stack_index": 12,
"type": "text"
},
{
@ -187,15 +249,15 @@
"semi_transient": false,
"settings":
{
"buffer_size": 10198,
"buffer_size": 11626,
"regions":
{
},
"selection":
[
[
0,
0
9330,
9330
]
],
"settings":
@ -205,10 +267,10 @@
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 0.0,
"translation.y": 5125.0,
"zoom_level": 1.0
},
"stack_index": 7,
"stack_index": 6,
"type": "text"
},
{
@ -236,7 +298,7 @@
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 6,
"stack_index": 5,
"type": "text"
},
{
@ -245,7 +307,7 @@
"semi_transient": false,
"settings":
{
"buffer_size": 781,
"buffer_size": 886,
"regions":
{
},
@ -264,11 +326,41 @@
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 5,
"stack_index": 2,
"type": "text"
},
{
"buffer": 4,
"file": "src/Model/Types.hs",
"semi_transient": false,
"settings":
{
"buffer_size": 2753,
"regions":
{
},
"selection":
[
[
2726,
2731
]
],
"settings":
{
"syntax": "Packages/Haskell/Haskell.sublime-syntax",
"tab_size": 2,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 1380.0,
"zoom_level": 1.0
},
"stack_index": 1,
"type": "text"
},
{
"buffer": 5,
"file": "src/Settings.hs",
"semi_transient": false,
"settings":
@ -294,35 +386,7 @@
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 4,
"type": "text"
},
{
"buffer": 5,
"file": "src/Handler/Comment.hs",
"semi_transient": false,
"settings":
{
"buffer_size": 661,
"regions":
{
},
"selection":
[
[
0,
0
]
],
"settings":
{
"syntax": "Packages/Haskell/Haskell.sublime-syntax"
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 3,
"stack_index": 11,
"type": "text"
},
{
@ -331,7 +395,7 @@
"semi_transient": false,
"settings":
{
"buffer_size": 777,
"buffer_size": 781,
"regions":
{
},
@ -350,7 +414,7 @@
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 2,
"stack_index": 10,
"type": "text"
},
{
@ -366,8 +430,8 @@
"selection":
[
[
818,
818
404,
404
]
],
"settings":
@ -380,11 +444,71 @@
"translation.y": 138.0,
"zoom_level": 1.0
},
"stack_index": 0,
"stack_index": 7,
"type": "text"
},
{
"buffer": 8,
"file": "src/Handler/Assist.hs",
"semi_transient": false,
"settings":
{
"buffer_size": 2858,
"regions":
{
},
"selection":
[
[
454,
454
]
],
"settings":
{
"syntax": "Packages/Haskell/Haskell.sublime-syntax",
"tab_size": 4,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 0,
"type": "text"
},
{
"buffer": 9,
"file": "templates/newcourse.hamlet",
"semi_transient": false,
"settings":
{
"buffer_size": 606,
"regions":
{
},
"selection":
[
[
0,
0
]
],
"settings":
{
"syntax": "Packages/Text/Plain text.tmLanguage",
"tab_size": 4,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 4,
"type": "text"
},
{
"buffer": 10,
"file": "src/Handler/Profile.hs",
"semi_transient": false,
"settings":
@ -396,8 +520,8 @@
"selection":
[
[
411,
411
213,
213
]
],
"settings":
@ -408,7 +532,65 @@
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 1,
"stack_index": 8,
"type": "text"
},
{
"buffer": 11,
"file": "models",
"semi_transient": false,
"settings":
{
"buffer_size": 4388,
"regions":
{
},
"selection":
[
[
747,
747
]
],
"settings":
{
"syntax": "Packages/Text/Plain text.tmLanguage",
"tab_size": 2,
"translate_tabs_to_spaces": true
},
"translation.x": 0.0,
"translation.y": 138.0,
"zoom_level": 1.0
},
"stack_index": 3,
"type": "text"
},
{
"buffer": 12,
"file": "stack.yaml",
"semi_transient": false,
"settings":
{
"buffer_size": 2233,
"regions":
{
},
"selection":
[
[
663,
663
]
],
"settings":
{
"syntax": "Packages/YAML/YAML.sublime-syntax"
},
"translation.x": 0.0,
"translation.y": 0.0,
"zoom_level": 1.0
},
"stack_index": 9,
"type": "text"
}
]
@ -416,7 +598,7 @@
],
"incremental_find":
{
"height": 31.0
"height": 33.0
},
"input":
{
@ -453,7 +635,7 @@
"project": "uniworx.sublime-project",
"replace":
{
"height": 58.0
"height": 61.0
},
"save_all_on_build": true,
"select_file":
@ -464,7 +646,23 @@
[
[
"",
"~/programming/Haskell/Yesod/uniworx/src/Handler/Home.hs"
"~/programming/Haskell/Yesod/uniworx/src/Handler/Assist.hs"
],
[
"mo",
"~/programming/Haskell/Yesod/uniworx/models"
],
[
"a",
"~/programming/Haskell/Yesod/uniworx/src/Handler/Assist.hs"
],
[
"f",
"~/programming/Haskell/Yesod/uniworx/src/Foundation.hs"
],
[
"m",
"~/programming/Haskell/Yesod/uniworx/models"
]
],
"width": 0.0