module StaffEdit 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.Api as Api import Lib.Editsum as Editsum import Gen.StaffEdit as GSE import Gen.Staff as GS import Gen.Types as GT import Gen.Api as GApi main : Program GSE.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 , alias : List GSE.RecvAlias , aliasDup : Bool , aid : Int , description : TP.Model , gender : String , lang : String , l_site : String , l_wikidata : Maybe Int , l_twitter : String , l_anidb : Maybe Int , l_pixiv : Int , id : Maybe String , dupCheck : Bool , dupStaff : List GApi.ApiStaffResult } init : GSE.Recv -> Model init d = { state = Api.Normal , editsum = { authmod = d.authmod, editsum = TP.bbcode d.editsum, locked = d.locked, hidden = d.hidden, hasawait = False } , alias = d.alias , aliasDup = False , aid = d.aid , description = TP.bbcode d.description , gender = d.gender , lang = d.lang , l_site = d.l_site , l_wikidata = d.l_wikidata , l_twitter = d.l_twitter , l_anidb = d.l_anidb , l_pixiv = d.l_pixiv , id = d.id , dupCheck = False , dupStaff = [] } encode : Model -> GSE.Send encode model = { id = model.id , editsum = model.editsum.editsum.data , hidden = model.editsum.hidden , locked = model.editsum.locked , aid = model.aid , alias = List.map (\e -> { aid = e.aid, name = e.name, latin = e.latin }) model.alias , description = model.description.data , gender = model.gender , lang = model.lang , l_site = model.l_site , l_wikidata = model.l_wikidata , l_twitter = model.l_twitter , l_anidb = model.l_anidb , l_pixiv = model.l_pixiv } newAid : Model -> Int newAid model = let id = Maybe.withDefault 0 <| List.minimum <| List.map .aid model.alias in if id >= 0 then -1 else id - 1 type Msg = Editsum Editsum.Msg | Submit | Submitted GApi.Response | Lang String | Gender String | Website String | LWikidata (Maybe Int) | LTwitter String | LAnidb String | LPixiv String | Desc TP.Msg | AliasDel Int | AliasName Int String | AliasLatin Int String | AliasMain Int Bool | AliasAdd | DupSubmit | DupResults GApi.Response validate : Model -> Model validate model = { model | aliasDup = hasDuplicates <| List.map (\e -> (e.name, Maybe.withDefault "" e.latin)) model.alias } 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) Lang s -> ({ model | lang = s }, Cmd.none) Gender s -> ({ model | gender = s }, Cmd.none) Website s -> ({ model | l_site = s }, Cmd.none) LWikidata n-> ({ model | l_wikidata= n }, Cmd.none) LTwitter s -> ({ model | l_twitter = s }, Cmd.none) LAnidb s -> ({ model | l_anidb = if s == "" then Nothing else String.toInt s }, Cmd.none) LPixiv s -> ({ model | l_pixiv = Maybe.withDefault 0 (String.toInt s) }, Cmd.none) Desc m -> let (nm,nc) = TP.update m model.description in ({ model | description = nm }, Cmd.map Desc nc) AliasDel i -> (validate { model | dupStaff = [], alias = delidx i model.alias }, Cmd.none) AliasName i s -> (validate { model | dupStaff = [], alias = modidx i (\e -> { e | name = s }) model.alias }, Cmd.none) AliasLatin i s-> (validate { model | dupStaff = [], alias = modidx i (\e -> { e | latin = if s == "" then Nothing else Just s }) model.alias }, Cmd.none) AliasMain n _ -> ({ model | aid = n }, Cmd.none) AliasAdd -> ({ model | alias = model.alias ++ [{ aid = newAid model, name = "", latin = Nothing, inuse = False, wantdel = False }] }, Cmd.none) DupSubmit -> if List.isEmpty model.dupStaff then ({ model | state = Api.Loading }, GS.send { search = List.concatMap (\e -> [e.name, Maybe.withDefault "" e.latin]) model.alias } DupResults) else ({ model | dupCheck = True, dupStaff = [] }, Cmd.none) DupResults (GApi.StaffResult staff) -> if List.isEmpty staff then ({ model | state = Api.Normal, dupCheck = True, dupStaff = [] }, Cmd.none) else ({ model | state = Api.Normal, dupStaff = staff }, Cmd.none) DupResults r -> ({ model | state = Api.Error r }, Cmd.none) Submit -> ({ model | state = Api.Loading }, GSE.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.aliasDup || List.any (\l -> Just l.name == l.latin) model.alias) view : Model -> Html Msg view model = let nameEntry n e = tr [] [ td [ class "tc_id" ] [ inputRadio "main" (e.aid == model.aid) (AliasMain e.aid) ] , td [ class "tc_name" ] [ inputText "" e.name (AliasName n) (placeholder "Name (original script)" :: GSE.valAliasName) ] , td [ class "tc_latin" ] <| if not (e.latin /= Nothing || containsNonLatin e.name) then [] else [ inputText "" (Maybe.withDefault "" e.latin) (AliasLatin n) (placeholder "Name (latin)" :: GSE.valAliasLatin) , case e.latin of Just s -> if containsNonLatin s then b [] [ text "Romanization should only consist of characters in the latin alphabet." ] else text "" Nothing -> text "" ] , td [ class "tc_add" ] [ if model.aid == e.aid then small [] [ text " primary" ] else if e.wantdel then b [] [ text " still referenced" ] else if e.inuse then small [] [ text " referenced" ] else inputButton "remove" (AliasDel n) [] ] ] names = table [ class "names" ] <| [ thead [] [ tr [] [ td [ class "tc_id" ] [] , td [ class "tc_name" ] [ text "Name (original script)" ] , td [ class "tc_latin" ] [ text "Romanization" ] , td [] [] ] ] ] ++ List.indexedMap nameEntry model.alias ++ [ tr [ class "alias_new" ] [ td [] [] , td [ colspan 3 ] [ if not model.aliasDup then text "" else b [] [ text "The list contains duplicate aliases.", br_ 1 ] , a [ onClick AliasAdd ] [ text "Add alias" ] ] ] ] newform () = form_ "" DupSubmit (model.state == Api.Loading) [ article [] [ h1 [] [ text "Add new staff" ] , table [ class "formtable" ] [ formField "Names" [ names, br_ 1 ] ] ] , if List.isEmpty model.dupStaff then text "" else article [] [ div [] [ h1 [] [ text "Possible duplicates" ] , text "The following is a list of staff that match the name(s) you gave. " , text "Please check this list to avoid creating a duplicate staff entry. " , ul [] <| List.map (\s -> li [] [ a [ href <| "/" ++ s.id, title (s.alttitle) ] [ text s.title ] ] ) model.dupStaff ] ] , article [ class "submit" ] [ submitButton (if List.isEmpty model.dupStaff then "Continue" else "Continue anyway") model.state (isValid model) ] ] fullform () = form_ "" Submit (model.state == Api.Loading) [ article [ class "staffedit" ] [ h1 [] [ text "General info" ] , table [ class "formtable" ] [ formField "Names" [ names, br_ 1 ] , formField "desc::Biography" [ TP.view "desc" model.description Desc 500 GSE.valDescription [ b [] [ text "English please!" ] ] ] , formField "gender::Gender" [ inputSelect "gender" model.gender Gender [] [ ("unknown", "Unknown or N/A") , ("f", "Female") , ("m", "Male") ] ] , formField "lang::Primary Language" [ inputSelect "lang" model.lang Lang [] locLangs ] , formField "l_site::Official page" [ inputText "l_site" model.l_site Website (style "width" "400px" :: GSE.valL_Site) ] , formField "l_wikidata::Wikidata ID" [ inputWikidata "l_wikidata" model.l_wikidata LWikidata [] ] , formField "l_twitter::Twitter username" [ inputText "l_twitter" model.l_twitter LTwitter GSE.valL_Twitter ] , formField "l_anidb::AniDB Creator ID" [ inputText "l_anidb" (Maybe.withDefault "" (Maybe.map String.fromInt model.l_anidb)) LAnidb GSE.valL_Anidb ] , formField "l_pixiv::Pixiv ID" [ inputText "l_pixiv" (if model.l_pixiv == 0 then "" else String.fromInt model.l_pixiv) LPixiv GSE.valL_Pixiv ] ] ] , 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 ()