Implemented parsing and generation of entity-list field render function. (#84)

This commit is contained in:
Matija Sosic 2020-02-03 16:16:45 +01:00 committed by GitHub
parent c695f30704
commit f955fa6a8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 284 additions and 75 deletions

View File

@ -49,6 +49,14 @@ export class {= listName =} extends React.Component {
this.setState({ {= entityBeingEditedStateVar =}: null }) this.setState({ {= entityBeingEditedStateVar =}: null })
} }
{=! Render "render" functions for each field, if provided =}
{=# listFields =}
{=# render =}
{= renderFnName =} =
{=& render =}
{=/ render =}
{=/ listFields =}
render() { render() {
const {= entityLowerName =}ListToShow = this.props.filter ? const {= entityLowerName =}ListToShow = this.props.filter ?
{=! TODO(matija): duplication, we could extract entityLowerName_List =} {=! TODO(matija): duplication, we could extract entityLowerName_List =}
@ -104,7 +112,12 @@ export class {= listName =} extends React.Component {
)} )}
/> />
) : ( ) : (
{=# render =}
this.{= renderFnName =}({= entityLowerName =})
{=/ render =}
{=^ render =}
{= entityLowerName =}.{= name =} {= entityLowerName =}.{= name =}
{=/ render =}
)} )}
</TableCell> </TableCell>
</ClickAwayListener> </ClickAwayListener>

View File

@ -68,5 +68,18 @@ entity-form<Task> NewTaskForm {
// Entity list definition. // Entity list definition.
entity-list<Task> TaskList { entity-list<Task> TaskList {
// Options TBD, not supported for now. fields: {
description: {
// The contract for render is: user must provide a function that:
// - receives a task as an input
// - returns a React Node or something that can be rendered by JSX
// - does not depend on any outer context
render: {=js
(task) => {
if (task.isDone) return (<s>{task.description}</s>)
return task.description
}
js=}
}
}
} }

View File

@ -105,10 +105,12 @@ entity-list<Task> TaskList {
// - receives a task as an input // - receives a task as an input
// - returns a React Node or something that can be rendered by JSX // - returns a React Node or something that can be rendered by JSX
// - does not depend on any outer context // - does not depend on any outer context
render: (task) => { render: {=js
if (task.isDone) return (<s>task.description</s>) (task) => {
if (task.isDone) return (<s>{task.description}</s>)
return task.description return task.description
} }
js=}
} }
} }
} }

View File

