Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(elm): Add form for creating a category #76

Merged
merged 3 commits into from
Aug 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions aion/web/elm/src/General/Constants.elm
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,13 @@ module General.Constants exposing (..)
hostname : String
hostname =
"http://localhost:4000/"


createCategoryUrl : String
createCategoryUrl =
hostname ++ "api/subjects"


createQuestionUrl : String
createQuestionUrl =
hostname ++ "api/questions"
3 changes: 2 additions & 1 deletion aion/web/elm/src/General/Models.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module General.Models exposing (..)

import Forms
import Msgs exposing (Msg)
import Panel.Models exposing (PanelData, questionForm)
import Panel.Models exposing (PanelData, categoryForm, questionForm)
import Phoenix.Socket
import RemoteData exposing (WebData)
import Room.Models exposing (RoomId, RoomsData, UsersInRoom, QuestionInRoom, UserGameData)
Expand Down Expand Up @@ -59,5 +59,6 @@ initialModel flags route =
, toasties = Toasty.initialState
, panelData =
{ questionForm = Forms.initForm questionForm
, categoryForm = Forms.initForm categoryForm
}
}
5 changes: 4 additions & 1 deletion aion/web/elm/src/Msgs.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ module Msgs exposing (..)

import Dom exposing (Error)
import Navigation exposing (Location)
import Panel.Models exposing (QuestionCreatedData)
import Panel.Models exposing (CategoryCreatedData, QuestionCreatedData)
import RemoteData exposing (WebData)
import Phoenix.Socket
import Json.Encode as Encode
Expand All @@ -17,6 +17,7 @@ type Msg
| OnFetchRooms (WebData RoomsData)
| OnFetchCurrentUser (WebData CurrentUser)
| OnQuestionCreated (WebData QuestionCreatedData)
| OnCategoryCreated (WebData CategoryCreatedData)
| PhoenixMsg (Phoenix.Socket.Msg Msg)
| ReceiveUserList Encode.Value
| SetAnswer String
Expand All @@ -29,4 +30,6 @@ type Msg
| ReceiveUserJoined Encode.Value
| ToastyMsg (Toasty.Msg Toasty.Defaults.Toast)
| CreateNewQuestionWithAnswers
| CreateNewCategory
| UpdateQuestionForm String String
| UpdateCategoryForm String String
38 changes: 32 additions & 6 deletions aion/web/elm/src/Panel/Api.elm
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
module Panel.Api exposing (..)

import Forms
import General.Constants exposing (hostname)
import General.Constants exposing (createCategoryUrl, createQuestionUrl, hostname)
import General.Utils exposing (getSubjectIdByName)
import Http
import Msgs exposing (Msg)
import RemoteData exposing (WebData)
import Panel.Decoders exposing (questionCreatedDecoder)
import Panel.Decoders exposing (categoryCreatedDecoder, questionCreatedDecoder)
import Json.Encode as Encode
import Panel.Models exposing (QuestionForm)
import Panel.Models exposing (CategoryForm, QuestionForm)
import Room.Models exposing (RoomsData)


createQuestionUrl : String
createQuestionUrl =
hostname ++ "api/questions"
-- create question section


createQuestionWithAnswers : QuestionForm -> WebData RoomsData -> Cmd Msg
Expand Down Expand Up @@ -52,3 +50,31 @@ questionCreationEncoder form rooms =
payload
|> Encode.object
|> Http.jsonBody



-- create category section


createCategory : CategoryForm -> Cmd Msg
createCategory form =
Http.post createCategoryUrl (categoryCreationEncoder form) categoryCreatedDecoder
|> RemoteData.sendRequest
|> Cmd.map Msgs.OnCategoryCreated


categoryCreationEncoder : QuestionForm -> Http.Body
categoryCreationEncoder form =
let
categoryName =
Forms.formValue form "name"

questionContent =
[ ( "name", Encode.string categoryName ) ]

payload =
[ ( "subject", Encode.object questionContent ) ]
in
payload
|> Encode.object
|> Http.jsonBody
22 changes: 21 additions & 1 deletion aion/web/elm/src/Panel/Decoders.elm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ module Panel.Decoders exposing (..)

