Skip to content

Commit

Permalink
Added Person/People Plural/Singular Support
Browse files Browse the repository at this point in the history
  • Loading branch information
s0kil committed Mar 24, 2021
1 parent de8af1e commit 2c31a96
Show file tree
Hide file tree
Showing 14 changed files with 300 additions and 79 deletions.
33 changes: 16 additions & 17 deletions IHP/IDE/CodeGen/ActionGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import qualified System.Process as Process
import IHP.IDE.CodeGen.Types
import qualified IHP.IDE.SchemaDesigner.Parser as SchemaDesigner
import IHP.IDE.SchemaDesigner.Types
import qualified Text.Countable as Countable
import qualified IHP.IDE.CodeGen.ViewGenerator as ViewGenerator

data ActionConfig = ActionConfig
{ controllerName :: Text
{ controllerName :: Text
, applicationName :: Text
, modelName :: Text
, actionName :: Text
Expand All @@ -23,7 +22,7 @@ buildPlan :: Text -> Text -> Text -> Bool -> IO (Either Text [GeneratorAction])
buildPlan actionName applicationName controllerName doGenerateView=
if (null actionName || null controllerName)
then pure $ Left "Neither action name nor controller name can be empty"
else do
else do
schema <- SchemaDesigner.parseSchemaSql >>= \case
Left parserError -> pure []
Right statements -> pure statements
Expand All @@ -48,8 +47,8 @@ buildPlan actionName applicationName controllerName doGenerateView=
-- get #applicationName config <> ".View." <> get #controllerName config <> "." <> viewName

generateGenericAction :: [Statement] -> ActionConfig -> Bool -> [GeneratorAction]
generateGenericAction schema config doGenerateView =
let
generateGenericAction schema config doGenerateView =
let
controllerName = get #controllerName config
name = ucfirst $ get #actionName config
singularName = config |> get #modelName
Expand All @@ -59,7 +58,7 @@ generateGenericAction schema config doGenerateView =
viewName = if "Action" `isSuffixOf` name
then Text.dropEnd 6 name
else name
indexAction = Countable.pluralize singularName <> "Action"
indexAction = pluralize singularName <> "Action"
specialCases = [
(indexAction, indexContent)
, ("Show" <> singularName <> "Action", showContent)
Expand All @@ -68,16 +67,16 @@ generateGenericAction schema config doGenerateView =
, ("Create" <> singularName <> "Action", createContent)
, ("Delete" <> singularName <> "Action", deleteContent)
]
actionContent = if doGenerateView

actionContent = if doGenerateView
then
" action " <> nameWithSuffix <> " = " <> "do" <> "\n"
<> " render " <> viewName <> "View { .. }\n"
else
else
""
<> " action " <> nameWithSuffix <> " = " <> "do" <> "\n"
<> " redirectTo "<> controllerName <> "Action\n"

modelVariablePlural = lcfirst name
modelVariableSingular = lcfirst singularName
idFieldName = lcfirst singularName <> "Id"
Expand Down Expand Up @@ -111,7 +110,7 @@ generateGenericAction schema config doGenerateView =
""
<> " action Update" <> singularName <> "Action { " <> idFieldName <> " } = do\n"
<> " " <> modelVariableSingular <> " <- fetch " <> idFieldName <> "\n"
<> " " <> modelVariableSingular <> "\n"
<> " " <> modelVariableSingular <> "\n"
<> " |> build" <> singularName <> "\n"
<> " |> ifValid \\case\n"
<> " Left " <> modelVariableSingular <> " -> render EditView { .. }\n"
Expand All @@ -124,7 +123,7 @@ generateGenericAction schema config doGenerateView =
""
<> " action Create" <> singularName <> "Action = do\n"
<> " let " <> modelVariableSingular <> " = newRecord @" <> model <> "\n"
<> " " <> modelVariableSingular <> "\n"
<> " " <> modelVariableSingular <> "\n"
<> " |> build" <> singularName <> "\n"
<> " |> ifValid \\case\n"
<> " Left " <> modelVariableSingular <> " -> render NewView { .. } \n"
Expand All @@ -141,19 +140,19 @@ generateGenericAction schema config doGenerateView =
<> " setSuccessMessage \"" <> model <> " deleted\"\n"
<> " redirectTo " <> name <> "Action\n"

typesContentGeneric =
typesContentGeneric =
" | " <> nameWithSuffix

typesContentWithParameter =
typesContentWithParameter =
" | " <> nameWithSuffix <> " { " <> idFieldName <> " :: !(" <> idType <> ") }\n"


chosenContent = fromMaybe actionContent (lookup nameWithSuffix specialCases)
chosenType = if chosenContent `elem` [actionContent, newContent, createContent, indexContent]
then typesContentGeneric
else typesContentWithParameter

in
in
[ AddAction { filePath = get #applicationName config <> "/Controller/" <> controllerName <> ".hs", fileContent = chosenContent}
, AddToDataConstructor { dataConstructor = "data " <> controllerName, filePath = get #applicationName config <> "/Types.hs", fileContent = chosenType }
]
]
19 changes: 9 additions & 10 deletions IHP/IDE/CodeGen/ApplicationGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import qualified System.Process as Process
import IHP.IDE.CodeGen.Types
import qualified IHP.IDE.SchemaDesigner.Parser as SchemaDesigner
import IHP.IDE.SchemaDesigner.Types
import qualified Text.Countable as Countable
import qualified Data.Text as Text
import qualified Data.Text.IO as Text

Expand Down Expand Up @@ -151,28 +150,28 @@ generateGenericApplication applicationName =
<> "import " <> applicationName <> ".Routes ()\n"
<> "import Application.Helper.View\n"

welcomeControllerStaticHs =
welcomeControllerStaticHs =
"module " <> applicationName <> ".Controller.Static where\n"
<> "import " <> applicationName <>".Controller.Prelude\n"
<> "import " <> applicationName <>".View.Static.Welcome\n"
<> "\n"
<> "instance Controller StaticController where\n"
<> "instance Controller StaticController where\n"
<> " action WelcomeAction = render WelcomeView\n"

welcomeViewStaticHs =
welcomeViewStaticHs =
"module " <> applicationName <> ".View.Static.Welcome where\n"
<>"import " <> applicationName <> ".View.Prelude\n"
<>"\n"
<>"data WelcomeView = WelcomeView\n"
<>"\n"
<>"instance View WelcomeView where\n"
<>" html WelcomeView = [hsx|\n"
<>" html WelcomeView = [hsx|\n"
<>" <div style=\"background-color: #657b83; padding-top: 2rem; padding-bottom: 2rem; color:hsla(196, 13%, 96%, 1); border-radius: 4px\">\n"
<>" <div style=\"max-width: 800px; margin-left: auto; margin-right: auto\">\n"
<>" <h1 style=\"margin-bottom: 2rem; font-size: 2rem; font-weight: 300; border-bottom: 1px solid white; padding-bottom: 0.25rem; border-color: hsla(196, 13%, 60%, 1)\">\n"
<>" <h1 style=\"margin-bottom: 2rem; font-size: 2rem; font-weight: 300; border-bottom: 1px solid white; padding-bottom: 0.25rem; border-color: hsla(196, 13%, 60%, 1)\">\n"
<>" IHP\n"
<>" </h1>\n"
<>"\n"
<>"\n"
<>" <h2 style=\"margin-top: 0; margin-bottom: 0rem; font-weight: 900; font-size: 3rem\">\n"
<>" It's working!\n"
<>" </h2>\n"
Expand All @@ -182,7 +181,7 @@ generateGenericApplication applicationName =
<>" </p>\n"
<>"\n"
<>" <a href=\"https://ihp.digitallyinduced.com/Guide/your-first-project.html\" style=\"margin-top: 2rem; background-color: #268bd2; padding: 1rem; border-radius: 3px; color: hsla(205, 69%, 98%, 1); text-decoration: none; font-weight: bold; display: inline-block; box-shadow: 0 4px 6px hsla(205, 69%, 0%, 0.08); transition: box-shadow 0.2s; transition: transform 0.2s;\" target=\"_blank\">\n"
<>" Learn the Next Steps in the Documentation\n"
<>" Learn the Next Steps in the Documentation\n"
<>" </a>\n"
<>" </div>\n"
<>" </div>\n"
Expand All @@ -193,8 +192,8 @@ generateGenericApplication applicationName =
<>" You can modify this start page by making changes to \"./Web/View/Static/Welcome.hs\".\n"
<>" </p>\n"
<>" </div> \n"
<>"|]"
<>"|]"

in
[ EnsureDirectory { directory = applicationName }
, EnsureDirectory { directory = applicationName <> "/Controller" }
Expand Down
9 changes: 4 additions & 5 deletions IHP/IDE/CodeGen/ControllerGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import Data.Text.IO (appendFile)
import qualified System.Exit as Exit
import IHP.HaskellSupport
import qualified Data.Text as Text
import qualified Text.Countable as Countable
import qualified Data.Char as Char
import qualified IHP.IDE.SchemaDesigner.Parser as SchemaDesigner
import IHP.IDE.SchemaDesigner.Types
Expand Down Expand Up @@ -54,9 +53,9 @@ data HaskellModule = HaskellModule { moduleName :: Text, body :: Text }
generateControllerData :: ControllerConfig -> Text
generateControllerData config =
let
pluralName = Countable.pluralize $ get #controllerName config
name = get #controllerName config
singularName = get #modelName config
pluralName = get #controllerName config |> lcfirst |> pluralize |> ucfirst
singularName = get #modelName config |> lcfirst |> singularize |> ucfirst
idFieldName = lcfirst singularName <> "Id"
idType = "Id " <> singularName
in
Expand All @@ -76,8 +75,8 @@ generateController schema config =
let
applicationName = get #applicationName config
name = config |> get #controllerName
pluralName = Countable.pluralize $ get #controllerName config
singularName = config |> get #modelName
pluralName = get #controllerName config |> lcfirst |> pluralize |> ucfirst
singularName = get #modelName config |> lcfirst |> singularize |> ucfirst
moduleName = applicationName <> ".Controller." <> name
controllerName = name <> "Controller"

Expand Down
3 changes: 1 addition & 2 deletions IHP/IDE/CodeGen/JobGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import qualified System.Process as Process
import IHP.IDE.CodeGen.Types
import qualified IHP.IDE.SchemaDesigner.Parser as SchemaDesigner
import IHP.IDE.SchemaDesigner.Types
import qualified Text.Countable as Countable
import qualified System.Directory as Directory
import qualified Data.Maybe as Maybe

Expand Down Expand Up @@ -107,4 +106,4 @@ instance Worker #{applicationName}Application where
else
[ AddImport { filePath = get #applicationName config <> "/Worker.hs", fileContent = "import " <> qualifiedJobModuleName config }
, AppendToMarker { marker = "-- Generator Marker", filePath = get #applicationName config <> "/Worker.hs", fileContent = " , worker @" <> nameWithSuffix }
]
]
3 changes: 1 addition & 2 deletions IHP/IDE/CodeGen/MailGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import qualified System.Process as Process
import IHP.IDE.CodeGen.Types
import qualified IHP.IDE.SchemaDesigner.Parser as SchemaDesigner
import IHP.IDE.SchemaDesigner.Types
import qualified Text.Countable as Countable

data MailConfig = MailConfig
{ controllerName :: Text
Expand Down Expand Up @@ -51,7 +50,7 @@ buildPlan' schema config =
then Text.replace "Mail" "" name
else name --e.g. "TestMail" -> "Test"

indexAction = Countable.pluralize singularName <> "Action"
indexAction = pluralize singularName <> "Action"

modelFields :: [Text]
modelFields = fieldsForTable schema (modelNameToTableName pluralVariableName)
Expand Down
16 changes: 8 additions & 8 deletions IHP/IDE/CodeGen/ViewGenerator.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import qualified System.Process as Process
import IHP.IDE.CodeGen.Types
import qualified IHP.IDE.SchemaDesigner.Parser as SchemaDesigner
import IHP.IDE.SchemaDesigner.Types
import qualified Text.Countable as Countable

data ViewConfig = ViewConfig
{ controllerName :: Text
Expand Down Expand Up @@ -41,7 +40,8 @@ buildPlan' schema config =
let
controllerName = get #controllerName config
name = get #viewName config
singularName = config |> get #modelName
singularName = config |> get #modelName |> lcfirst |> singularize |> ucfirst -- TODO: `singularize` Should Support Lower-Cased Words
pluralName = singularName |> lcfirst |> pluralize |> ucfirst -- TODO: `pluralize` Should Support Lower-Cased Words
singularVariableName = lcfirst singularName
pluralVariableName = lcfirst controllerName
nameWithSuffix = if "View" `isSuffixOf` name
Expand All @@ -51,7 +51,7 @@ buildPlan' schema config =
then Text.replace "View" "" name
else name --e.g. "TestView" -> "Test"

indexAction = Countable.pluralize singularName <> "Action"
indexAction = pluralName <> "Action"
specialCases = [
("IndexView", indexView)
, ("ShowView", showView)
Expand All @@ -77,7 +77,7 @@ buildPlan' schema config =
<> " html " <> nameWithSuffix <> " { .. } = [hsx|\n"
<> " <nav>\n"
<> " <ol class=\"breadcrumb\">\n"
<> " <li class=\"breadcrumb-item\"><a href={" <> indexAction <> "}>" <> Countable.pluralize name <> "</a></li>\n"
<> " <li class=\"breadcrumb-item\"><a href={" <> indexAction <> "}>" <> pluralize name <> "</a></li>\n"
<> " <li class=\"breadcrumb-item active\">" <> nameWithSuffix <> "</li>\n"
<> " </ol>\n"
<> " </nav>\n"
Expand All @@ -92,7 +92,7 @@ buildPlan' schema config =
<> " html ShowView { .. } = [hsx|\n"
<> " <nav>\n"
<> " <ol class=\"breadcrumb\">\n"
<> " <li class=\"breadcrumb-item\"><a href={" <> indexAction <> "}>" <> Countable.pluralize singularName <> "</a></li>\n"
<> " <li class=\"breadcrumb-item\"><a href={" <> indexAction <> "}>" <> pluralName <> "</a></li>\n"
<> " <li class=\"breadcrumb-item active\">Show " <> singularName <> "</li>\n"
<> " </ol>\n"
<> " </nav>\n"
Expand All @@ -108,7 +108,7 @@ buildPlan' schema config =
<> " html NewView { .. } = [hsx|\n"
<> " <nav>\n"
<> " <ol class=\"breadcrumb\">\n"
<> " <li class=\"breadcrumb-item\"><a href={" <> indexAction <> "}>" <> Countable.pluralize singularName <> "</a></li>\n"
<> " <li class=\"breadcrumb-item\"><a href={" <> indexAction <> "}>" <> pluralName <> "</a></li>\n"
<> " <li class=\"breadcrumb-item active\">New " <> singularName <> "</li>\n"
<> " </ol>\n"
<> " </nav>\n"
Expand All @@ -130,7 +130,7 @@ buildPlan' schema config =
<> " html EditView { .. } = [hsx|\n"
<> " <nav>\n"
<> " <ol class=\"breadcrumb\">\n"
<> " <li class=\"breadcrumb-item\"><a href={" <> indexAction <> "}>" <> Countable.pluralize singularName <> "</a></li>\n"
<> " <li class=\"breadcrumb-item\"><a href={" <> indexAction <> "}>" <> pluralName <> "</a></li>\n"
<> " <li class=\"breadcrumb-item active\">Edit " <> singularName <> "</li>\n"
<> " </ol>\n"
<> " </nav>\n"
Expand All @@ -152,7 +152,7 @@ buildPlan' schema config =
<> " html IndexView { .. } = [hsx|\n"
<> " <nav>\n"
<> " <ol class=\"breadcrumb\">\n"
<> " <li class=\"breadcrumb-item active\"><a href={" <> indexAction <> "}>" <> Countable.pluralize singularName <> "</a></li>\n"
<> " <li class=\"breadcrumb-item active\"><a href={" <> indexAction <> "}>" <> pluralName <> "</a></li>\n"
<> " </ol>\n"
<> " </nav>\n"
<> " <h1>" <> nameWithoutSuffix <> " <a href={pathTo New" <> singularName <> "Action} class=\"btn btn-primary ml-4\">+ New</a></h1>\n"
Expand Down
7 changes: 3 additions & 4 deletions IHP/IDE/SchemaDesigner/View/Columns/Edit.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import qualified IHP.IDE.SchemaDesigner.Compiler as Compiler
import IHP.IDE.ToolServer.Types
import IHP.IDE.ToolServer.Layout
import IHP.IDE.SchemaDesigner.View.Layout
import Text.Countable (singularize)

data EditColumnView = EditColumnView
{ statements :: [Statement]
Expand Down Expand Up @@ -105,7 +104,7 @@ instance View EditColumnView where
<input type="hidden" name="isArray" value={inputValue False}/>
</form>
|]
modalFooter = mempty
modalFooter = mempty
modalCloseUrl = pathTo ShowTableAction { tableName }
modalTitle = "Edit Column"
modal = Modal { modalContent, modalFooter, modalCloseUrl, modalTitle }
Expand Down Expand Up @@ -149,7 +148,7 @@ typeSelector postgresType enumNames = [hsx|
Just selection ->
if selection == value || selection == value <> "[]"
then [hsx|<option value={value} selected="selected">{text}</option>|]
else [hsx|<option value={value}>{text}</option>|]
else [hsx|<option value={value}>{text}</option>|]
customenums [] = [hsx| |]
customenums xs = [hsx| <optgroup label="Custom Enums">
{forEach xs renderEnumType}
Expand All @@ -174,4 +173,4 @@ defaultSelector defValue = [hsx|
displayedValue = case expression of
TextExpression "" -> "\"\""
_ -> Compiler.compileExpression expression
renderValue Nothing = [hsx|<option value="" selected={Nothing == defValue}>No default</option>|]
renderValue Nothing = [hsx|<option value="" selected={Nothing == defValue}>No default</option>|]
4 changes: 1 addition & 3 deletions IHP/IDE/SchemaDesigner/View/Columns/New.hs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import IHP.IDE.SchemaDesigner.Types
import IHP.IDE.ToolServer.Types
import IHP.IDE.ToolServer.Layout
import IHP.IDE.SchemaDesigner.View.Layout
import qualified Text.Countable as Countable
import IHP.IDE.SchemaDesigner.View.Columns.Edit (typeSelector)
import Text.Countable (singularize)

data NewColumnView = NewColumnView
{ statements :: [Statement]
Expand Down Expand Up @@ -83,7 +81,7 @@ instance View NewColumnView where
where
generateReferenceCheckboxes = [hsx|<span id="checkboxes">{forEach tableNames checkbox}</span>|]
where checkbox tableName = [hsx|
<label class="mx-2 ref" style="font-size: 12px; display: none;" data-attribute={(Countable.singularize tableName) <> "_id"} data-table={tableName}>
<label class="mx-2 ref" style="font-size: 12px; display: none;" data-attribute={(singularize tableName) <> "_id"} data-table={tableName}>
<input id="reference" type="checkbox" name="isReference" class="mr-1"/>
<a id="refText">References {tableName}</a>
</label>|]
Expand Down

0 comments on commit 2c31a96

Please sign in to comment.