@ -9,14 +9,18 @@ import Data.Maybe (fromJust)
import Path ((</>), reldir, relfile, parseRelFile) import Path ((</>), reldir, relfile, parseRelFile)
import qualified Path.Aliases as Path import qualified Path.Aliases as Path
import qualified Util as U
import qualified Wasp import qualified Wasp
import Wasp (Wasp) import Wasp (Wasp)
import qualified Wasp.EntityList as WEL import qualified Wasp.EntityList as WEL
import qualified Wasp.JsCode
import qualified Generator.FileDraft as FD import qualified Generator.FileDraft as FD
import qualified Generator.Entity.Common as EC import qualified Generator.Entity.Common as EC
import qualified Generator.Common as Common import qualified Generator.Common as Common
data EntityListTemplateData = EntityListTemplateData data EntityListTemplateData = EntityListTemplateData
{ _listName :: !String { _listName :: !String
, _entityName :: !String , _entityName :: !String
@ -40,6 +44,8 @@ instance ToJSON EntityListTemplateData where
data ListFieldTemplateData = ListFieldTemplateData data ListFieldTemplateData = ListFieldTemplateData
{ _fieldName :: !String { _fieldName :: !String
, _fieldType :: !Wasp.EntityFieldType , _fieldType :: !Wasp.EntityFieldType
, _fieldRender :: Maybe Wasp.JsCode.JsCode
, _fieldRenderFnName :: String
} }
instance ToJSON ListFieldTemplateData where instance ToJSON ListFieldTemplateData where
@ -47,6 +53,8 @@ instance ToJSON ListFieldTemplateData where
object object
[ "name" .= _fieldName f [ "name" .= _fieldName f
, "type" .= _fieldType f , "type" .= _fieldType f
, "render" .= _fieldRender f
, "renderFnName" .= _fieldRenderFnName f
] ]
createEntityListTemplateData :: Wasp.Entity -> WEL.EntityList -> EntityListTemplateData createEntityListTemplateData :: Wasp.Entity -> WEL.EntityList -> EntityListTemplateData
@ -58,17 +66,26 @@ createEntityListTemplateData entity entityList =
, _entityName = Wasp.entityName entity , _entityName = Wasp.entityName entity
, _entityClassName = EC.getEntityClassName entity , _entityClassName = EC.getEntityClassName entity
, _entityLowerName = EC.getEntityLowerName entity , _entityLowerName = EC.getEntityLowerName entity
, _listFields = map (createListFieldTD entityList) $ Wasp.entityFields entity , _listFields = map (createListFieldTD entity entityList) $ Wasp.entityFields entity
, _entityBeingEditedStateVar = entityLowerName ++ "BeingEdited" , _entityBeingEditedStateVar = entityLowerName ++ "BeingEdited"
} }
where where
entityLowerName = EC.getEntityLowerName entity entityLowerName = EC.getEntityLowerName entity
createListFieldTD :: WEL.EntityList -> Wasp.EntityField -> ListFieldTemplateData createListFieldTD :: Wasp.Entity -> WEL.EntityList -> Wasp.EntityField -> ListFieldTemplateData
createListFieldTD _ entityField = ListFieldTemplateData createListFieldTD entity entityList entityField = ListFieldTemplateData
{ _fieldName = Wasp.entityFieldName entityField { _fieldName = Wasp.entityFieldName entityField
, _fieldType = Wasp.entityFieldType entityField , _fieldType = Wasp.entityFieldType entityField
, _fieldRender = listFieldConfig >>= WEL._fieldRender
, _fieldRenderFnName = "render" ++ entityUpper ++ entityFieldUpper
} }
where
-- Configuration of a form field within entity-list, if there is any.
listFieldConfig :: Maybe WEL.Field
listFieldConfig = WEL.getConfigForField entityList entityField
entityUpper = U.toUpperFirst $ Wasp.entityName entity
entityFieldUpper = U.toUpperFirst $ Wasp.entityFieldName entityField
generateEntityList :: Wasp -> WEL.EntityList -> FD.FileDraft generateEntityList :: Wasp -> WEL.EntityList -> FD.FileDraft
generateEntityList wasp entityList = generateEntityList wasp entityList =

View File

@ -12,8 +12,8 @@ import Lexer
import Parser.App (app) import Parser.App (app)
import Parser.Page (page) import Parser.Page (page)
import Parser.Entity (entity) import Parser.Entity (entity)
import Parser.EntityForm (entityForm) import Parser.Entity.EntityForm (entityForm)
import Parser.EntityList (entityList) import Parser.Entity.EntityList (entityList)
import Parser.JsImport (jsImport) import Parser.JsImport (jsImport)
import Parser.Common (runWaspParser) import Parser.Common (runWaspParser)

View File

@ -12,6 +12,7 @@ import qualified Path.Aliases as Path
import qualified Lexer as L import qualified Lexer as L
-- | Runs given wasp parser on a specified input. -- | Runs given wasp parser on a specified input.
runWaspParser :: Parser a -> String -> Either ParseError a runWaspParser :: Parser a -> String -> Either ParseError a
runWaspParser waspParser input = parse waspParser sourceName input runWaspParser waspParser input = parse waspParser sourceName input

View File

