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
, original : String
, alias : String
, lang : String
, website : String
, lWikidata : Maybe Int
, desc : TP.Model
, rel : List GPE.RecvRelations
, relSearch : A.Model GApi.ApiProducerResult
, id : Maybe Int
, 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 }
, ptype = d.ptype
, name = d.name
, original = d.original
, alias = d.alias
, lang = d.lang
, website = d.website
, lWikidata = d.l_wikidata
, desc = TP.bbcode d.desc
, 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
, original = model.original
, alias = model.alias
, lang = model.lang
, website = model.website
, l_wikidata = model.lWikidata
, desc = model.desc.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
| Original 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)
Original s -> ({ model | original = 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.desc in ({ model | desc = 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, original = p.original, relation = "old" }] }, c)
DupSubmit ->
if List.isEmpty model.dupProds
then ({ model | state = Api.Loading }, GP.send { hidden = True, search = model.name :: model.original :: 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 /= "" && model.name == model.original)
|| hasDuplicates (List.map (\p -> p.pid) model.rel)
)
view : Model -> Html Msg
view model =
let
titles =
[ formField "name::Name (romaji)" [ inputText "name" model.name Name (style "width" "500px" :: GPE.valName) ]
, formField "original::Original name"
[ inputText "original" model.original Original (style "width" "500px" :: GPE.valOriginal)
, if model.name /= "" && model.name == model.original
then b [ class "standout" ] [ br [] [], text "Should not be the same as the Name (romaji). Leave blank is the original name is already in the latin alphabet" ]
else if model.original /= "" && String.toLower model.name /= String.toLower model.original && not (containsNonLatin model.original)
then b [ class "standout" ] [ br [] [], text "Original name does not seem to contain any non-latin characters. Leave this field empty if the name is already in the latin alphabet" ]
else text ""
]
, formField "alias::Aliases"
[ inputTextArea "alias" model.alias Alias (rows 3 :: GPE.valAlias)
, br [] []
, if hasDuplicates <| String.lines <| String.toLower model.alias
then b [ class "standout" ] [ 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 [] GT.languages ]
, 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.desc Desc 600 (style "height" "180px" :: GPE.valDesc) [ b [ class "standout" ] [ 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 [ style "text-align" "right" ] [ b [ class "grayedout" ] [ text <| "p" ++ String.fromInt p.pid ++ ":" ] ]
, td [ style "text-align" "right"] [ a [ href <| "/p" ++ String.fromInt p.pid ] [ text p.name ] ]
, td []
[ text "is an "
, inputSelect "" p.relation (RelRel i) [] GT.producerRelations
, text " of this producer"
]
, td [] [ inputButton "remove" (RelDel i) [] ]
]
) model.rel
, A.view prodConfig model.relSearch [placeholder "Add Producer..."]
]
]
newform () =
form_ DupSubmit (model.state == Api.Loading)
[ div [ class "mainbox" ] [ h1 [] [ text "Add a new producer" ], table [ class "formtable" ] titles ]
, div [ class "mainbox" ]
[ if List.isEmpty model.dupProds then text "" else
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" ++ String.fromInt p.id ] [ text p.name ]
, if p.hidden then b [ class "standout" ] [ text " (deleted)" ] else text ""
]
) model.dupProds
]
, fieldset [ class "submit" ] [ submitButton (if List.isEmpty model.dupProds then "Continue" else "Continue anyway") model.state (isValid model) ]
]
]
fullform () =
form_ Submit (model.state == Api.Loading)
[ div [ class "mainbox" ] [ h1 [] [ text "Edit producer" ], table [ class "formtable" ] geninfo ]
, div [ class "mainbox" ] [ fieldset [ 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 ()