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.
181 lines
4.3 KiB
Elm
181 lines
4.3 KiB
Elm
module Comp.IntField exposing
|
|
( Model
|
|
, Msg
|
|
, init
|
|
, update
|
|
, view
|
|
, viewWithInfo
|
|
, viewWithInfo2
|
|
)
|
|
|
|
import Html exposing (..)
|
|
import Html.Attributes exposing (..)
|
|
import Html.Events exposing (onInput)
|
|
import Markdown
|
|
import Styles as S
|
|
|
|
|
|
type alias Model =
|
|
{ min : Maybe Int
|
|
, max : Maybe Int
|
|
, label : String
|
|
, error : Maybe String
|
|
, lastInput : String
|
|
, optional : Bool
|
|
}
|
|
|
|
|
|
type Msg
|
|
= SetValue String
|
|
|
|
|
|
init : Maybe Int -> Maybe Int -> Bool -> String -> Model
|
|
init min max opt label =
|
|
{ min = min
|
|
, max = max
|
|
, label = label
|
|
, error = Nothing
|
|
, lastInput = ""
|
|
, optional = opt
|
|
}
|
|
|
|
|
|
tooLow : Model -> Int -> Bool
|
|
tooLow model n =
|
|
Maybe.map ((<) n) model.min
|
|
|> Maybe.withDefault (not model.optional)
|
|
|
|
|
|
tooHigh : Model -> Int -> Bool
|
|
tooHigh model n =
|
|
Maybe.map ((>) n) model.max
|
|
|> Maybe.withDefault (not model.optional)
|
|
|
|
|
|
update : Msg -> Model -> ( Model, Maybe Int )
|
|
update msg model =
|
|
let
|
|
tooHighError =
|
|
Maybe.withDefault 0 model.max
|
|
|> String.fromInt
|
|
|> (++) "Number must be <= "
|
|
|
|
tooLowError =
|
|
Maybe.withDefault 0 model.min
|
|
|> String.fromInt
|
|
|> (++) "Number must be >= "
|
|
in
|
|
case msg of
|
|
SetValue str ->
|
|
let
|
|
m =
|
|
{ model | lastInput = str }
|
|
in
|
|
case String.toInt str of
|
|
Just n ->
|
|
if tooLow model n then
|
|
( { m | error = Just tooLowError }
|
|
, Nothing
|
|
)
|
|
|
|
else if tooHigh model n then
|
|
( { m | error = Just tooHighError }
|
|
, Nothing
|
|
)
|
|
|
|
else
|
|
( { m | error = Nothing }, Just n )
|
|
|
|
Nothing ->
|
|
if model.optional && String.trim str == "" then
|
|
( { m | error = Nothing }, Nothing )
|
|
|
|
else
|
|
( { m | error = Just ("'" ++ str ++ "' is not a valid number!") }
|
|
, Nothing
|
|
)
|
|
|
|
|
|
view : Maybe Int -> String -> Model -> Html Msg
|
|
view =
|
|
viewWithInfo ""
|
|
|
|
|
|
viewWithInfo : String -> Maybe Int -> String -> Model -> Html Msg
|
|
viewWithInfo info nval classes model =
|
|
div
|
|
[ classList
|
|
[ ( classes, True )
|
|
, ( "error", model.error /= Nothing )
|
|
]
|
|
]
|
|
[ label [] [ text model.label ]
|
|
, input
|
|
[ type_ "text"
|
|
, Maybe.map String.fromInt nval
|
|
|> Maybe.withDefault model.lastInput
|
|
|> value
|
|
, onInput SetValue
|
|
]
|
|
[]
|
|
, span
|
|
[ classList
|
|
[ ( "small-info", True )
|
|
, ( "hidden invisible", info == "" )
|
|
]
|
|
]
|
|
[ Markdown.toHtml [] info
|
|
]
|
|
, div
|
|
[ classList
|
|
[ ( "ui pointing red basic label", True )
|
|
, ( "hidden", model.error == Nothing )
|
|
]
|
|
]
|
|
[ Maybe.withDefault "" model.error |> text
|
|
]
|
|
]
|
|
|
|
|
|
|
|
--- View2
|
|
|
|
|
|
viewWithInfo2 : String -> Maybe Int -> String -> Model -> Html Msg
|
|
viewWithInfo2 info nval classes model =
|
|
div
|
|
[ classList
|
|
[ ( classes, True )
|
|
, ( "error", model.error /= Nothing )
|
|
]
|
|
]
|
|
[ label [ class S.inputLabel ]
|
|
[ text model.label
|
|
]
|
|
, input
|
|
[ type_ "text"
|
|
, Maybe.map String.fromInt nval
|
|
|> Maybe.withDefault model.lastInput
|
|
|> value
|
|
, onInput SetValue
|
|
, class S.textInput
|
|
]
|
|
[]
|
|
, span
|
|
[ classList
|
|
[ ( "hidden", info == "" )
|
|
]
|
|
, class "opacity-50 text-sm"
|
|
]
|
|
[ Markdown.toHtml [] info
|
|
]
|
|
, div
|
|
[ classList
|
|
[ ( "hidden", model.error == Nothing )
|
|
]
|
|
, class S.errorMessage
|
|
]
|
|
[ Maybe.withDefault "" model.error |> text
|
|
]
|
|
]
|