@ -0,0 +1,39 @@
module Parser.Entity.Common
( waspPropertyEntityFields
) where
import Text.Parsec.String (Parser)
import qualified Lexer as L
import Parser.Common as P
-- A function that takes an entity field name (e.g. "description) and a list of parsed field
-- options, and then creates a final Wasp AST record from it (fieldConfig).
type CreateFieldConfig fieldOption fieldConfig = (String, [fieldOption]) -> fieldConfig
-- | Parses configuration of fields within a wasp entity component (e.g. entity-form
-- or entity-list). Parses the following format:
--
-- fields: { FIELD_NAME: {...}, FIELD_NAME: {...}, ... }
--
-- At least one field must be specified.
waspPropertyEntityFields
:: Parser fo -- ^ Parser of a single field option.
-> CreateFieldConfig fo fc -- ^ Function that creates a record with all parsed field options.
-> Parser [fc] -- ^ Field configs, a list of record with all the field options.
waspPropertyEntityFields fieldOptionP createFieldConfig = P.waspPropertyClosure "fields" $
L.commaSep1 $ waspPropertyEntityField fieldOptionP createFieldConfig
-- | Parses configuration of a specific field within a wasp entity component (e.g. entity-form
-- or entity-list). Parses the following format:
--
-- FIELD_NAME: { option1, option2 }
--
-- At least one option must be present.
waspPropertyEntityField
:: Parser fo -- ^ Parser of a single field option.
-> CreateFieldConfig fo fc -- ^ Function that creates a record with all parsed field options.
-> Parser fc -- ^ Field config, a record with all the field options.
waspPropertyEntityField fieldOptionP createFieldConfig =
(P.waspIdentifierClosure $ L.commaSep1 fieldOptionP) >>= (return . createFieldConfig)

View File

@ -1,4 +1,4 @@
module Parser.EntityForm module Parser.Entity.EntityForm
( entityForm ( entityForm
-- For testing -- For testing
@ -11,10 +11,11 @@ module Parser.EntityForm
import Text.Parsec (choice) import Text.Parsec (choice)
import Text.Parsec.String (Parser) import Text.Parsec.String (Parser)
import qualified Wasp.EntityForm as EF import qualified Wasp.EntityForm as WEF
import Wasp.EntityForm (EntityForm) import Wasp.EntityForm (EntityForm)
import qualified Parser.Common as P import qualified Parser.Common as P
import qualified Parser.Entity.Common as PE
import qualified Util as U import qualified Util as U
import qualified Lexer as L import qualified Lexer as L
@ -27,16 +28,16 @@ entityForm = do
(entityName, formName, options) <- (entityName, formName, options) <-
P.waspElementLinkedToEntity L.reservedNameEntityForm entityFormOptions P.waspElementLinkedToEntity L.reservedNameEntityForm entityFormOptions
return EF.EntityForm return WEF.EntityForm
{ EF._name = formName { WEF._name = formName
, EF._entityName = entityName , WEF._entityName = entityName
, EF._submit = maybeGetSubmitConfig options , WEF._submit = maybeGetSubmitConfig options
, EF._fields = getFieldsConfig options , WEF._fields = getFieldsConfig options
} }
data EntityFormOption data EntityFormOption
= EfoSubmit EF.Submit = EfoSubmit WEF.Submit
| EfoFields [EF.Field] | EfoFields [WEF.Field]
deriving (Show, Eq) deriving (Show, Eq)
entityFormOptions :: Parser [EntityFormOption] entityFormOptions :: Parser [EntityFormOption]
@ -50,25 +51,25 @@ entityFormOption = choice
-- * Submit -- * Submit
maybeGetSubmitConfig :: [EntityFormOption] -> Maybe EF.Submit maybeGetSubmitConfig :: [EntityFormOption] -> Maybe WEF.Submit
maybeGetSubmitConfig options = U.headSafe [s | EfoSubmit s <- options] maybeGetSubmitConfig options = U.headSafe [s | EfoSubmit s <- options]
entityFormOptionSubmit :: Parser EntityFormOption entityFormOptionSubmit :: Parser EntityFormOption
entityFormOptionSubmit = EfoSubmit <$> (P.waspPropertyClosure "submit" submitConfig) entityFormOptionSubmit = EfoSubmit <$> (P.waspPropertyClosure "submit" submitConfig)
submitConfig :: Parser EF.Submit submitConfig :: Parser WEF.Submit
submitConfig = do submitConfig = do
-- TODO(matija): this pattern of "having at least 1 property in closure" could be further -- TODO(matija): this pattern of "having at least 1 property in closure" could be further
-- extracted to e.g. "waspClosureOptions" - but again sometimes it is ok not to have any props, -- extracted to e.g. "waspClosureOptions" - but again sometimes it is ok not to have any props,
-- e.g. EntityForm. Maybe then "waspClosureOptions1" and "waspClosureOptions"? -- e.g. EntityForm. Maybe then "waspClosureOptions1" and "waspClosureOptions"?
options <- L.commaSep1 submitOption options <- L.commaSep1 submitOption
return EF.Submit return WEF.Submit
{ EF._onEnter = maybeGetSoOnEnter options { WEF._onEnter = maybeGetSoOnEnter options
, EF._submitButton = maybeGetSoSubmitButton options , WEF._submitButton = maybeGetSoSubmitButton options
} }
data SubmitOption = SoOnEnter Bool | SoSubmitButton EF.SubmitButton deriving (Show, Eq) data SubmitOption = SoOnEnter Bool | SoSubmitButton WEF.SubmitButton deriving (Show, Eq)
submitOption :: Parser SubmitOption submitOption :: Parser SubmitOption
submitOption = choice [submitOptionOnEnter, submitOptionSubmitButton] submitOption = choice [submitOptionOnEnter, submitOptionSubmitButton]
@ -84,15 +85,15 @@ maybeGetSoOnEnter options = U.headSafe [b | SoOnEnter b <- options]
submitOptionSubmitButton :: Parser SubmitOption submitOptionSubmitButton :: Parser SubmitOption
submitOptionSubmitButton = SoSubmitButton <$> P.waspPropertyClosure "button" submitButtonConfig submitOptionSubmitButton = SoSubmitButton <$> P.waspPropertyClosure "button" submitButtonConfig
maybeGetSoSubmitButton :: [SubmitOption] -> Maybe EF.SubmitButton maybeGetSoSubmitButton :: [SubmitOption] -> Maybe WEF.SubmitButton
maybeGetSoSubmitButton options = U.headSafe [sb | SoSubmitButton sb <- options] maybeGetSoSubmitButton options = U.headSafe [sb | SoSubmitButton sb <- options]
submitButtonConfig :: Parser EF.SubmitButton submitButtonConfig :: Parser WEF.SubmitButton
submitButtonConfig = do submitButtonConfig = do
options <- L.commaSep1 submitButtonOption options <- L.commaSep1 submitButtonOption
return EF.SubmitButton return WEF.SubmitButton
{ EF._submitButtonShow = maybeGetSboShow options { WEF._submitButtonShow = maybeGetSboShow options
} }
data SubmitButtonOption = SboShow Bool deriving (Show, Eq) data SubmitButtonOption = SboShow Bool deriving (Show, Eq)
@ -108,28 +109,24 @@ maybeGetSboShow options = U.headSafe [b | SboShow b <- options]
-- * Fields -- * Fields
getFieldsConfig :: [EntityFormOption] -> [EF.Field] getFieldsConfig :: [EntityFormOption] -> [WEF.Field]
getFieldsConfig options = case [fs | EfoFields fs <- options] of getFieldsConfig options = case [fs | EfoFields fs <- options] of
[] -> [] [] -> []
ls -> head ls ls -> head ls
entityFormOptionFields :: Parser EntityFormOption entityFormOptionFields :: Parser EntityFormOption
entityFormOptionFields = EfoFields <$> (P.waspPropertyClosure "fields" $ L.commaSep1 field) entityFormOptionFields = EfoFields <$> PE.waspPropertyEntityFields fieldOption createFieldConfig
-- | Parses 'FIELD_NAME: { ... }.' createFieldConfig :: (String, [FieldOption]) -> WEF.Field
field :: Parser EF.Field createFieldConfig (fieldName, options) = WEF.Field
field = do { WEF._fieldName = fieldName
(fieldName, options) <- P.waspIdentifierClosure $ L.commaSep1 fieldOption , WEF._fieldShow = maybeGetFieldOptionShow options
, WEF._fieldDefaultValue = maybeGetFieldOptionDefaultValue options
return EF.Field
{ EF._fieldName = fieldName
, EF._fieldShow = maybeGetFieldOptionShow options
, EF._fieldDefaultValue = maybeGetFieldOptionDefaultValue options
} }
data FieldOption data FieldOption
= FieldOptionShow Bool = FieldOptionShow Bool
| FieldOptionDefaultValue EF.DefaultValue | FieldOptionDefaultValue WEF.DefaultValue
deriving (Show, Eq) deriving (Show, Eq)
-- | Parses a single field option, e.g. "show" or "defaultValue". -- | Parses a single field option, e.g. "show" or "defaultValue".
@ -139,14 +136,14 @@ fieldOption = choice
, FieldOptionDefaultValue <$> defaultValue , FieldOptionDefaultValue <$> defaultValue
] ]
defaultValue :: Parser EF.DefaultValue defaultValue :: Parser WEF.DefaultValue
defaultValue = P.waspProperty "defaultValue" $ choice defaultValue = P.waspProperty "defaultValue" $ choice
[ EF.DefaultValueString <$> L.stringLiteral [ WEF.DefaultValueString <$> L.stringLiteral
, EF.DefaultValueBool <$> L.bool , WEF.DefaultValueBool <$> L.bool
] ]
maybeGetFieldOptionShow :: [FieldOption] -> Maybe Bool maybeGetFieldOptionShow :: [FieldOption] -> Maybe Bool
maybeGetFieldOptionShow options = U.headSafe [b | FieldOptionShow b <- options] maybeGetFieldOptionShow options = U.headSafe [b | FieldOptionShow b <- options]
maybeGetFieldOptionDefaultValue :: [FieldOption] -> Maybe EF.DefaultValue maybeGetFieldOptionDefaultValue :: [FieldOption] -> Maybe WEF.DefaultValue
maybeGetFieldOptionDefaultValue options = U.headSafe [dv | FieldOptionDefaultValue dv <- options] maybeGetFieldOptionDefaultValue options = U.headSafe [dv | FieldOptionDefaultValue dv <- options]

View File

@ -0,0 +1,75 @@
module Parser.Entity.EntityList
( entityList
) where
import Text.Parsec (choice)
import Text.Parsec.String (Parser)
import qualified Wasp.EntityList as WEL
import Wasp.EntityList (EntityList)
import qualified Wasp.JsCode as WJS
import qualified Parser.JsCode
import qualified Parser.Common as P
import qualified Parser.Entity.Common as PE
import qualified Util as U
import qualified Lexer as L
-- * EntityList
-- | Parses entity list, e.g. "entity-list<Task> TaskList {...}"
entityList :: Parser EntityList
entityList = do
(entityName, listName, options) <-
P.waspElementLinkedToEntity L.reservedNameEntityList entityListOptions
return WEL.EntityList
{ WEL._name = listName
, WEL._entityName = entityName
, WEL._fields = getFieldsConfig options
}
data EntityListOption
= EloFields [WEL.Field]
deriving (Show, Eq)
entityListOptions :: Parser [EntityListOption]
-- TODO(matija): this could be further abstracted as waspClosureOptions option ->
-- that way we abstract L.commaSep
entityListOptions = L.commaSep entityListOption
entityListOption :: Parser EntityListOption
entityListOption = choice
[ entityListOptionFields
]
-- * Fields
getFieldsConfig :: [EntityListOption] -> [WEL.Field]
getFieldsConfig options = case [fs | EloFields fs <- options] of
[] -> []
ls -> head ls
entityListOptionFields :: Parser EntityListOption
entityListOptionFields = EloFields <$> PE.waspPropertyEntityFields fieldOption createFieldConfig
createFieldConfig :: (String, [FieldOption]) -> WEL.Field
createFieldConfig (fieldName, options) = WEL.Field
{ WEL._fieldName = fieldName
, WEL._fieldRender = maybeGetFieldOptionRender options
}
data FieldOption
= FieldOptionRender WJS.JsCode
fieldOption :: Parser FieldOption
fieldOption = choice
[ fieldOptionRender
]
fieldOptionRender :: Parser FieldOption
fieldOptionRender = FieldOptionRender <$> P.waspProperty "render" Parser.JsCode.jsCode
maybeGetFieldOptionRender :: [FieldOption] -> Maybe WJS.JsCode
maybeGetFieldOptionRender options = U.headSafe [js | FieldOptionRender js <- options]

View File

@ -1,26 +0,0 @@
module Parser.EntityList
( entityList
) where
import Text.Parsec.String (Parser)
import Text.Parsec.Char (spaces)
import qualified Wasp.EntityList as EL
import Wasp.EntityList (EntityList)
import qualified Parser.Common as P
import qualified Lexer as L
-- * EntityList
-- | Parses entity list, e.g. "entity-list<Task> TaskList {...}"
entityList :: Parser EntityList
entityList = do
(entityName, listName, _) <-
-- NOTE(matija): not supporting any options yet.
P.waspElementLinkedToEntity L.reservedNameEntityList spaces
return EL.EntityList
{ EL._name = listName
, EL._entityName = entityName
}

12
src/Parser/JsCode.hs Normal file
View File

@ -0,0 +1,12 @@
module Parser.JsCode
( jsCode
) where
import Text.Parsec.String (Parser)
import qualified Data.Text as Text
import qualified Parser.Common as P
import qualified Wasp.JsCode as WJS
jsCode :: Parser WJS.JsCode
jsCode = (WJS.JsCode . Text.pack) <$> P.waspNamedClosure "js"

View File

@ -21,6 +21,12 @@ data EntityForm = EntityForm
, _fields :: [Field] , _fields :: [Field]
} deriving (Show, Eq) } deriving (Show, Eq)
-- NOTE(matija): Ideally generator would not depend on this logic defined outside of it.
-- We are moving away from this approach but some parts of code (Page generator) still
-- rely on it so we cannot remove it completely yet without further refactoring.
--
-- Some record fields are note even included (e.g. _fields), we are keeping this only for the
-- backwards compatibility.
instance ToJSON EntityForm where instance ToJSON EntityForm where
toJSON entityForm = object toJSON entityForm = object
[ "name" .= _name entityForm [ "name" .= _name entityForm

View File

@ -1,16 +1,49 @@
module Wasp.EntityList module Wasp.EntityList
( EntityList(..) ( EntityList(..)
, Field(..)
, getConfigForField
) where ) where
import Data.Aeson ((.=), object, ToJSON(..)) import Data.Aeson ((.=), object, ToJSON(..))
import Wasp.JsCode (JsCode)
import qualified Util as U
import qualified Wasp.Entity as Entity
data EntityList = EntityList data EntityList = EntityList
{ _name :: !String -- Name of the list { _name :: !String -- Name of the list
, _entityName :: !String -- Name of the entity the form is linked to , _entityName :: !String -- Name of the entity the form is linked to
, _fields :: [Field]
} deriving (Show, Eq) } deriving (Show, Eq)
-- NOTE(matija): Ideally generator would not depend on this logic defined outside of it.
-- We are moving away from this approach but some parts of code (Page generator) still
-- rely on it so we cannot remove it completely yet without further refactoring.
--
-- Some record fields are note even included (e.g. _fields), we are keeping this only for the
-- backwards compatibility.
instance ToJSON EntityList where instance ToJSON EntityList where
toJSON entityList = object toJSON entityList = object
[ "name" .= _name entityList [ "name" .= _name entityList
, "entityName" .= _entityName entityList , "entityName" .= _entityName entityList
] ]
-- | For a given entity field, returns its configuration from the given entity-list, if present.
-- TODO(matija): this is very similar to the same function in EntityForm, we could extract it
-- (prob. using typeclass or TH) in the future.
getConfigForField :: EntityList -> Entity.EntityField -> Maybe Field
getConfigForField entityList entityField =
U.headSafe $ filter isConfigOfInputEntityField $ _fields entityList
where
isConfigOfInputEntityField :: Field -> Bool
isConfigOfInputEntityField =
(== Entity.entityFieldName entityField) . _fieldName
-- * Field
data Field = Field
{ _fieldName :: !String
, _fieldRender :: Maybe JsCode -- Js function that renders a list field.
} deriving (Show, Eq)

14
src/Wasp/JsCode.hs Normal file
View File

@ -0,0 +1,14 @@
module Wasp.JsCode
( JsCode(..)
) where
import Data.Aeson (ToJSON(..))
import Data.Text (Text)
data JsCode = JsCode !Text deriving (Show, Eq)
-- TODO(matija): Currently generator is relying on this implementation, which is not
-- ideal. Ideally all the generation logic would be in the generator. But for now this was
-- the simplest way to implement it.
instance ToJSON JsCode where
toJSON (JsCode code) = toJSON code

View File

@ -3,7 +3,7 @@ module Parser.EntityFormTest where
import Test.Tasty.Hspec import Test.Tasty.Hspec
import Parser.Common (runWaspParser) import Parser.Common (runWaspParser)
import Parser.EntityForm import Parser.Entity.EntityForm
( entityForm ( entityForm
, submitConfig , submitConfig

View File

@ -9,6 +9,7 @@ import Wasp
import qualified Wasp.EntityForm as EF import qualified Wasp.EntityForm as EF
import qualified Wasp.EntityList as EL import qualified Wasp.EntityList as EL
import qualified Wasp.Style import qualified Wasp.Style
import qualified Wasp.JsCode
spec_parseWasp :: Spec spec_parseWasp :: Spec
@ -88,6 +89,12 @@ spec_parseWasp =
, WaspElementEntityList $ EL.EntityList , WaspElementEntityList $ EL.EntityList
{ EL._name = "TaskList" { EL._name = "TaskList"
, EL._entityName = "Task" , EL._entityName = "Task"
, EL._fields =
[ EL.Field
{ EL._fieldName = "description"
, EL._fieldRender = Just $ Wasp.JsCode.JsCode "task => task.description"
}
]
} }
] ]
`setJsImports` [ JsImport "something" [relfile|some/file|] ] `setJsImports` [ JsImport "something" [relfile|some/file|] ]

View File

@ -69,5 +69,11 @@ entity-form<Task> CreateTaskForm {
} }
entity-list<Task> TaskList { entity-list<Task> TaskList {
// Options TBD. fields: {
description: {
render: {=js
task => task.description
js=}
}
}
} }