module ProducerEdit exposing (main) import Html exposing (..) import Html.Events exposing (..) import Html.Attributes exposing (..) import Browser import Browser.Navigation exposing (load) import Lib.Util exposing (..) import Lib.Html exposing (..) import Lib.TextPreview as TP import Lib.Autocomplete as A import Lib.Api as Api import Lib.Editsum as Editsum import Gen.Producers as GP import Gen.ProducerEdit as GPE import Gen.Types as GT import Gen.Api as GApi main : Program GPE.Recv Model Msg main = Browser.element { init = \e -> (init e, Cmd.none) , view = view , update = update , subscriptions = always Sub.none } type alias Model = { state : Api.State , editsum : Editsum.Model , ptype : String , name : String , latin : Maybe String , alias : String , lang : String , website : String , lWikidata : Maybe Int , description : TP.Model , rel : List GPE.RecvRelations , relSearch : A.Model GApi.ApiProducerResult , id : Maybe String , dupCheck : Bool , dupProds : List GApi.ApiProducerResult } init : GPE.Recv -> Model init d = { state = Api.Normal , editsum = { authmod = d.authmod, editsum = TP.bbcode d.editsum, locked = d.locked, hidden = d.hidden, hasawait = False } , ptype = d.ptype , name = d.name , latin = d.latin , alias = d.alias , lang = d.lang , website = d.website , lWikidata = d.l_wikidata , description = TP.bbcode d.description , rel = d.relations , relSearch = A.init "" , id = d.id , dupCheck = False , dupProds = [] } encode : Model -> GPE.Send encode model = { id = model.id , editsum = model.editsum.editsum.data , hidden = model.editsum.hidden , locked = model.editsum.locked , ptype = model.ptype , name = model.name , latin = model.latin , alias = model.alias , lang = model.lang , website = model.website , l_wikidata = model.lWikidata , description = model.description.data , relations = List.map (\p -> { pid = p.pid, relation = p.relation }) model.rel } prodConfig : A.Config Msg GApi.ApiProducerResult prodConfig = { wrap = RelSearch, id = "relationadd", source = A.producerSource } type Msg = Editsum Editsum.Msg | Submit | Submitted GApi.Response | PType String | Name String | Latin String | Alias String | Lang String | Website String | LWikidata (Maybe Int) | Desc TP.Msg | RelDel Int | RelRel Int String | RelSearch (A.Msg GApi.ApiProducerResult) | DupSubmit | DupResults GApi.Response update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of Editsum m -> let (nm,nc) = Editsum.update m model.editsum in ({ model | editsum = nm }, Cmd.map Editsum nc) PType s -> ({ model | ptype = s }, Cmd.none) Name s -> ({ model | name = s, dupProds = [] }, Cmd.none) Latin s -> ({ model | latin = if s == "" then Nothing else Just s, dupProds = [] }, Cmd.none) Alias s -> ({ model | alias = s, dupProds = [] }, Cmd.none) Lang s -> ({ model | lang = s }, Cmd.none) Website s -> ({ model | website = s }, Cmd.none) LWikidata n-> ({ model | lWikidata = n }, Cmd.none) Desc m -> let (nm,nc) = TP.update m model.description in ({ model | description = nm }, Cmd.map Desc nc) RelDel idx -> ({ model | rel = delidx idx model.rel }, Cmd.none) RelRel idx rel -> ({ model | rel = modidx idx (\p -> { p | relation = rel }) model.rel }, Cmd.none) RelSearch m -> let (nm, c, res) = A.update prodConfig m model.relSearch in case res of Nothing -> ({ model | relSearch = nm }, c) Just p -> if List.any (\l -> l.pid == p.id) model.rel then ({ model | relSearch = A.clear nm "" }, c) else ({ model | relSearch = A.clear nm "", rel = model.rel ++ [{ pid = p.id, name = p.name, altname = p.altname, relation = "old" }] }, c) DupSubmit -> if List.isEmpty model.dupProds then ({ model | state = Api.Loading }, GP.send { search = model.name :: Maybe.withDefault "" model.latin :: String.lines model.alias } DupResults) else ({ model | dupCheck = True, dupProds = [] }, Cmd.none) DupResults (GApi.ProducerResult prods) -> if List.isEmpty prods then ({ model | state = Api.Normal, dupCheck = True, dupProds = [] }, Cmd.none) else ({ model | state = Api.Normal, dupProds = prods }, Cmd.none) DupResults r -> ({ model | state = Api.Error r }, Cmd.none) Submit -> ({ model | state = Api.Loading }, GPE.send (encode model) Submitted) Submitted (GApi.Redirect s) -> (model, load s) Submitted r -> ({ model | state = Api.Error r }, Cmd.none) isValid : Model -> Bool isValid model = not ( (model.name /= "" && Just model.name == model.latin) || hasDuplicates (List.map (\p -> p.pid) model.rel) ) view : Model -> Html Msg view model = let titles = [ formField "name::Name (original)" [ inputText "name" model.name Name (style "width" "500px" :: GPE.valName) ] , if not (model.latin /= Nothing || containsNonLatin model.name) then text "" else formField "latin::Name (latin)" [ inputText "latin" (Maybe.withDefault "" model.latin) Latin (style "width" "500px" :: placeholder "Romanization" :: GPE.valLatin) , case model.latin of Just s -> if containsNonLatin s then b [] [ br [] [], text "Romanization should only consist of characters in the latin alphabet." ] else text "" Nothing -> text "" ] , formField "alias::Aliases" [ inputTextArea "alias" model.alias Alias (rows 3 :: GPE.valAlias) , br [] [] , if hasDuplicates <| String.lines <| String.toLower model.alias then b [] [ text "List contains duplicate aliases.", br [] [] ] else text "" , text "(Un)official aliases, separated by a newline." ] ] geninfo = [ formField "ptype::Type" [ inputSelect "ptype" model.ptype PType [] GT.producerTypes ] ] ++ titles ++ [ formField "lang::Primary language" [ inputSelect "lang" model.lang Lang [] locLangs ] , formField "website::Website" [ inputText "website" model.website Website GPE.valWebsite ] , formField "l_wikidata::Wikidata ID" [ inputWikidata "l_wikidata" model.lWikidata LWikidata [] ] , formField "desc::Description" [ TP.view "desc" model.description Desc 600 (style "height" "180px" :: GPE.valDescription) [ b [] [ text "English please!" ] ] ] , tr [ class "newpart" ] [ td [ colspan 2 ] [ text "Database relations" ] ] , formField "Related producers" [ if List.isEmpty model.rel then text "" else table [] <| List.indexedMap (\i p -> tr [] [ td [] [ inputSelect "" p.relation (RelRel i) [] GT.producerRelations ] , td [] [ small [] [ text <| p.pid ++ ": " ], a [ href <| "/" ++ p.pid, title (Maybe.withDefault "" p.altname) ] [ text p.name ] ] , td [] [ inputButton "remove" (RelDel i) [] ] ] ) model.rel , A.view prodConfig model.relSearch [placeholder "Add Producer..."] ] ] newform () = form_ "" DupSubmit (model.state == Api.Loading) [ article [] [ h1 [] [ text "Add a new producer" ], table [ class "formtable" ] titles ] , if List.isEmpty model.dupProds then text "" else article [] [ div [] [ h1 [] [ text "Possible duplicates" ] , text "The following is a list of producers that match the name(s) you gave. " , text "Please check this list to avoid creating a duplicate producer entry. " , text "Be especially wary of items that have been deleted! To see why an entry has been deleted, click on its title." , ul [] <| List.map (\p -> li [] [ a [ href <| "/" ++ p.id ] [ text p.name ] ]) model.dupProds ] ] , article [ class "submit" ] [ submitButton (if List.isEmpty model.dupProds then "Continue" else "Continue anyway") model.state (isValid model) ] ] fullform () = form_ "" Submit (model.state == Api.Loading) [ article [] [ h1 [] [ text "Edit producer" ], table [ class "formtable" ] geninfo ] , article [ class "submit" ] [ Html.map Editsum (Editsum.view model.editsum) , submitButton "Submit" model.state (isValid model) ] ] in if model.id == Nothing && not model.dupCheck then newform () else fullform ()