port module UList.Opt exposing (main)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Task
import Process
import Browser
import Date
import Dict exposing (Dict)
import Lib.Util exposing (..)
import Lib.Html exposing (..)
import Lib.Api as Api
import Lib.RDate as RDate
import Lib.DropDown as DD
import UList.ReleaseEdit as RE
import Gen.Types as T
import Gen.Api as GApi
import Gen.UListVNNotes as GVN
import Gen.UListDel as GDE
import Gen.Release as GR
main : Program GVN.Recv Model Msg
main = Browser.element
{ init = \f -> (init f, Date.today |> Task.perform Today)
, subscriptions = \model -> List.map (\r -> Sub.map (Rel r.rid) (DD.sub r.dd)) model.rels |> Sub.batch
, view = view
, update = update
}
port ulistVNDeleted : Bool -> Cmd msg
port ulistNotesChanged : String -> Cmd msg
port ulistRelChanged : (Int, Int) -> Cmd msg
type alias Model =
{ flags : GVN.Recv
, today : Date.Date
, del : Bool
, delState : Api.State
, notes : String
, notesRev : Int
, notesState : Api.State
, rels : List RE.Model
, relNfo : Dict String GApi.ApiReleases
, relOptions : Maybe (List (String, String))
, relState : Api.State
}
init : GVN.Recv -> Model
init f =
{ flags = f
, today = Date.fromOrdinalDate 2100 1
, del = False
, delState = Api.Normal
, notes = f.notes
, notesRev = 0
, notesState = Api.Normal
, rels = List.map2 (\st nfo -> RE.init f.vid { uid = f.uid, rid = nfo.id, status = Just st, empty = "" }) f.relstatus f.rels
, relNfo = Dict.fromList <| List.map (\r -> (r.id, r)) f.rels
, relOptions = Nothing
, relState = Api.Normal
}
type Msg
= Today Date.Date
| Del Bool
| Delete
| Deleted GApi.Response
| Notes String
| NotesSave Int
| NotesSaved Int GApi.Response
| Rel String RE.Msg
| RelLoad
| RelLoaded GApi.Response
| RelAdd String
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Today d -> ({ model | today = d }, Cmd.none)
Del b -> ({ model | del = b }, Cmd.none)
Delete ->
( { model | delState = Api.Loading }
, GDE.send { uid = model.flags.uid, vid = model.flags.vid } Deleted)
Deleted GApi.Success -> (model, ulistVNDeleted True)
Deleted e -> ({ model | delState = Api.Error e }, Cmd.none)
Notes s ->
( { model | notes = s, notesRev = model.notesRev + 1 }
, Task.perform (\_ -> NotesSave (model.notesRev+1)) <| Process.sleep 1000)
NotesSave rev ->
if rev /= model.notesRev || model.notes == model.flags.notes
then (model, Cmd.none)
else ( { model | notesState = Api.Loading }
, GVN.send { uid = model.flags.uid, vid = model.flags.vid, notes = model.notes } (NotesSaved rev))
NotesSaved rev GApi.Success ->
let f = model.flags
nf = { f | notes = model.notes }
in if model.notesRev /= rev
then (model, Cmd.none)
else ({model | flags = nf, notesState = Api.Normal }, ulistNotesChanged model.notes)
NotesSaved _ e -> ({ model | notesState = Api.Error e }, Cmd.none)
Rel rid m ->
case List.filterMap (\r -> if r.rid == rid then Just (RE.update m r) else Nothing) model.rels |> List.head of
Nothing -> (model, Cmd.none)
Just (rm, rc) ->
let
nr = if rm.state == Api.Normal && rm.status == Nothing
then List.filter (\r -> r.rid /= rid) model.rels
else List.map (\r -> if r.rid == rid then rm else r) model.rels
nm = { model | rels = nr }
nc = Cmd.batch
[ Cmd.map (Rel rid) rc
, ulistRelChanged (List.length <| List.filter (\r -> r.status == Just 2) nr, List.length nr) ]
in (nm, nc)
RelLoad ->
( { model | relState = Api.Loading }
, GR.send { vid = model.flags.vid } RelLoaded )
RelLoaded (GApi.Releases rels) ->
( { model
| relState = Api.Normal
, relNfo = Dict.union (Dict.fromList <| List.map (\r -> (r.id, r)) rels) model.relNfo
, relOptions = Just <| List.map (\r -> (r.id, RDate.showrel r)) rels
}, Cmd.none)
RelLoaded e -> ({ model | relState = Api.Error e }, Cmd.none)
RelAdd rid ->
( { model | rels = model.rels ++ (if rid == "" then [] else [RE.init model.flags.vid { rid = rid, uid = model.flags.uid, status = Just 2, empty = "" }]) }
, Task.perform (always <| Rel rid <| RE.Set (Just 2) True) <| Task.succeed True)
view : Model -> Html Msg
view model =
let
opt =
[ tr []
[ td [ colspan 5 ]
[ textarea (
[ placeholder "Notes", rows 2, cols 80
, onInput Notes, onBlur (NotesSave model.notesRev)
] ++ GVN.valNotes
) [ text model.notes ]
, div [ ] <|
[ div [ class "spinner", classList [("hidden", model.notesState /= Api.Loading)] ] []
, a [ href "#", onClickD (Del True) ] [ text "Remove VN" ]
] ++ (
if model.relOptions == Nothing
then [ text " | ", a [ href "#", onClickD RelLoad ] [ text "Add release" ] ]
else []
) ++ (
case model.notesState of
Api.Error e -> [ br [] [], b [] [ text <| Api.showResponse e ] ]
_ -> []
)
]
]
, if model.relOptions == Nothing && model.relState == Api.Normal
then text ""
else tfoot []
[ tr []
[ td [ colspan 5 ] <|
-- TODO: This