-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathMain.elm
153 lines (111 loc) · 3.32 KB
/
Main.elm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
module Main exposing (..)
import Debug exposing (..)
import Dict exposing (..)
import Html exposing (..)
import Html.App exposing (program)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http
import Task exposing (Task, perform)
import Api exposing (..)
main : Program Never
main =
program
{ init = init
, update = update
, subscriptions = \_ -> Sub.none
, view = view
}
-- MODEL
type alias Model =
{ items : Dict Int Item
, addItemInput : String
, error : Maybe String
}
type alias ItemId =
Int
init : ( Model, Cmd Msg )
init =
let
fetch =
toServer Initial Api.getApiItem
state =
{ items = empty, addItemInput = "", error = Nothing }
in
( state, fetch )
-- UPDATE
type Msg
= FromServer FromServer
| FromUi FromUi
| Error String
type FromServer
= Initial (List ItemId)
| NewItem Item
| Delete ItemId
type FromUi
= AddItemInputChange String
| AddItemButton
| Done ItemId
update : Msg -> Model -> ( Model, Cmd Msg )
update message s =
case message of
FromServer fromServer ->
case fromServer of
Initial itemIds ->
let
cmd : Cmd Msg
cmd =
Cmd.batch
<| List.map (toServer NewItem << getApiItemByItemId) itemIds
in
( s, cmd )
NewItem item ->
{ s | items = insert item.id item s.items } ! []
Delete id ->
{ s | items = remove id s.items } ! []
FromUi fromUi ->
case fromUi of
AddItemButton ->
let
new =
s.addItemInput
cmd =
toServer (\id -> NewItem (Item id new)) (postApiItem new)
newState =
{ s | addItemInput = "" }
in
if new == "" then
update (Error "empty field") s
else
( newState, cmd )
AddItemInputChange t ->
{ s | addItemInput = t } ! []
Done id ->
let
cmd =
toServer (always (Delete id)) (deleteApiItemByItemId id)
in
( s, cmd )
Error msg ->
( { s | error = Just msg }, Cmd.none )
toServer : (a -> FromServer) -> Task Http.Error a -> Cmd Msg
toServer tag task =
perform (Error << toString) (FromServer << tag) task
-- VIEW
view : Model -> Html Msg
view state =
div []
<| [ text (toString state)
, br [] []
]
++ (List.map (viewItem << snd) (toList state.items))
++ [ input [ onInput (FromUi << AddItemInputChange) ] []
, button [ onClick (FromUi AddItemButton) ] [ text "add item" ]
]
viewItem : Item -> Html Msg
viewItem item =
div []
<| [ text (item.text)
, text " - "
, button [ onClick (FromUi <| Done item.id) ] [ text "done" ]
]