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
|
module UList.DateEdit exposing (main)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Task
import Process
import Browser
import Regex
import Lib.Html exposing (..)
import Lib.Api as Api
import Gen.Api as GApi
import Gen.UListDateEdit as GDE
main : Program GDE.Send Model Msg
main = Browser.element
{ init = \f -> (init f, Cmd.none)
, subscriptions = always Sub.none
, view = view
, update = update
}
type alias Model =
{ state : Api.State
, flags : GDE.Send
, val : String
, valid : Bool
, debnum : Int -- Debounce for submit
, visible : Bool
}
init : GDE.Send -> Model
init f =
{ state = Api.Normal
, flags = f
, val = f.date
, valid = True
, debnum = 0
, visible = False
}
type Msg
= Show
| Val String Bool
| Save Int
| Saved GApi.Response
isDate : String -> Bool
isDate s
= Regex.fromString "^(?:19[7-9][0-9]|20[0-9][0-9])-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])$"
|> Maybe.map (\r -> Regex.contains r s) |> Maybe.withDefault True
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Show -> ({ model | visible = True }, Cmd.none)
Val s b ->
({ model | val = s, debnum = model.debnum + 1, valid = b && isDate s }
, Task.perform (\_ -> Save (model.debnum+1)) <| Process.sleep 300)
Save n ->
if n /= model.debnum || model.val == model.flags.date || not model.valid
then (model, Cmd.none)
else ( { model | state = Api.Loading, debnum = model.debnum+1 }
, Api.post "/u/ulist/setdate.json" (GDE.encode { uid = model.flags.uid, vid = model.flags.vid, start = model.flags.start, date = model.val }) Saved )
Saved GApi.Success ->
let f = model.flags
nf = { f | date = model.val }
in ({ model | state = Api.Normal, flags = nf }, Cmd.none)
Saved e -> ({ model | state = Api.Error e }, Cmd.none)
view : Model -> Html Msg
view model = div (class "compact" :: if model.visible then [] else [onMouseOver Show]) <|
case model.state of
Api.Loading -> [ span [ class "spinner" ] [] ]
Api.Error _ -> [ b [ class "standout" ] [ text "error" ] ] -- Argh
Api.Normal ->
[ if model.visible
then input ([ type_ "date", class "text", value model.val, onInputValidation Val, onBlur (Save model.debnum), placeholder "yyyy-mm-dd" ] ++ GDE.valDate) []
else text ""
, span [] [ text model.val ]
]
|