mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-08 07:59:51 +00:00
This drops fomantic-ui as css toolkit and introduces tailwindcss. With tailwind there are no predefined components, but it's very easy to create those. So customizing the look&feel is much simpler, most of the time no additional css is needed. This requires a complete rewrite of the markup + styles. Luckily all logic can be kept as is. The now old ui is not removed, it is still available by using a request header `Docspell-Ui` with a value of `1` for the old ui and `2` for the new ui. Another addition is "dev mode", where docspell serves assets with a no-cache header, to disable browser caching. This makes developing a lot easier.
287 lines
7.4 KiB
Elm
287 lines
7.4 KiB
Elm
module Comp.UserForm exposing
|
|
( Model
|
|
, Msg(..)
|
|
, emptyModel
|
|
, getUser
|
|
, isNewUser
|
|
, isValid
|
|
, update
|
|
, view
|
|
, view2
|
|
)
|
|
|
|
import Api.Model.User exposing (User)
|
|
import Comp.Basic as B
|
|
import Comp.Dropdown
|
|
import Data.DropdownStyle as DS
|
|
import Data.Flags exposing (Flags)
|
|
import Data.UiSettings exposing (UiSettings)
|
|
import Data.UserState exposing (UserState)
|
|
import Html exposing (..)
|
|
import Html.Attributes exposing (..)
|
|
import Html.Events exposing (onInput)
|
|
import Styles as S
|
|
import Util.Maybe
|
|
|
|
|
|
type alias Model =
|
|
{ user : User
|
|
, login : String
|
|
, email : Maybe String
|
|
, state : Comp.Dropdown.Model UserState
|
|
, password : Maybe String
|
|
}
|
|
|
|
|
|
emptyModel : Model
|
|
emptyModel =
|
|
{ user = Api.Model.User.empty
|
|
, login = ""
|
|
, email = Nothing
|
|
, password = Nothing
|
|
, state =
|
|
Comp.Dropdown.makeSingleList
|
|
{ makeOption =
|
|
\s ->
|
|
{ value = Data.UserState.toString s
|
|
, text = Data.UserState.toString s
|
|
, additional = ""
|
|
}
|
|
, placeholder = ""
|
|
, options = Data.UserState.all
|
|
, selected = List.head Data.UserState.all
|
|
}
|
|
}
|
|
|
|
|
|
isValid : Model -> Bool
|
|
isValid model =
|
|
if model.user.login == "" then
|
|
model.login /= "" && Util.Maybe.nonEmpty model.password
|
|
|
|
else
|
|
True
|
|
|
|
|
|
isNewUser : Model -> Bool
|
|
isNewUser model =
|
|
model.user.login == ""
|
|
|
|
|
|
getUser : Model -> User
|
|
getUser model =
|
|
let
|
|
s =
|
|
model.user
|
|
|
|
state =
|
|
Comp.Dropdown.getSelected model.state
|
|
|> List.head
|
|
|> Maybe.withDefault Data.UserState.Active
|
|
|> Data.UserState.toString
|
|
in
|
|
{ s
|
|
| login = model.login
|
|
, email = model.email
|
|
, state = state
|
|
, password = model.password
|
|
}
|
|
|
|
|
|
type Msg
|
|
= SetLogin String
|
|
| SetUser User
|
|
| SetEmail String
|
|
| StateMsg (Comp.Dropdown.Msg UserState)
|
|
| SetPassword String
|
|
|
|
|
|
update : Flags -> Msg -> Model -> ( Model, Cmd Msg )
|
|
update _ msg model =
|
|
case msg of
|
|
SetUser t ->
|
|
let
|
|
state =
|
|
Comp.Dropdown.makeSingleList
|
|
{ makeOption =
|
|
\s ->
|
|
{ value = Data.UserState.toString s
|
|
, text = Data.UserState.toString s
|
|
, additional = ""
|
|
}
|
|
, placeholder = ""
|
|
, options = Data.UserState.all
|
|
, selected =
|
|
Data.UserState.fromString t.state
|
|
|> Maybe.map (\u -> List.filter ((==) u) Data.UserState.all)
|
|
|> Maybe.andThen List.head
|
|
|> Util.Maybe.withDefault (List.head Data.UserState.all)
|
|
}
|
|
in
|
|
( { model
|
|
| user = t
|
|
, login = t.login
|
|
, email = t.email
|
|
, password = t.password
|
|
, state = state
|
|
}
|
|
, Cmd.none
|
|
)
|
|
|
|
StateMsg m ->
|
|
let
|
|
( m1, c1 ) =
|
|
Comp.Dropdown.update m model.state
|
|
in
|
|
( { model | state = m1 }, Cmd.map StateMsg c1 )
|
|
|
|
SetLogin n ->
|
|
( { model | login = n }, Cmd.none )
|
|
|
|
SetEmail e ->
|
|
( { model
|
|
| email =
|
|
if e == "" then
|
|
Nothing
|
|
|
|
else
|
|
Just e
|
|
}
|
|
, Cmd.none
|
|
)
|
|
|
|
SetPassword p ->
|
|
( { model
|
|
| password =
|
|
if p == "" then
|
|
Nothing
|
|
|
|
else
|
|
Just p
|
|
}
|
|
, Cmd.none
|
|
)
|
|
|
|
|
|
|
|
--- View
|
|
|
|
|
|
view : UiSettings -> Model -> Html Msg
|
|
view settings model =
|
|
div [ class "ui form" ]
|
|
[ div
|
|
[ classList
|
|
[ ( "field", True )
|
|
, ( "error", model.login == "" )
|
|
, ( "invisible", model.user.login /= "" )
|
|
]
|
|
]
|
|
[ label [] [ text "Login*" ]
|
|
, input
|
|
[ type_ "text"
|
|
, onInput SetLogin
|
|
, placeholder "Login"
|
|
, value model.login
|
|
]
|
|
[]
|
|
]
|
|
, div [ class "field" ]
|
|
[ label [] [ text "E-Mail" ]
|
|
, input
|
|
[ onInput SetEmail
|
|
, model.email |> Maybe.withDefault "" |> value
|
|
, placeholder "E-Mail"
|
|
]
|
|
[]
|
|
]
|
|
, div [ class "field" ]
|
|
[ label [] [ text "State" ]
|
|
, Html.map StateMsg (Comp.Dropdown.view settings model.state)
|
|
]
|
|
, div
|
|
[ classList
|
|
[ ( "field", True )
|
|
, ( "invisible", model.user.login /= "" )
|
|
, ( "error", Util.Maybe.isEmpty model.password )
|
|
]
|
|
]
|
|
[ label [] [ text "Password*" ]
|
|
, input
|
|
[ type_ "text"
|
|
, onInput SetPassword
|
|
, placeholder "Password"
|
|
, Maybe.withDefault "" model.password |> value
|
|
]
|
|
[]
|
|
]
|
|
]
|
|
|
|
|
|
|
|
--- View2
|
|
|
|
|
|
view2 : UiSettings -> Model -> Html Msg
|
|
view2 settings model =
|
|
div [ class "flex flex-col" ]
|
|
[ div
|
|
[ class "mb-4" ]
|
|
[ label [ class S.inputLabel ]
|
|
[ text "Login"
|
|
, B.inputRequired
|
|
]
|
|
, input
|
|
[ type_ "text"
|
|
, onInput SetLogin
|
|
, placeholder "Login"
|
|
, value model.login
|
|
, class S.textInput
|
|
, classList [ ( S.inputErrorBorder, model.login == "" ) ]
|
|
]
|
|
[]
|
|
]
|
|
, div [ class "mb-4" ]
|
|
[ label [ class S.inputLabel ]
|
|
[ text "E-Mail"
|
|
]
|
|
, input
|
|
[ onInput SetEmail
|
|
, type_ "text"
|
|
, model.email |> Maybe.withDefault "" |> value
|
|
, placeholder "E-Mail"
|
|
, class S.textInput
|
|
]
|
|
[]
|
|
]
|
|
, div [ class "mb-4" ]
|
|
[ label [ class S.inputLabel ]
|
|
[ text "State"
|
|
]
|
|
, Html.map StateMsg
|
|
(Comp.Dropdown.view2
|
|
DS.mainStyle
|
|
settings
|
|
model.state
|
|
)
|
|
]
|
|
, div
|
|
[ class "mb-4"
|
|
, classList [ ( "hidden", model.user.login /= "" ) ]
|
|
]
|
|
[ label [ class S.inputLabel ]
|
|
[ text "Password"
|
|
, B.inputRequired
|
|
]
|
|
, input
|
|
[ type_ "text"
|
|
, onInput SetPassword
|
|
, placeholder "Password"
|
|
, Maybe.withDefault "" model.password |> value
|
|
, class S.textInput
|
|
, classList [ ( S.inputErrorBorder, Util.Maybe.isEmpty model.password ) ]
|
|
]
|
|
[]
|
|
]
|
|
]
|