import Json.Decode as Decode exposing (field, map, null, oneOf)
import Json.Decode.Pipeline exposing (decode, required)
import Panel.Models exposing (QuestionCreatedContent, QuestionCreatedData)
import Panel.Models exposing (CategoryCreatedContent, CategoryCreatedData, QuestionCreatedContent, QuestionCreatedData)


-- question creation section


questionCreatedDecoder : Decode.Decoder QuestionCreatedData
Expand All @@ -18,3 +21,20 @@ questionCreatedContentDecoder =
|> required "image_name" (oneOf [ Decode.string, null "" ])
|> required "id" Decode.int
|> required "content" Decode.string



-- category creation section


categoryCreatedDecoder : Decode.Decoder CategoryCreatedData
categoryCreatedDecoder =
decode CategoryCreatedData
|> required "data" categoryCreatedContendDecoder


categoryCreatedContendDecoder : Decode.Decoder CategoryCreatedContent
categoryCreatedContendDecoder =
decode CategoryCreatedContent
|> required "id" Decode.int
|> required "name" Decode.string
35 changes: 34 additions & 1 deletion aion/web/elm/src/Panel/Models.elm
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
module Panel.Models exposing (..)

import Forms
import Panel.Validators exposing (answersValidations, questionValidations, subjectValidations)
import Panel.Validators exposing (answersValidations, categoryNameValidations, questionValidations, subjectValidations)


type alias PanelData =
{ questionForm : QuestionForm
, categoryForm : CategoryForm
}



-- question form section


type alias QuestionForm =
Forms.Form

Expand Down Expand Up @@ -36,3 +41,31 @@ type alias QuestionCreatedContent =
, id : Int
, content : String
}



-- category form section


type alias CategoryForm =
Forms.Form


categoryNamePossibleFields : List String
categoryNamePossibleFields =
[ "name" ]


categoryForm : List ( String, List Forms.FieldValidator )
categoryForm =
[ ( "name", categoryNameValidations ) ]


type alias CategoryCreatedData =
{ data : CategoryCreatedContent }


type alias CategoryCreatedContent =
{ id : Int
, name : String
}
22 changes: 22 additions & 0 deletions aion/web/elm/src/Panel/Notifications.elm
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import Msgs exposing (Msg(..))
import Toasty.Defaults


-- question form notifications


questionFormValidationErrorToast : ( Model, Cmd Msg ) -> ( Model, Cmd Msg )
questionFormValidationErrorToast =
addToast (Toasty.Defaults.Error "Error!" "Submission form is not valid!")
Expand All @@ -19,3 +22,22 @@ questionCreationErrorToast =
questionCreationSuccessfulToast : ( Model, Cmd Msg ) -> ( Model, Cmd Msg )
questionCreationSuccessfulToast =
addToast (Toasty.Defaults.Success "Success!" "Question created successfully.")



-- category form notifications


categoryFormValidationErrorToast : ( Model, Cmd Msg ) -> ( Model, Cmd Msg )
categoryFormValidationErrorToast =
addToast (Toasty.Defaults.Error "Error!" "Category submission form is not valid!")


categoryCreationErrorToast : ( Model, Cmd Msg ) -> ( Model, Cmd Msg )
categoryCreationErrorToast =
addToast (Toasty.Defaults.Error "Error!" "Failed to create a category.")


categoryCreationSuccessfulToast : ( Model, Cmd Msg ) -> ( Model, Cmd Msg )
categoryCreationSuccessfulToast =
addToast (Toasty.Defaults.Success "Success!" "Category created successfully.")
7 changes: 7 additions & 0 deletions aion/web/elm/src/Panel/Validators.elm
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ subjectValidations =
[ Forms.validateExistence ]


categoryNameValidations : List Forms.FieldValidator
categoryNameValidations =
[ Forms.validateExistence
, Forms.validateMaxLength 24
]


