mirror of
https://github.com/wasp-lang/wasp.git
synced 2024-12-25 18:13:52 +03:00
Entity lists are supported in .wasp now, no options supported yet. (#78)
This commit is contained in:
parent
e2a885bd90
commit
e57fa6c021
@ -10,13 +10,17 @@ import {= what =} from "{= from =}"
|
||||
import * as {= entityLowerName =}State from '{= entityStatePath =}'
|
||||
import * as {= entityLowerName =}Actions from '{= entityActionsPath =}'
|
||||
import {= entity.name =} from '{= entityClassPath =}'
|
||||
import {= entity.name =}List from '{= entityListPath =}'
|
||||
|
||||
{=! Imports of entity create forms =}
|
||||
{=# entityCreateForms =}
|
||||
import {= entityForm.name =} from '{= path =}'
|
||||
{=/ entityCreateForms =}
|
||||
|
||||
{=! Imports of entity lists =}
|
||||
{=# entityLists =}
|
||||
import {= entityList.name =} from '{= path =}'
|
||||
{=/ entityLists =}
|
||||
|
||||
{=/ entities =}
|
||||
{=# pageStylePath =}
|
||||
import '{= pageStylePath =}'
|
||||
|
@ -10,7 +10,7 @@ import TextField from '@material-ui/core/TextField'
|
||||
import {= entityClassName =} from '../{= entityClassName =}'
|
||||
|
||||
|
||||
export default class {= name =} extends React.Component {
|
||||
export default class {= formName =} extends React.Component {
|
||||
// TODO: Add propTypes.
|
||||
|
||||
state = {
|
||||
|
@ -19,16 +19,16 @@ import * as {= entityLowerName =}Actions from '../actions'
|
||||
import {= entityClassName =} from '../{= entityClassName =}'
|
||||
|
||||
|
||||
export class List extends React.Component {
|
||||
export class {= listName =} extends React.Component {
|
||||
static propTypes = {
|
||||
editable: PropTypes.bool,
|
||||
}
|
||||
|
||||
update{= entity.name =}Field = (fieldName, newFieldValue, {= entityLowerName =}) => {
|
||||
const updated{= entity.name =} = new {= entityClassName =}(
|
||||
update{= entityName =}Field = (fieldName, newFieldValue, {= entityLowerName =}) => {
|
||||
const updated{= entityName =} = new {= entityClassName =}(
|
||||
{ ...{= entityLowerName =}.toData(), [fieldName]: newFieldValue }
|
||||
)
|
||||
this.props.update{= entity.name =}({= entityLowerName =}.id, updated{= entity.name =})
|
||||
this.props.update{= entityName =}({= entityLowerName =}.id, updated{= entityName =})
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -38,21 +38,21 @@ export class List extends React.Component {
|
||||
<Table>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
{=# entityTypedFields =}
|
||||
{=# listFields =}
|
||||
{=# boolean =}
|
||||
<TableCell>{= name =}</TableCell>
|
||||
{=/ boolean =}
|
||||
{=# string =}
|
||||
<TableCell>{= name =}</TableCell>
|
||||
{=/ string =}
|
||||
{=/ entityTypedFields =}
|
||||
{=/ listFields =}
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
|
||||
<TableBody>
|
||||
{this.props.{= entityLowerName =}List.map(({= entityLowerName =}) => (
|
||||
<TableRow key={{= entityLowerName =}.id}>
|
||||
{=# entityTypedFields =}
|
||||
{=# listFields =}
|
||||
{=# boolean =}
|
||||
<TableCell>
|
||||
<Checkbox
|
||||
@ -62,7 +62,7 @@ export class List extends React.Component {
|
||||
'aria-label': 'checkbox'
|
||||
}}
|
||||
disabled={!this.props.editable}
|
||||
onChange={e => this.update{= entity.name =}Field(
|
||||
onChange={e => this.update{= entityName =}Field(
|
||||
'{= name =}', e.target.checked, {= entityLowerName =}
|
||||
)}
|
||||
/>
|
||||
@ -73,7 +73,7 @@ export class List extends React.Component {
|
||||
{this.props.editable ? (
|
||||
<TextField
|
||||
value={{= entityLowerName =}.{= name =}}
|
||||
onChange={e => this.update{= entity.name =}Field(
|
||||
onChange={e => this.update{= entityName =}Field(
|
||||
'{= name =}', e.target.value, {= entityLowerName =}
|
||||
)}
|
||||
/>
|
||||
@ -82,7 +82,7 @@ export class List extends React.Component {
|
||||
)}
|
||||
</TableCell>
|
||||
{=/ string =}
|
||||
{=/ entityTypedFields =}
|
||||
{=/ listFields =}
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
@ -98,5 +98,5 @@ export default connect(state => ({
|
||||
{= entityLowerName =}List: {= entityLowerName =}State.selectors.all(state)
|
||||
}), {
|
||||
// Actions
|
||||
update{= entity.name =}: {= entityLowerName =}Actions.update
|
||||
})(List)
|
||||
update{= entityName =}: {= entityLowerName =}Actions.update
|
||||
})({= listName =})
|
||||
|
@ -2,7 +2,7 @@ import React from 'react'
|
||||
|
||||
import Task from '@wasp/entities/task/Task'
|
||||
import NewTaskForm from '@wasp/entities/task/components/NewTaskForm'
|
||||
import TaskList from '@wasp/entities/task/components/List'
|
||||
import TaskList from '@wasp/entities/task/components/TaskList'
|
||||
|
||||
import * as config from './config'
|
||||
|
||||
@ -28,7 +28,8 @@ export default class Todo extends React.Component {
|
||||
<h1> { config.appName } </h1>
|
||||
|
||||
<button onClick={this.toggleIsDoneForAllTasks}>
|
||||
Toggle completion {/* TODO: Use icon (but we need to either install @material-ui/icons or add font awesome to the index.html. */}
|
||||
Toggle completion {/* TODO: Use icon (but we need to either install @material-ui/icons
|
||||
or add font-awesome to the index.html. */}
|
||||
</button>
|
||||
|
||||
<NewTaskForm
|
||||
|
@ -61,6 +61,7 @@ entity-form<Task> NewTaskForm {
|
||||
}
|
||||
}
|
||||
|
||||
// We can define multiple forms for a single entity.
|
||||
entity-form<Task> CreateTaskForm {
|
||||
// Entity list definition.
|
||||
entity-list<Task> TaskList {
|
||||
// Options TBD, not supported for now.
|
||||
}
|
||||
|
@ -5,8 +5,6 @@ module Generator.Entity
|
||||
, entityClassPathInSrc
|
||||
, entityStatePathInSrc
|
||||
, entityActionsPathInSrc
|
||||
, entityCreateFormPathInSrc
|
||||
, entityListPathInSrc
|
||||
|
||||
-- EXPORTED FOR TESTING:
|
||||
, generateEntityClass
|
||||
@ -19,16 +17,20 @@ module Generator.Entity
|
||||
) where
|
||||
|
||||
import Data.Maybe (fromJust)
|
||||
import Path ((</>), relfile, reldir)
|
||||
import Path ((</>), relfile)
|
||||
import qualified Path
|
||||
import qualified Path.Aliases as Path
|
||||
|
||||
import Wasp
|
||||
import Generator.FileDraft
|
||||
import qualified Generator.Common as Common
|
||||
import Generator.Entity.EntityForm (generateEntityCreateForm, entityCreateFormPathInSrc)
|
||||
import Generator.Entity.EntityForm (generateEntityCreateForm)
|
||||
import Generator.Entity.EntityList (generateEntityList)
|
||||
import Generator.Entity.Common
|
||||
(entityTemplatesDirPath, entityTemplateData, entityDirPathInSrc, entityComponentsDirPathInSrc)
|
||||
( entityTemplatesDirPath
|
||||
, entityTemplateData
|
||||
, entityDirPathInSrc
|
||||
)
|
||||
|
||||
|
||||
generateEntities :: Wasp -> [FileDraft]
|
||||
@ -59,31 +61,23 @@ generateEntityActions :: Wasp -> Entity -> FileDraft
|
||||
generateEntityActions wasp entity
|
||||
= createSimpleEntityFileDraft wasp entity (entityActionsPathInSrc entity) [relfile|actions.js|]
|
||||
|
||||
-- TODO(matija): currently we are generating these components automatically, as soon as the
|
||||
-- entity is defined. Now we are changing this and will generate them on-demand, depending on
|
||||
-- what is in Wasp.
|
||||
generateEntityComponents :: Wasp -> Entity -> [FileDraft]
|
||||
generateEntityComponents wasp entity = concat
|
||||
[ generateEntityCreateForms wasp entity
|
||||
|
||||
-- TODO(matija): this will become listS as well (in the future PR).
|
||||
, [generateEntityList wasp entity]
|
||||
, generateEntityLists wasp entity
|
||||
]
|
||||
|
||||
-- | Generates creation forms for the given entity.
|
||||
generateEntityCreateForms :: Wasp -> Entity -> [FileDraft]
|
||||
generateEntityCreateForms wasp entity =
|
||||
map (generateEntityCreateForm wasp) entityForms
|
||||
generateEntityCreateForms wasp entity = map (generateEntityCreateForm wasp) entityForms
|
||||
where
|
||||
entityForms = getEntityFormsForEntity wasp entity
|
||||
|
||||
-- TODO(matija): do I need wasp at all?
|
||||
-- | Generates list component for the specified entity, so user can see all the
|
||||
-- entity instances.
|
||||
generateEntityList :: Wasp -> Entity -> FileDraft
|
||||
generateEntityList wasp entity
|
||||
= createSimpleEntityFileDraft wasp entity (entityListPathInSrc entity)
|
||||
([reldir|components|] </> [relfile|List.js|])
|
||||
-- | Generates list components for the given entity.
|
||||
generateEntityLists :: Wasp -> Entity -> [FileDraft]
|
||||
generateEntityLists wasp entity = map (generateEntityList wasp) entityLists
|
||||
where
|
||||
entityLists = getEntityListsForEntity wasp entity
|
||||
|
||||
-- | Helper function that captures common logic for generating entity file draft.
|
||||
createSimpleEntityFileDraft :: Wasp -> Entity -> Path.RelFile -> Path.RelFile -> FileDraft
|
||||
@ -108,8 +102,3 @@ entityActionTypesPathInSrc entity = entityDirPathInSrc entity </> [relfile|actio
|
||||
entityClassPathInSrc :: Entity -> Path.RelFile
|
||||
entityClassPathInSrc entity = entityDirPathInSrc entity </>
|
||||
(fromJust $ Path.parseRelFile $ (entityName entity) ++ ".js")
|
||||
|
||||
-- * Components
|
||||
|
||||
entityListPathInSrc :: Entity -> Path.RelFile
|
||||
entityListPathInSrc entity = entityComponentsDirPathInSrc entity </> [relfile|List.js|]
|
||||
|
@ -6,8 +6,8 @@ module Generator.Entity.EntityForm
|
||||
, FormFieldTemplateData(..)
|
||||
) where
|
||||
|
||||
import Data.Aeson ((.=), object, ToJSON(..))
|
||||
import Control.Exception (assert)
|
||||
import Data.Aeson ((.=), object, ToJSON(..))
|
||||
import Data.Maybe (fromJust)
|
||||
import Path ((</>), reldir, relfile)
|
||||
import qualified Path
|
||||
@ -17,8 +17,8 @@ import qualified Util
|
||||
import qualified Wasp as Wasp
|
||||
import Wasp (Wasp)
|
||||
|
||||
import qualified Wasp.EntityForm as EF
|
||||
import Generator.FileDraft
|
||||
import qualified Wasp.EntityForm as WEF
|
||||
import qualified Generator.FileDraft as FD
|
||||
import qualified Generator.Entity.Common as EC
|
||||
import qualified Generator.Common as Common
|
||||
|
||||
@ -33,7 +33,7 @@ data EntityFormTemplateData = EntityFormTemplateData
|
||||
|
||||
instance ToJSON EntityFormTemplateData where
|
||||
toJSON td = object
|
||||
[ "name" .= _formName td
|
||||
[ "formName" .= _formName td
|
||||
, "entityClassName" .= _entityClassName td
|
||||
, "formFields" .= _formFields td
|
||||
, "showSubmitButton" .= _showSubmitButton td
|
||||
@ -42,9 +42,9 @@ instance ToJSON EntityFormTemplateData where
|
||||
-- | Represents template data for the individual form field.
|
||||
data FormFieldTemplateData = FormFieldTemplateData
|
||||
{ _fieldName :: !String
|
||||
, _fieldType :: Wasp.EntityFieldType
|
||||
, _fieldType :: !Wasp.EntityFieldType
|
||||
, _fieldShow :: !Bool
|
||||
, _fieldDefaultValue :: !EF.DefaultValue
|
||||
, _fieldDefaultValue :: !WEF.DefaultValue
|
||||
} deriving (Show)
|
||||
|
||||
instance ToJSON FormFieldTemplateData where
|
||||
@ -54,67 +54,67 @@ instance ToJSON FormFieldTemplateData where
|
||||
, "type" .= _fieldType f
|
||||
, "show" .= _fieldShow f
|
||||
, "defaultValue" .= case (_fieldDefaultValue f) of
|
||||
(EF.DefaultValueString s) -> s
|
||||
(EF.DefaultValueBool b) -> Util.toLowerFirst $ show b
|
||||
(WEF.DefaultValueString s) -> s
|
||||
(WEF.DefaultValueBool b) -> Util.toLowerFirst $ show b
|
||||
]
|
||||
|
||||
-- | Given entity and an entity form for it, creates a single data structure
|
||||
-- with all the values needed by the template to generate the form.
|
||||
createEntityFormTemplateData :: Wasp.Entity -> EF.EntityForm -> EntityFormTemplateData
|
||||
createEntityFormTemplateData :: Wasp.Entity -> WEF.EntityForm -> EntityFormTemplateData
|
||||
createEntityFormTemplateData entity entityForm =
|
||||
assert (Wasp.entityName entity == EF._entityName entityForm) $
|
||||
assert (Wasp.entityName entity == WEF._entityName entityForm) $
|
||||
|
||||
EntityFormTemplateData
|
||||
{ _formName = EF._name entityForm
|
||||
{ _formName = WEF._name entityForm
|
||||
, _entityClassName = EC.getEntityClassName entity
|
||||
, _formFields = map (createFormField entityForm) $ Wasp.entityFields entity
|
||||
, _formFields = map (createFormFieldTD entityForm) $ Wasp.entityFields entity
|
||||
-- Submit
|
||||
, _showSubmitButton = maybe True id maybeShowSubmitButton
|
||||
}
|
||||
where
|
||||
maybeShowSubmitButton :: Maybe Bool
|
||||
maybeShowSubmitButton = EF._submit entityForm >>= EF._submitButton >>= EF._submitButtonShow
|
||||
maybeShowSubmitButton = WEF._submit entityForm >>= WEF._submitButton >>= WEF._submitButtonShow
|
||||
|
||||
-- | Given field data from entity and an entity form for it, creates a single
|
||||
-- data structure with all the values needed by the template to generate a form field.
|
||||
createFormField :: EF.EntityForm -> Wasp.EntityField -> FormFieldTemplateData
|
||||
createFormField entityForm entityField = FormFieldTemplateData
|
||||
createFormFieldTD :: WEF.EntityForm -> Wasp.EntityField -> FormFieldTemplateData
|
||||
createFormFieldTD entityForm entityField = FormFieldTemplateData
|
||||
{ _fieldName = Wasp.entityFieldName entityField
|
||||
, _fieldType = Wasp.entityFieldType entityField
|
||||
, _fieldShow = maybe True id $ formFieldConfig >>= EF._fieldShow
|
||||
, _fieldShow = maybe True id $ formFieldConfig >>= WEF._fieldShow
|
||||
, _fieldDefaultValue = maybe
|
||||
defaultValueIfNothingInForm
|
||||
id
|
||||
$ formFieldConfig >>= EF._fieldDefaultValue
|
||||
$ formFieldConfig >>= WEF._fieldDefaultValue
|
||||
}
|
||||
where
|
||||
-- Configuration of a form field within entity-form, if there is any.
|
||||
formFieldConfig :: Maybe EF.Field
|
||||
formFieldConfig = EF.getConfigForField entityForm entityField
|
||||
formFieldConfig :: Maybe WEF.Field
|
||||
formFieldConfig = WEF.getConfigForField entityForm entityField
|
||||
|
||||
getDefaultValueForFieldWithType :: Wasp.EntityFieldType -> EF.DefaultValue
|
||||
getDefaultValueForFieldWithType :: Wasp.EntityFieldType -> WEF.DefaultValue
|
||||
getDefaultValueForFieldWithType efType = case efType of
|
||||
Wasp.EftString -> EF.DefaultValueString ""
|
||||
Wasp.EftBoolean -> EF.DefaultValueBool False
|
||||
Wasp.EftString -> WEF.DefaultValueString ""
|
||||
Wasp.EftBoolean -> WEF.DefaultValueBool False
|
||||
|
||||
-- If user did not explicitly set a default value, we determine it ourselves.
|
||||
defaultValueIfNothingInForm :: EF.DefaultValue
|
||||
defaultValueIfNothingInForm :: WEF.DefaultValue
|
||||
defaultValueIfNothingInForm =
|
||||
getDefaultValueForFieldWithType $ Wasp.entityFieldType entityField
|
||||
|
||||
|
||||
-- | Generates entity creation form.
|
||||
generateEntityCreateForm :: Wasp -> EF.EntityForm -> FileDraft
|
||||
generateEntityCreateForm :: Wasp -> WEF.EntityForm -> FD.FileDraft
|
||||
generateEntityCreateForm wasp entityForm =
|
||||
createTemplateFileDraft dstPath templateSrcPath (Just templateData)
|
||||
FD.createTemplateFileDraft dstPath templateSrcPath (Just templateData)
|
||||
where
|
||||
-- NOTE(matija): There should always be an entity in wasp for the given entity form,
|
||||
-- we want an error to be thrown otherwise.
|
||||
-- NOTE(matija): There should always be an entity in wasp for the given entity form.
|
||||
-- If not, we want an error to be thrown.
|
||||
entity = maybe
|
||||
(error $ "Wasp must contain entity to which the entity form refers: " ++
|
||||
EF._entityName entityForm)
|
||||
WEF._entityName entityForm)
|
||||
id
|
||||
(Wasp.getEntityByName wasp (EF._entityName entityForm))
|
||||
(Wasp.getEntityByName wasp (WEF._entityName entityForm))
|
||||
|
||||
templateSrcPath = EC.entityTemplatesDirPath </> [reldir|components|] </> [relfile|CreateForm.js|]
|
||||
|
||||
@ -122,7 +122,7 @@ generateEntityCreateForm wasp entityForm =
|
||||
|
||||
templateData = toJSON $ createEntityFormTemplateData entity entityForm
|
||||
|
||||
entityCreateFormPathInSrc :: Wasp.Entity -> EF.EntityForm -> Path.RelFile
|
||||
entityCreateFormPathInSrc :: Wasp.Entity -> WEF.EntityForm -> Path.RelFile
|
||||
entityCreateFormPathInSrc entity entityForm =
|
||||
EC.entityComponentsDirPathInSrc entity </>
|
||||
(fromJust $ Path.parseRelFile $ (EF._name entityForm) ++ ".js")
|
||||
(fromJust $ Path.parseRelFile $ (WEF._name entityForm) ++ ".js")
|
||||
|
89
src/Generator/Entity/EntityList.hs
Normal file
89
src/Generator/Entity/EntityList.hs
Normal file
@ -0,0 +1,89 @@
|
||||
module Generator.Entity.EntityList
|
||||
( generateEntityList
|
||||
, entityListPathInSrc
|
||||
) where
|
||||
|
||||
import Control.Exception (assert)
|
||||
import Data.Aeson ((.=), object, ToJSON(..))
|
||||
import Data.Maybe (fromJust)
|
||||
import Path ((</>), reldir, relfile, parseRelFile)
|
||||
import qualified Path.Aliases as Path
|
||||
|
||||
import qualified Wasp
|
||||
import Wasp (Wasp)
|
||||
import qualified Wasp.EntityList as WEL
|
||||
|
||||
import qualified Generator.FileDraft as FD
|
||||
import qualified Generator.Entity.Common as EC
|
||||
import qualified Generator.Common as Common
|
||||
|
||||
data EntityListTemplateData = EntityListTemplateData
|
||||
{ _listName :: !String
|
||||
, _entityName :: !String
|
||||
, _entityClassName :: !String
|
||||
, _entityLowerName :: !String
|
||||
, _listFields :: ![ListFieldTemplateData]
|
||||
}
|
||||
|
||||
instance ToJSON EntityListTemplateData where
|
||||
toJSON td = object
|
||||
[ "listName" .= _listName td
|
||||
, "entityName" .= _entityName td
|
||||
, "entityClassName" .= _entityClassName td
|
||||
, "entityLowerName" .= _entityLowerName td
|
||||
, "listFields" .= _listFields td
|
||||
]
|
||||
|
||||
data ListFieldTemplateData = ListFieldTemplateData
|
||||
{ _fieldName :: !String
|
||||
, _fieldType :: !Wasp.EntityFieldType
|
||||
}
|
||||
|
||||
instance ToJSON ListFieldTemplateData where
|
||||
toJSON f = EC.addEntityFieldTypeToJsonAsKeyWithValueTrue (_fieldType f) $
|
||||
object
|
||||
[ "name" .= _fieldName f
|
||||
, "type" .= _fieldType f
|
||||
]
|
||||
|
||||
createEntityListTemplateData :: Wasp.Entity -> WEL.EntityList -> EntityListTemplateData
|
||||
createEntityListTemplateData entity entityList =
|
||||
assert (Wasp.entityName entity == WEL._entityName entityList) $
|
||||
|
||||
EntityListTemplateData
|
||||
{ _listName = WEL._name entityList
|
||||
, _entityName = Wasp.entityName entity
|
||||
, _entityClassName = EC.getEntityClassName entity
|
||||
, _entityLowerName = EC.getEntityLowerName entity
|
||||
, _listFields = map (createListFieldTD entityList) $ Wasp.entityFields entity
|
||||
}
|
||||
|
||||
createListFieldTD :: WEL.EntityList -> Wasp.EntityField -> ListFieldTemplateData
|
||||
createListFieldTD _ entityField = ListFieldTemplateData
|
||||
{ _fieldName = Wasp.entityFieldName entityField
|
||||
, _fieldType = Wasp.entityFieldType entityField
|
||||
}
|
||||
|
||||
generateEntityList :: Wasp -> WEL.EntityList -> FD.FileDraft
|
||||
generateEntityList wasp entityList =
|
||||
FD.createTemplateFileDraft dstPath templateSrcPath (Just templateData)
|
||||
where
|
||||
-- NOTE(matija): There should always be an entity in wasp for the given entity list.
|
||||
-- If not, we want an error to be thrown.
|
||||
entity = maybe
|
||||
(error $ "Wasp must contain entity to which the entity list refers: " ++
|
||||
WEL._entityName entityList)
|
||||
id
|
||||
(Wasp.getEntityByName wasp (WEL._entityName entityList))
|
||||
|
||||
templateSrcPath = EC.entityTemplatesDirPath </> [reldir|components|] </> [relfile|List.js|]
|
||||
|
||||
dstPath = Common.srcDirPath </> (entityListPathInSrc entity entityList)
|
||||
|
||||
templateData = toJSON $ createEntityListTemplateData entity entityList
|
||||
|
||||
-- | Path in the generated src dir where the given entity list will be located.
|
||||
entityListPathInSrc :: Wasp.Entity -> WEL.EntityList -> Path.RelFile
|
||||
entityListPathInSrc entity entityList =
|
||||
EC.entityComponentsDirPathInSrc entity </>
|
||||
(fromJust $ parseRelFile $ (WEL._name entityList) ++ ".js")
|
@ -20,6 +20,8 @@ import qualified Util
|
||||
import Wasp
|
||||
import Generator.FileDraft
|
||||
import qualified Generator.Entity as EntityGenerator
|
||||
import qualified Generator.Entity.EntityForm as GEF
|
||||
import qualified Generator.Entity.EntityList as GEL
|
||||
import Generator.ExternalCode.Common (externalCodeDirPathInSrc)
|
||||
import qualified Generator.Common as Common
|
||||
|
||||
@ -59,20 +61,29 @@ generatePageComponent wasp page = createTemplateFileDraft dstPath srcPath (Just
|
||||
, "entityClassPath" .=
|
||||
(buildImportPathFromPathInSrc $ EntityGenerator.entityClassPathInSrc entity)
|
||||
, "entityCreateForms" .= map toEntityFormData entityForms
|
||||
|
||||
-- TODO(matija): this will become "entityLists"
|
||||
, "entityListPath" .= (buildImportPathFromPathInSrc $ EntityGenerator.entityListPathInSrc entity)
|
||||
, "entityLists" .= map toEntityListData entityLists
|
||||
]
|
||||
where
|
||||
-- Entity forms
|
||||
entityForms = getEntityFormsForEntity wasp entity
|
||||
generateEntityFormPath entityForm =
|
||||
buildImportPathFromPathInSrc $ EntityGenerator.entityCreateFormPathInSrc entity entityForm
|
||||
buildImportPathFromPathInSrc $ GEF.entityCreateFormPathInSrc entity entityForm
|
||||
|
||||
toEntityFormData entityForm = object
|
||||
[ "entityForm" .= entityForm
|
||||
, "path" .= generateEntityFormPath entityForm
|
||||
]
|
||||
|
||||
-- Entity list
|
||||
entityLists = getEntityListsForEntity wasp entity
|
||||
generateEntityListPath entityList =
|
||||
buildImportPathFromPathInSrc $ GEL.entityListPathInSrc entity entityList
|
||||
|
||||
toEntityListData entityList = object
|
||||
[ "entityList" .= entityList
|
||||
, "path" .= generateEntityListPath entityList
|
||||
]
|
||||
|
||||
toJsImportData :: Wasp.JsImport -> Aeson.Value
|
||||
toJsImportData jsImport = object
|
||||
[ "what" .= jsImportWhat jsImport
|
||||
|
@ -25,6 +25,9 @@ reservedNameEntity = "entity"
|
||||
reservedNameEntityForm :: String
|
||||
reservedNameEntityForm = "entity-form"
|
||||
|
||||
reservedNameEntityList :: String
|
||||
reservedNameEntityList = "entity-list"
|
||||
|
||||
-- * Data types.
|
||||
|
||||
reservedNameString :: String
|
||||
|
@ -13,16 +13,18 @@ import Parser.App (app)
|
||||
import Parser.Page (page)
|
||||
import Parser.Entity (entity)
|
||||
import Parser.EntityForm (entityForm)
|
||||
import Parser.EntityList (entityList)
|
||||
import Parser.JsImport (jsImport)
|
||||
import Parser.Common (runWaspParser)
|
||||
|
||||
|
||||
waspElement :: Parser Wasp.WaspElement
|
||||
waspElement =
|
||||
waspElementApp
|
||||
waspElement
|
||||
= waspElementApp
|
||||
<|> waspElementPage
|
||||
<|> waspElementEntity
|
||||
<|> waspElementEntityForm
|
||||
<|> waspElementEntityList
|
||||
|
||||
waspElementApp :: Parser Wasp.WaspElement
|
||||
waspElementApp = Wasp.WaspElementApp <$> app
|
||||
@ -36,6 +38,9 @@ waspElementEntity = Wasp.WaspElementEntity <$> entity
|
||||
waspElementEntityForm :: Parser Wasp.WaspElement
|
||||
waspElementEntityForm = Wasp.WaspElementEntityForm <$> entityForm
|
||||
|
||||
waspElementEntityList :: Parser Wasp.WaspElement
|
||||
waspElementEntityList = Wasp.WaspElementEntityList <$> entityList
|
||||
|
||||
-- | Top level parser, produces Wasp.
|
||||
waspParser :: Parser Wasp.Wasp
|
||||
waspParser = do
|
||||
|
@ -24,7 +24,8 @@ import qualified Lexer as L
|
||||
-- | Parses entity form, e.g. "entity-form<Task> NewTaskForm {...}"
|
||||
entityForm :: Parser EntityForm
|
||||
entityForm = do
|
||||
(entityName, formName, options) <- P.waspElementLinkedToEntity L.reservedNameEntityForm entityFormOptions
|
||||
(entityName, formName, options) <-
|
||||
P.waspElementLinkedToEntity L.reservedNameEntityForm entityFormOptions
|
||||
|
||||
return EF.EntityForm
|
||||
{ EF._name = formName
|
||||
|
26
src/Parser/EntityList.hs
Normal file
26
src/Parser/EntityList.hs
Normal file
@ -0,0 +1,26 @@
|
||||
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/Wasp.hs
12
src/Wasp.hs
@ -18,6 +18,7 @@ module Wasp
|
||||
, getEntityByName
|
||||
|
||||
, getEntityFormsForEntity
|
||||
, getEntityListsForEntity
|
||||
|
||||
, module Wasp.Page
|
||||
, getPages
|
||||
@ -33,6 +34,7 @@ import qualified ExternalCode
|
||||
import Wasp.App
|
||||
import Wasp.Entity
|
||||
import qualified Wasp.EntityForm as EF
|
||||
import qualified Wasp.EntityList as EL
|
||||
import Wasp.JsImport
|
||||
import Wasp.Page
|
||||
|
||||
@ -51,6 +53,7 @@ data WaspElement
|
||||
| WaspElementPage !Page
|
||||
| WaspElementEntity !Entity
|
||||
| WaspElementEntityForm !EF.EntityForm
|
||||
| WaspElementEntityList !EL.EntityList
|
||||
deriving (Show, Eq)
|
||||
|
||||
fromWaspElems :: [WaspElement] -> Wasp
|
||||
@ -127,6 +130,15 @@ getEntityFormsForEntity wasp entity = filter isFormOfGivenEntity allEntityForms
|
||||
allEntityForms = [entityForm | (WaspElementEntityForm entityForm) <- waspElements wasp]
|
||||
isFormOfGivenEntity ef = entityName entity == EF._entityName ef
|
||||
|
||||
-- * EntityList
|
||||
|
||||
-- | Retrieves all entity lists for a given entity from a Wasp record.
|
||||
getEntityListsForEntity :: Wasp -> Entity -> [EL.EntityList]
|
||||
getEntityListsForEntity wasp entity = filter isListOfGivenEntity allEntityLists
|
||||
where
|
||||
allEntityLists = [entityList | (WaspElementEntityList entityList) <- waspElements wasp]
|
||||
isListOfGivenEntity el = entityName entity == EL._entityName el
|
||||
|
||||
-- * ToJSON instances.
|
||||
|
||||
instance ToJSON Wasp where
|
||||
|
16
src/Wasp/EntityList.hs
Normal file
16
src/Wasp/EntityList.hs
Normal file
@ -0,0 +1,16 @@
|
||||
module Wasp.EntityList
|
||||
( EntityList(..)
|
||||
) where
|
||||
|
||||
import Data.Aeson ((.=), object, ToJSON(..))
|
||||
|
||||
data EntityList = EntityList
|
||||
{ _name :: !String -- Name of the list
|
||||
, _entityName :: !String -- Name of the entity the form is linked to
|
||||
} deriving (Show, Eq)
|
||||
|
||||
instance ToJSON EntityList where
|
||||
toJSON entityList = object
|
||||
[ "name" .= _name entityList
|
||||
, "entityName" .= _entityName entityList
|
||||
]
|
@ -6,6 +6,7 @@ import Data.Either
|
||||
import Parser
|
||||
import Wasp
|
||||
import qualified Wasp.EntityForm as EF
|
||||
import qualified Wasp.EntityList as EL
|
||||
|
||||
spec_parseWasp :: Spec
|
||||
spec_parseWasp =
|
||||
@ -81,6 +82,10 @@ spec_parseWasp =
|
||||
}
|
||||
]
|
||||
}
|
||||
, WaspElementEntityList $ EL.EntityList
|
||||
{ EL._name = "TaskList"
|
||||
, EL._entityName = "Task"
|
||||
}
|
||||
]
|
||||
`setJsImports` [ JsImport "something" "some/file" ]
|
||||
)
|
||||
|
@ -67,4 +67,6 @@ entity-form<Task> CreateTaskForm {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
entity-list<Task> TaskList {
|
||||
// Options TBD.
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user