{- Copyright 2020 Docspell Contributors SPDX-License-Identifier: GPL-3.0-or-later -} module Comp.PersonForm exposing ( Model , Msg(..) , emptyModel , getPerson , isValid , update , view2 ) import Api.Model.IdName exposing (IdName) import Api.Model.Person exposing (Person) import Comp.AddressForm import Comp.Basic as B import Comp.ContactField import Comp.Dropdown import Comp.FixedDropdown import Data.DropdownStyle as DS import Data.Flags exposing (Flags) import Data.PersonUse exposing (PersonUse) import Data.UiSettings exposing (UiSettings) import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (onInput) import Messages.Comp.PersonForm exposing (Texts) import Styles as S type alias Model = { person : Person , name : String , addressModel : Comp.AddressForm.Model , contactModel : Comp.ContactField.Model , notes : Maybe String , use : PersonUse , useModel : Comp.FixedDropdown.Model PersonUse , orgModel : Comp.Dropdown.Model IdName } emptyModel : Model emptyModel = { person = Api.Model.Person.empty , name = "" , addressModel = Comp.AddressForm.emptyModel , contactModel = Comp.ContactField.emptyModel , notes = Nothing , use = Data.PersonUse.Both , useModel = Comp.FixedDropdown.init Data.PersonUse.all , orgModel = Comp.Dropdown.makeSingle } isValid : Model -> Bool isValid model = model.name /= "" getPerson : Model -> Person getPerson model = let person = model.person org = Comp.Dropdown.getSelected model.orgModel |> List.head in { person | name = model.name , address = Comp.AddressForm.getAddress model.addressModel , contacts = Comp.ContactField.getContacts model.contactModel , notes = model.notes , use = Data.PersonUse.asString model.use , organization = org } type Msg = SetName String | SetPerson Person | AddressMsg Comp.AddressForm.Msg | ContactMsg Comp.ContactField.Msg | SetNotes String | SetOrgs (List IdName) | OrgDropdownMsg (Comp.Dropdown.Msg IdName) | UseDropdownMsg (Comp.FixedDropdown.Msg PersonUse) update : Flags -> Msg -> Model -> ( Model, Cmd Msg ) update flags msg model = case msg of SetPerson t -> let ( m1, c1 ) = update flags (AddressMsg (Comp.AddressForm.SetAddress t.address)) model ( m2, c2 ) = update flags (ContactMsg (Comp.ContactField.SetItems t.contacts)) m1 ( m3, c3 ) = update flags (OrgDropdownMsg (Comp.Dropdown.SetSelection (List.filterMap identity [ t.organization ]) ) ) m2 in ( { m3 | person = t , name = t.name , notes = t.notes , use = Data.PersonUse.fromString t.use |> Maybe.withDefault Data.PersonUse.Both } , Cmd.batch [ c1, c2, c3 ] ) SetOrgs orgs -> let opts = Comp.Dropdown.SetOptions orgs in update flags (OrgDropdownMsg opts) model AddressMsg am -> let ( m1, c1 ) = Comp.AddressForm.update am model.addressModel in ( { model | addressModel = m1 }, Cmd.map AddressMsg c1 ) ContactMsg m -> let ( m1, c1 ) = Comp.ContactField.update m model.contactModel in ( { model | contactModel = m1 }, Cmd.map ContactMsg c1 ) SetName n -> ( { model | name = n }, Cmd.none ) SetNotes str -> ( { model | notes = if str == "" then Nothing else Just str } , Cmd.none ) UseDropdownMsg lm -> let ( nm, mu ) = Comp.FixedDropdown.update lm model.useModel newUse = Maybe.withDefault model.use mu in ( { model | useModel = nm, use = newUse }, Cmd.none ) OrgDropdownMsg lm -> let ( dm_, cmd_ ) = Comp.Dropdown.update lm model.orgModel in ( { model | orgModel = dm_ } , Cmd.map OrgDropdownMsg cmd_ ) --- View2 view2 : Texts -> Bool -> UiSettings -> Model -> Html Msg view2 texts mobile settings model = let personUseCfg = { display = texts.personUseLabel , icon = \_ -> Nothing , style = DS.mainStyle , selectPlaceholder = texts.basics.selectPlaceholder } contactCfg = { mobile = mobile , contactTypeLabel = texts.contactTypeLabel , editLabel = texts.basics.edit , selectPlaceholder = texts.basics.selectPlaceholder } in div [ class "flex flex-col" ] [ div [ class "mb-4" ] [ label [ class S.inputLabel , for "personname" ] [ text texts.basics.name , B.inputRequired ] , input [ type_ "text" , onInput SetName , placeholder texts.basics.name , value model.name , class S.textInput , classList [ ( S.inputErrorBorder, not (isValid model) ) ] , name "personname" ] [] ] , div [ class "mb-4" ] [ label [ class S.inputLabel ] [ text texts.useOfPerson ] , Html.map UseDropdownMsg (Comp.FixedDropdown.viewStyled2 personUseCfg False (Just model.use) model.useModel) , span [ class "opacity-50 text-sm" ] [ case model.use of Data.PersonUse.Concerning -> text texts.useAsConcerningOnly Data.PersonUse.Correspondent -> text texts.useAsCorrespondentOnly Data.PersonUse.Both -> text texts.useAsBoth Data.PersonUse.Disabled -> text texts.dontUseForSuggestions ] ] , div [ class "mb-4" ] [ label [ class S.inputLabel ] [ text texts.basics.organization ] , Html.map OrgDropdownMsg (Comp.Dropdown.view2 (Comp.Dropdown.orgFormViewSettings texts.chooseAnOrg DS.mainStyle) settings model.orgModel ) ] , div [ class "mb-4" ] [ h3 [ class "ui dividing header" ] [ text texts.address ] , Html.map AddressMsg (Comp.AddressForm.view2 texts.addressForm settings model.addressModel ) ] , div [ class "mb-4" ] [ h3 [ class S.header3 ] [ text texts.contacts ] , Html.map ContactMsg (Comp.ContactField.view2 contactCfg settings model.contactModel) ] , div [ class "mb-4" ] [ h3 [ class S.header3 ] [ text texts.notes ] , div [ class "" ] [ textarea [ onInput SetNotes , Maybe.withDefault "" model.notes |> value , class S.textAreaInput ] [] ] ] ]