validateRegularExpression : String -> String -> Maybe String
validateRegularExpression regex string =
let
Expand Down
29 changes: 28 additions & 1 deletion aion/web/elm/src/Panel/View.elm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import General.Notifications exposing (toastsConfig)
import Html exposing (..)
import Html.Attributes exposing (placeholder, type_, value)
import Html.Events exposing (onClick, onInput, onWithOptions)
import Json.Decode
import Msgs exposing (Msg(..))
import RemoteData exposing (WebData)
import Room.Models exposing (RoomsData)
Expand All @@ -26,9 +25,19 @@ panelView model =
, input [ type_ "button", value "submit", onClick CreateNewQuestionWithAnswers ] []
, Toasty.view toastsConfig Toasty.Defaults.view ToastyMsg model.toasties
]
, h3 [] [ text "Create new category:" ]
, form []
[ categoryNameFormElement model.panelData.categoryForm
, input [ type_ "button", value "submit", onClick CreateNewCategory ] []
, Toasty.view toastsConfig Toasty.Defaults.view ToastyMsg model.toasties
]
]



-- question form section


questionFormElement : Forms.Form -> Html Msg
questionFormElement form =
div []
Expand Down Expand Up @@ -74,3 +83,21 @@ listRooms result =

_ ->
[]



-- category form section


categoryNameFormElement : Forms.Form -> Html Msg
categoryNameFormElement form =
div []
[ p [] [ text "Enter category name bellow, should be uppercase:" ]
, input
[ placeholder "for instance: History or Famous people"
, onInput (UpdateCategoryForm "name")
, value (Forms.formValue form "name")
]
[]
, small [] [ text (Forms.errorString form "name") ]
]
1 change: 0 additions & 1 deletion aion/web/elm/src/Room/Notifications.elm
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ module Room.Notifications exposing (..)
import General.Models exposing (Model)
import General.Notifications exposing (addToast)
import Msgs exposing (Msg(..))
import Toasty
import Toasty.Defaults


Expand Down
52 changes: 50 additions & 2 deletions aion/web/elm/src/Update.elm
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import General.Notifications exposing (toastsConfig)
import Json.Decode as Decode
import Json.Encode as Encode
import Msgs exposing (Msg(..))
import Panel.Api exposing (createQuestionWithAnswers)
import Panel.Models exposing (questionFormPossibleFields)
import Panel.Api exposing (createCategory, createQuestionWithAnswers)
import Panel.Models exposing (categoryNamePossibleFields, questionFormPossibleFields)
import Panel.Notifications exposing (..)
import RemoteData
import Room.Constants exposing (answerInputFieldId, enterKeyCode)
Expand Down Expand Up @@ -52,6 +52,24 @@ update msg model =
_ ->
questionCreationErrorToast (model ! [])

OnCategoryCreated response ->
case response of
RemoteData.Success responseData ->
let
oldPanelData =
model.panelData

oldCategoryForm =
model.panelData.categoryForm

newCategoryForm =
Forms.updateFormInput oldCategoryForm "name" ""
in
categoryCreationSuccessfulToast ({ model | panelData = { oldPanelData | categoryForm = newCategoryForm } } ! [])

_ ->
categoryCreationErrorToast (model ! [])

OnLocationChange location ->
let
newRoute =
Expand Down Expand Up @@ -191,6 +209,20 @@ update msg model =
}
! []

UpdateCategoryForm name value ->
let
oldPanelData =
model.panelData

categoryForm =
oldPanelData.categoryForm
in
{ model
| panelData =
{ oldPanelData | categoryForm = Forms.updateFormInput categoryForm name value }
}
! []

CreateNewQuestionWithAnswers ->
let
questionForm =
Expand All @@ -207,6 +239,22 @@ update msg model =
else
questionFormValidationErrorToast (model ! [])

CreateNewCategory ->
let
categoryForm =
model.panelData.categoryForm

validationErrors =
categoryNamePossibleFields
|> List.map (\name -> Forms.errorList categoryForm name)
|> List.foldr (++) []
|> List.filter (\validations -> validations /= Nothing)
in
if List.isEmpty validationErrors then
( model, createCategory model.panelData.categoryForm )
else
categoryFormValidationErrorToast (model ! [])

ToastyMsg subMsg ->
Toasty.update toastsConfig ToastyMsg subMsg model

Expand Down