update frontend to allow creating tasks.
This commit is contained in:
parent
637a246caa
commit
d2dfbb9a4a
|
@ -2,9 +2,12 @@ module Dashboard exposing (Model, Msg, Task, init, update, view)
|
||||||
|
|
||||||
import Browser exposing (Document)
|
import Browser exposing (Document)
|
||||||
import Browser.Navigation as Nav
|
import Browser.Navigation as Nav
|
||||||
import Html exposing (Html, div, text)
|
import Html exposing (Html, button, div, input, text, textarea)
|
||||||
|
import Html.Attributes exposing (placeholder, value)
|
||||||
|
import Html.Events exposing (onClick, onInput)
|
||||||
import Http
|
import Http
|
||||||
import Json.Decode exposing (Decoder, field, int, list, map3, maybe, string)
|
import Json.Decode exposing (Decoder, field, int, list, map3, maybe, string)
|
||||||
|
import Json.Encode as Encode
|
||||||
|
|
||||||
|
|
||||||
type alias Task =
|
type alias Task =
|
||||||
|
@ -14,9 +17,22 @@ type alias Task =
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type alias CreateTaskInfo =
|
||||||
|
{ title : String, description : String }
|
||||||
|
|
||||||
|
|
||||||
|
defaultCreateTask : CreateTaskInfo
|
||||||
|
defaultCreateTask =
|
||||||
|
{ title = ""
|
||||||
|
, description = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
{ navKey : Nav.Key
|
{ navKey : Nav.Key
|
||||||
, tasks : Status (List Task)
|
, tasks : Status (List Task)
|
||||||
|
, createTaskCollapsed : Bool
|
||||||
|
, createTask : CreateTaskInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,16 +44,21 @@ type Status a
|
||||||
|
|
||||||
init : Nav.Key -> ( Model, Cmd Msg )
|
init : Nav.Key -> ( Model, Cmd Msg )
|
||||||
init navKey =
|
init navKey =
|
||||||
( Model navKey Loading
|
( Model navKey Loading True defaultCreateTask
|
||||||
, Http.get
|
, Http.get
|
||||||
{ url = "http://localhost:3000/tasks"
|
{ url = "http://localhost:3000/tasks"
|
||||||
, expect = Http.expectJson GotTasks taskDecoder
|
, expect = Http.expectJson GotTasks (list taskDecoder)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
type Msg
|
||||||
= GotTasks (Result Http.Error (List Task))
|
= GotTasks (Result Http.Error (List Task))
|
||||||
|
| ToggleCreateTask
|
||||||
|
| CreateTask
|
||||||
|
| GotTaskCreated (Result Http.Error Task)
|
||||||
|
| CreateTaskUpdateTitle String
|
||||||
|
| CreateTaskUpdateDescription String
|
||||||
|
|
||||||
|
|
||||||
update : Msg -> Model -> ( Model, Cmd Msg )
|
update : Msg -> Model -> ( Model, Cmd Msg )
|
||||||
|
@ -51,21 +72,68 @@ update msg model =
|
||||||
Err _ ->
|
Err _ ->
|
||||||
( { model | tasks = Failure }, Cmd.none )
|
( { model | tasks = Failure }, Cmd.none )
|
||||||
|
|
||||||
|
ToggleCreateTask ->
|
||||||
|
( { model | createTaskCollapsed = not model.createTaskCollapsed }
|
||||||
|
, Cmd.none
|
||||||
|
)
|
||||||
|
|
||||||
taskDecoder : Decoder (List Task)
|
CreateTask ->
|
||||||
|
( model
|
||||||
|
, Http.post
|
||||||
|
{ url = "http://localhost:3000/tasks"
|
||||||
|
, body = Http.jsonBody (taskEncoder model.createTask)
|
||||||
|
, expect = Http.expectJson GotTaskCreated taskDecoder
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
GotTaskCreated result ->
|
||||||
|
case result of
|
||||||
|
Ok task ->
|
||||||
|
case model.tasks of
|
||||||
|
Success tasks ->
|
||||||
|
( { model | tasks = Success (task :: tasks) }, Cmd.none )
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
( { model | tasks = Success [ task ] }, Cmd.none )
|
||||||
|
|
||||||
|
Err _ ->
|
||||||
|
( model, Cmd.none )
|
||||||
|
|
||||||
|
CreateTaskUpdateTitle title ->
|
||||||
|
let
|
||||||
|
createTask =
|
||||||
|
model.createTask
|
||||||
|
in
|
||||||
|
( { model | createTask = { createTask | title = title } }, Cmd.none )
|
||||||
|
|
||||||
|
CreateTaskUpdateDescription description ->
|
||||||
|
let
|
||||||
|
createTask =
|
||||||
|
model.createTask
|
||||||
|
in
|
||||||
|
( { model | createTask = { createTask | description = description } }, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
|
taskDecoder : Decoder Task
|
||||||
taskDecoder =
|
taskDecoder =
|
||||||
list
|
map3 Task
|
||||||
(map3 Task
|
(field "id" int)
|
||||||
(field "id" int)
|
(field "title" string)
|
||||||
(field "title" string)
|
(maybe
|
||||||
(maybe
|
(field "description"
|
||||||
(field "description"
|
string
|
||||||
string
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
taskEncoder : CreateTaskInfo -> Encode.Value
|
||||||
|
taskEncoder task =
|
||||||
|
Encode.object
|
||||||
|
[ ( "title", Encode.string task.title )
|
||||||
|
, ( "description", Encode.string task.description )
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
view : Model -> Document Msg
|
view : Model -> Document Msg
|
||||||
view model =
|
view model =
|
||||||
{ title = "Dashboard"
|
{ title = "Dashboard"
|
||||||
|
@ -83,4 +151,38 @@ viewBody model =
|
||||||
div [] [ text "Loading" ]
|
div [] [ text "Loading" ]
|
||||||
|
|
||||||
Success tasks ->
|
Success tasks ->
|
||||||
div [] [ text ("Loaded " ++ String.fromInt (List.length tasks) ++ " tasks") ]
|
div []
|
||||||
|
[ text ("Loaded " ++ String.fromInt (List.length tasks) ++ "tasks")
|
||||||
|
, viewCreate model
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
viewCreate : Model -> Html Msg
|
||||||
|
viewCreate model =
|
||||||
|
if model.createTaskCollapsed then
|
||||||
|
div [] [ button [ onClick ToggleCreateTask ] [ text "+ Expand" ] ]
|
||||||
|
|
||||||
|
else
|
||||||
|
div []
|
||||||
|
[ button [ onClick ToggleCreateTask ] [ text "- Collapse" ]
|
||||||
|
, div []
|
||||||
|
[ input
|
||||||
|
[ placeholder "Task Title"
|
||||||
|
, value
|
||||||
|
model.createTask.title
|
||||||
|
, onInput CreateTaskUpdateTitle
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
, div []
|
||||||
|
[ textarea
|
||||||
|
[ placeholder "Task Description"
|
||||||
|
, value
|
||||||
|
model.createTask.description
|
||||||
|
, onInput CreateTaskUpdateDescription
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
, div []
|
||||||
|
[ button [ onClick CreateTask ] [ text "Create Task" ] ]
|
||||||
|
]
|
||||||
|
|
Loading…
Reference in New Issue