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 ()