diff options
Diffstat (limited to 'elm/ProducerEdit.elm')
-rw-r--r-- | elm/ProducerEdit.elm | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/elm/ProducerEdit.elm b/elm/ProducerEdit.elm new file mode 100644 index 00000000..f301d20c --- /dev/null +++ b/elm/ProducerEdit.elm @@ -0,0 +1,231 @@ +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" }] }, Cmd.none) + + 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 () |