Fix input field updates

Issue: #1340, #1299
This commit is contained in:
eikek
2022-02-27 00:53:09 +01:00
parent 79d58fe320
commit 96bcb11e7d
20 changed files with 664 additions and 383 deletions

View File

@ -302,7 +302,7 @@ viewForm texts _ _ model =
else
h1 [ class S.header2 ]
[ text (Maybe.withDefault "" model.formModel.name)
[ text (Comp.BookmarkQueryForm.getName model.formModel |> Maybe.withDefault "")
]
, MB.view
{ start =

View File

@ -5,34 +5,40 @@
-}
module Comp.BookmarkQueryForm exposing (Model, Msg, get, init, initQuery, initWith, update, view)
module Comp.BookmarkQueryForm exposing (Model, Msg, get, getName, init, initQuery, initWith, update, view)
import Api
import Api.Model.BookmarkedQuery exposing (BookmarkedQuery)
import Comp.Basic as B
import Comp.PowerSearchInput
import Comp.SimpleTextInput
import Data.Flags exposing (Flags)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onCheck, onInput)
import Html.Events exposing (onCheck)
import Http
import Messages.Comp.BookmarkQueryForm exposing (Texts)
import Styles as S
import Throttle exposing (Throttle)
import Time
import Util.Maybe
type alias Model =
{ bookmark : BookmarkedQuery
, name : Maybe String
, name : Comp.SimpleTextInput.Model
, nameExists : Bool
, queryModel : Comp.PowerSearchInput.Model
, isPersonal : Bool
, nameExistsThrottle : Throttle Msg
}
nameCfg : Comp.SimpleTextInput.Config
nameCfg =
let
c =
Comp.SimpleTextInput.defaultConfig
in
{ c | delay = 600 }
initQuery : String -> ( Model, Cmd Msg )
initQuery q =
let
@ -42,11 +48,10 @@ initQuery q =
Comp.PowerSearchInput.init
in
( { bookmark = Api.Model.BookmarkedQuery.empty
, name = Nothing
, name = Comp.SimpleTextInput.init nameCfg Nothing
, nameExists = False
, queryModel = res.model
, isPersonal = True
, nameExistsThrottle = Throttle.create 1
}
, Cmd.batch
[ Cmd.map QueryMsg res.cmd
@ -66,7 +71,7 @@ initWith bm =
initQuery bm.query
in
( { m
| name = Just bm.name
| name = Comp.SimpleTextInput.init nameCfg <| Just bm.name
, isPersonal = bm.personal
, bookmark = bm
}
@ -78,16 +83,22 @@ isValid : Model -> Bool
isValid model =
List.all identity
[ Comp.PowerSearchInput.isValid model.queryModel
, model.name /= Nothing
, getName model /= Nothing
, not model.nameExists
]
getName : Model -> Maybe String
getName model =
Comp.SimpleTextInput.getValue model.name
get : Model -> Maybe BookmarkedQuery
get model =
let
qStr =
Maybe.withDefault "" model.queryModel.input
Comp.PowerSearchInput.getSearchString model.queryModel
|> Maybe.withDefault ""
bm =
model.bookmark
@ -96,7 +107,7 @@ get model =
Just
{ bm
| query = qStr
, name = Maybe.withDefault "" model.name
, name = getName model |> Maybe.withDefault ""
, personal = model.isPersonal
}
@ -105,11 +116,10 @@ get model =
type Msg
= SetName String
= SetName Comp.SimpleTextInput.Msg
| QueryMsg Comp.PowerSearchInput.Msg
| SetPersonal Bool
| NameExistsResp (Result Http.Error Bool)
| UpdateThrottle
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
@ -117,21 +127,24 @@ update flags msg model =
let
nameCheck1 name =
Api.bookmarkNameExists flags name NameExistsResp
throttleSub =
Throttle.ifNeeded
(Time.every 150 (\_ -> UpdateThrottle))
model.nameExistsThrottle
in
case msg of
SetName n ->
SetName lm ->
let
( newThrottle, cmd ) =
Throttle.try (nameCheck1 n) model.nameExistsThrottle
result =
Comp.SimpleTextInput.update lm model.name
cmd =
case result.change of
Comp.SimpleTextInput.ValueUnchanged ->
Cmd.none
Comp.SimpleTextInput.ValueUpdated v ->
Maybe.map nameCheck1 v |> Maybe.withDefault Cmd.none
in
( { model | name = Util.Maybe.fromString n, nameExistsThrottle = newThrottle }
, cmd
, throttleSub
( { model | name = result.model }
, Cmd.batch [ cmd, Cmd.map SetName result.cmd ]
, Sub.map SetName result.sub
)
SetPersonal flag ->
@ -156,16 +169,6 @@ update flags msg model =
NameExistsResp (Err _) ->
( model, Cmd.none, Sub.none )
UpdateThrottle ->
let
( newThrottle, cmd ) =
Throttle.update model.nameExistsThrottle
in
( { model | nameExistsThrottle = newThrottle }
, cmd
, throttleSub
)
--- View
@ -180,7 +183,6 @@ view texts model =
[ Html.map QueryMsg
(Comp.PowerSearchInput.viewInput
{ placeholder = texts.queryLabel
, extraAttrs = []
}
model.queryModel
)
@ -198,15 +200,18 @@ view texts model =
[ text texts.basics.name
, B.inputRequired
]
, input
[ type_ "text"
, onInput SetName
, placeholder texts.basics.name
, value <| Maybe.withDefault "" model.name
, id "bookmark-name"
, class S.textInput
]
[]
, Html.map SetName
(Comp.SimpleTextInput.view [ placeholder texts.basics.name, class S.textInput, id "bookmark-name" ] model.name)
-- , input
-- [ type_ "text"
-- , onInput SetName
-- , placeholder texts.basics.name
-- , value <| Maybe.withDefault "" model.name
-- , id "bookmark-name"
-- , class S.textInput
-- ]
-- []
, span
[ class S.warnMessagePlain
, class "font-medium text-sm"

View File

@ -49,7 +49,8 @@ toSearchQuery model =
Search pm ->
let
qstr =
Maybe.withDefault "" pm.input
Comp.PowerSearchInput.getSearchString pm
|> Maybe.withDefault ""
in
if qstr == "" || Comp.PowerSearchInput.isValid pm then
Just (SearchQueryString qstr)
@ -258,7 +259,6 @@ view texts settings model =
searchSettings =
{ placeholder = texts.searchPlaceholder
, extraAttrs = []
}
in
div [ class "flex flex-col" ]

View File

@ -11,7 +11,9 @@ module Comp.CustomFieldInput exposing
, Msg
, UpdateResult
, init
, init1
, initWith
, initWith1
, update
, updateSearch
, view2
@ -21,6 +23,7 @@ import Api.Model.CustomField exposing (CustomField)
import Api.Model.ItemFieldValue exposing (ItemFieldValue)
import Comp.DatePicker
import Comp.MenuBar as MB
import Comp.SimpleTextInput
import Data.CustomFieldType exposing (CustomFieldType)
import Data.Icons as Icons
import Data.Money exposing (MoneyParseError(..))
@ -32,7 +35,6 @@ import Html.Events exposing (onClick, onInput)
import Messages.Comp.CustomFieldInput exposing (Texts)
import Styles as S
import Util.CustomField
import Util.Maybe
type alias Model =
@ -48,24 +50,30 @@ type FieldError
type alias FloatModel =
{ input : Comp.SimpleTextInput.Model
, result : Result FieldError Float
}
type alias MoneyModel =
{ input : String
, result : Result FieldError Float
}
type FieldModel
= TextField (Maybe String)
= TextField Comp.SimpleTextInput.Model
| NumberField FloatModel
| MoneyField FloatModel
| MoneyField MoneyModel
| BoolField Bool
| DateField (Maybe Date) DatePicker
type Msg
= NumberMsg String
= NumberMsg Comp.SimpleTextInput.Msg
| MoneyMsg String
| DateMsg DatePicker.Msg
| SetText String
| SetTextMsg Comp.SimpleTextInput.Msg
| ToggleBool
| Remove
@ -115,7 +123,7 @@ errorMsg texts model =
parseMsg True parseError
TextField mt ->
if mt == Nothing then
if Comp.SimpleTextInput.getValue mt == Nothing then
Just texts.errorNoValue
else
@ -126,7 +134,12 @@ errorMsg texts model =
init : CustomField -> ( Model, Cmd Msg )
init field =
init =
init1 Comp.SimpleTextInput.defaultConfig
init1 : Comp.SimpleTextInput.Config -> CustomField -> ( Model, Cmd Msg )
init1 cfg field =
let
( dm, dc ) =
Comp.DatePicker.init
@ -135,13 +148,13 @@ init field =
, fieldModel =
case fieldType field of
Data.CustomFieldType.Text ->
TextField Nothing
TextField (Comp.SimpleTextInput.init cfg Nothing)
Data.CustomFieldType.Numeric ->
NumberField (FloatModel "" (Err NoValue))
NumberField (FloatModel (Comp.SimpleTextInput.init cfg Nothing) (Err NoValue))
Data.CustomFieldType.Money ->
MoneyField (FloatModel "" (Err NoValue))
MoneyField (MoneyModel "" (Err NoValue))
Data.CustomFieldType.Boolean ->
BoolField False
@ -158,7 +171,12 @@ init field =
initWith : ItemFieldValue -> ( Model, Cmd Msg )
initWith value =
initWith =
initWith1 Comp.SimpleTextInput.defaultConfig
initWith1 : Comp.SimpleTextInput.Config -> ItemFieldValue -> ( Model, Cmd Msg )
initWith1 cfg value =
let
field =
CustomField value.id value.name value.label value.ftype 0 0
@ -170,19 +188,22 @@ initWith value =
, fieldModel =
case fieldType field of
Data.CustomFieldType.Text ->
TextField (Just value.value)
TextField (Comp.SimpleTextInput.init cfg <| Just value.value)
Data.CustomFieldType.Numeric ->
let
( fm, _ ) =
updateFloatModel False value.value string2Float identity
fm =
Comp.SimpleTextInput.init cfg <| Just value.value
res =
string2Float value.value
in
NumberField fm
NumberField { input = fm, result = res }
Data.CustomFieldType.Money ->
let
( fm, _ ) =
updateFloatModel
updateMoneyModel
False
value.value
(Data.Money.fromString >> Result.mapError NotMoney)
@ -223,6 +244,7 @@ type alias UpdateResult =
{ model : Model
, cmd : Cmd Msg
, result : FieldResult
, sub : Sub Msg
}
@ -239,30 +261,37 @@ updateSearch =
update1 : Bool -> Msg -> Model -> UpdateResult
update1 forSearch msg model =
case ( msg, model.fieldModel ) of
( SetText str, TextField _ ) ->
( SetTextMsg lm, TextField tm ) ->
let
newValue =
Util.Maybe.fromString str
result =
Comp.SimpleTextInput.update lm tm
model_ =
{ model | fieldModel = TextField newValue }
in
UpdateResult model_ Cmd.none (Maybe.map Value newValue |> Maybe.withDefault NoResult)
{ model | fieldModel = TextField result.model }
( NumberMsg str, NumberField _ ) ->
let
( fm, res ) =
updateFloatModel forSearch str string2Float identity
cmd =
Cmd.map SetTextMsg result.cmd
model_ =
{ model | fieldModel = NumberField fm }
sub =
Sub.map SetTextMsg result.sub
fres =
case result.change of
Comp.SimpleTextInput.ValueUpdated v ->
Maybe.map Value v |> Maybe.withDefault NoResult
Comp.SimpleTextInput.ValueUnchanged ->
NoResult
in
UpdateResult model_ Cmd.none res
UpdateResult model_ cmd fres sub
( NumberMsg lm, NumberField tm ) ->
updateFloatModel forSearch model lm tm string2Float
( MoneyMsg str, MoneyField _ ) ->
let
( fm, res ) =
updateFloatModel
updateMoneyModel
forSearch
str
(Data.Money.fromString >> Result.mapError NotMoney)
@ -271,7 +300,7 @@ update1 forSearch msg model =
model_ =
{ model | fieldModel = MoneyField fm }
in
UpdateResult model_ Cmd.none res
UpdateResult model_ Cmd.none res Sub.none
( ToggleBool, BoolField b ) ->
let
@ -281,7 +310,7 @@ update1 forSearch msg model =
value =
Util.CustomField.boolValue (not b)
in
UpdateResult model_ Cmd.none (Value value)
UpdateResult model_ Cmd.none (Value value) Sub.none
( DateMsg lm, DateField old picker ) ->
let
@ -309,23 +338,23 @@ update1 forSearch msg model =
model_ =
{ model | fieldModel = DateField newDate picker_ }
in
UpdateResult model_ Cmd.none value
UpdateResult model_ Cmd.none value Sub.none
( Remove, _ ) ->
UpdateResult model Cmd.none RemoveField
UpdateResult model Cmd.none RemoveField Sub.none
-- no other possibilities, not well encoded here
_ ->
UpdateResult model Cmd.none NoResult
UpdateResult model Cmd.none NoResult Sub.none
updateFloatModel :
updateMoneyModel :
Bool
-> String
-> (String -> Result FieldError Float)
-> (String -> String)
-> ( FloatModel, FieldResult )
updateFloatModel forSearch msg parse normalize =
-> ( MoneyModel, FieldResult )
updateMoneyModel forSearch msg parse normalize =
if forSearch && hasWildCards msg then
( { input = normalize msg
, result = Ok 0
@ -350,6 +379,57 @@ updateFloatModel forSearch msg parse normalize =
)
updateFloatModel :
Bool
-> Model
-> Comp.SimpleTextInput.Msg
-> FloatModel
-> (String -> Result FieldError Float)
-> UpdateResult
updateFloatModel forSearch model lm fm parse =
let
result =
Comp.SimpleTextInput.update lm fm.input
( floatModel, fieldResult ) =
case result.change of
Comp.SimpleTextInput.ValueUnchanged ->
( { fm | input = result.model }, NoResult )
Comp.SimpleTextInput.ValueUpdated v ->
let
value =
Maybe.withDefault "" v
in
if forSearch && hasWildCards value then
( { input = result.model
, result = Ok 0
}
, Value value
)
else
case parse value of
Ok n ->
( { input = result.model
, result = Ok n
}
, Value value
)
Err err ->
( { input = result.model
, result = Err err
}
, NoResult
)
model_ =
{ model | fieldModel = NumberField floatModel }
in
UpdateResult model_ (Cmd.map NumberMsg result.cmd) fieldResult (Sub.map NumberMsg result.sub)
hasWildCards : String -> Bool
hasWildCards msg =
String.startsWith "*" msg || String.endsWith "*" msg
@ -406,14 +486,8 @@ makeInput2 icon model =
case model.fieldModel of
TextField v ->
div [ class "flex flex-row relative" ]
[ input
[ type_ "text"
, Maybe.withDefault "" v |> value
, onInput SetText
, class S.textInputSidebar
, class "pl-10 pr-10"
]
[]
[ Html.map SetTextMsg
(Comp.SimpleTextInput.view [ class S.textInputSidebar, class "pl-10 pr-10" ] v)
, removeButton2 ""
, i
[ class (iconOr <| Icons.customFieldType2 Data.CustomFieldType.Text)
@ -424,14 +498,8 @@ makeInput2 icon model =
NumberField nm ->
div [ class "flex flex-row relative" ]
[ input
[ type_ "text"
, value nm.input
, onInput NumberMsg
, class S.textInputSidebar
, class "pl-10 pr-10"
]
[]
[ Html.map NumberMsg
(Comp.SimpleTextInput.view [ class S.textInputSidebar, class "pl-10 pr-10" ] nm.input)
, removeButton2 ""
, i
[ class (iconOr <| Icons.customFieldType2 Data.CustomFieldType.Numeric)

View File

@ -29,6 +29,7 @@ import Api.Model.CustomFieldList exposing (CustomFieldList)
import Api.Model.ItemFieldValue exposing (ItemFieldValue)
import Comp.CustomFieldInput
import Comp.FixedDropdown
import Comp.SimpleTextInput
import Data.CustomFieldChange exposing (CustomFieldChange(..))
import Data.CustomFieldOrder
import Data.CustomFieldType
@ -157,6 +158,7 @@ mkFieldSelect fields =
type alias UpdateResult =
{ model : Model
, cmd : Cmd Msg
, sub : Sub Msg
, result : CustomFieldChange
}
@ -175,7 +177,7 @@ update1 : Bool -> Flags -> Msg -> Model -> UpdateResult
update1 forSearch flags msg model =
case msg of
CreateNewField ->
UpdateResult model Cmd.none FieldCreateNew
UpdateResult model Cmd.none Sub.none FieldCreateNew
CustomFieldResp (Ok list) ->
let
@ -185,10 +187,10 @@ update1 forSearch flags msg model =
, fieldSelect = mkFieldSelect (currentOptions list.items model.visibleFields)
}
in
UpdateResult model_ Cmd.none NoFieldChange
UpdateResult model_ Cmd.none Sub.none NoFieldChange
CustomFieldResp (Err _) ->
UpdateResult model Cmd.none NoFieldChange
UpdateResult model Cmd.none Sub.none NoFieldChange
FieldSelectMsg lm ->
let
@ -208,15 +210,15 @@ update1 forSearch flags msg model =
in
case sel of
Just field ->
update flags (ApplyField field) model
update1 forSearch flags (ApplyField field) model
Nothing ->
UpdateResult model_ Cmd.none NoFieldChange
UpdateResult model_ Cmd.none Sub.none NoFieldChange
ApplyField f ->
let
( fm, fc ) =
Comp.CustomFieldInput.init f
Comp.CustomFieldInput.init1 (textInputCfg forSearch) f
visible =
Dict.insert f.name (VisibleField f fm) model.visibleFields
@ -241,7 +243,7 @@ update1 forSearch flags msg model =
_ ->
NoFieldChange
in
UpdateResult model_ cmd_ change
UpdateResult model_ cmd_ Sub.none change
RemoveField f ->
let
@ -254,7 +256,7 @@ update1 forSearch flags msg model =
, fieldSelect = mkFieldSelect (currentOptions model.allFields visible)
}
in
UpdateResult model_ Cmd.none (FieldValueRemove f)
UpdateResult model_ Cmd.none Sub.none (FieldValueRemove f)
CustomFieldInputMsg f lm ->
let
@ -280,6 +282,9 @@ update1 forSearch flags msg model =
cmd_ =
Cmd.map (CustomFieldInputMsg field) res.cmd
sub_ =
Sub.map (CustomFieldInputMsg field) res.sub
result =
case res.result of
Comp.CustomFieldInput.Value str ->
@ -292,13 +297,13 @@ update1 forSearch flags msg model =
NoFieldChange
in
if res.result == Comp.CustomFieldInput.RemoveField then
update flags (RemoveField field) model_
update1 forSearch flags (RemoveField field) model_
else
UpdateResult model_ cmd_ result
UpdateResult model_ cmd_ sub_ result
Nothing ->
UpdateResult model Cmd.none NoFieldChange
UpdateResult model Cmd.none Sub.none NoFieldChange
SetValues values ->
let
@ -308,7 +313,7 @@ update1 forSearch flags msg model =
merge fv ( dict, cmds ) =
let
( fim, fic ) =
Comp.CustomFieldInput.initWith fv
Comp.CustomFieldInput.initWith1 (textInputCfg forSearch) fv
f =
field fv
@ -326,7 +331,16 @@ update1 forSearch flags msg model =
, visibleFields = modelDict
}
in
UpdateResult model_ (Cmd.batch cmdList) NoFieldChange
UpdateResult model_ (Cmd.batch cmdList) Sub.none NoFieldChange
textInputCfg : Bool -> Comp.SimpleTextInput.Config
textInputCfg forSearch =
if forSearch then
Comp.SimpleTextInput.onEnterOnly
else
Comp.SimpleTextInput.defaultConfig
@ -381,7 +395,7 @@ viewMenuBar2 viewSettings model =
dropdown
)
:: (if viewSettings.showAddButton then
[ addFieldLink2 viewSettings.createCustomFieldTitle "ml-1" model
[ addFieldLink viewSettings.createCustomFieldTitle "ml-1" model
]
else
@ -409,8 +423,8 @@ viewCustomField2 texts viewSettings model field =
span [] []
addFieldLink2 : String -> String -> Model -> Html Msg
addFieldLink2 titleStr classes _ =
addFieldLink : String -> String -> Model -> Html Msg
addFieldLink titleStr classes _ =
a
[ class classes
, class S.secondaryButton

View File

@ -20,6 +20,7 @@ import Comp.ItemDetail.Model
, personMatchesOrg
)
import Comp.KeyInput
import Comp.SimpleTextInput
import Comp.Tabs as TB
import Comp.TagDropdown
import Data.DropdownStyle
@ -158,14 +159,11 @@ formTabs texts flags settings model =
, info = Nothing
, body =
[ div [ class "relative mb-4" ]
[ input
[ type_ "text"
, value model.nameModel
, onInput SetName
, class S.textInputSidebar
, class "pr-10"
]
[]
[ Html.map SetNameMsg
(Comp.SimpleTextInput.view
[ class S.textInputSidebar, class "pr-10" ]
model.nameInput
)
, span [ class S.inputLeftIconOnly ]
[ i
[ classList

View File

@ -53,6 +53,7 @@ import Comp.KeyInput
import Comp.LinkTarget exposing (LinkTarget)
import Comp.MarkdownInput
import Comp.SentMails
import Comp.SimpleTextInput
import Comp.TagDropdown
import Data.Direction exposing (Direction)
import Data.Fields exposing (Field)
@ -65,8 +66,6 @@ import Html5.DragDrop as DD
import Http
import Page exposing (Page(..))
import Set exposing (Set)
import Throttle exposing (Throttle)
import Util.Tag
type alias Model =
@ -83,8 +82,8 @@ type alias Model =
, folderModel : Comp.Dropdown.Model IdName
, allFolders : List FolderItem
, nameModel : String
, nameInput : Comp.SimpleTextInput.Model
, nameState : SaveNameState
, nameSaveThrottle : Throttle Msg
, notesModel : Maybe String
, notesField : NotesField
, itemModal : Maybe ConfirmModalValue
@ -114,7 +113,6 @@ type alias Model =
, keyInputModel : Comp.KeyInput.Model
, customFieldsModel : Comp.CustomFieldMultiInput.Model
, customFieldSavingIcon : Dict String String
, customFieldThrottle : Throttle Msg
, allTags : List Tag
, allPersons : Dict String Person
, attachmentDropdownOpen : Bool
@ -218,9 +216,9 @@ emptyModel =
, concEquipModel = Comp.Dropdown.makeSingle
, folderModel = Comp.Dropdown.makeSingle
, allFolders = []
, nameInput = Comp.SimpleTextInput.initDefault Nothing
, nameModel = ""
, nameState = SaveSuccess
, nameSaveThrottle = Throttle.create 1
, notesModel = Nothing
, notesField = ViewNotes
, itemModal = Nothing
@ -250,7 +248,6 @@ emptyModel =
, keyInputModel = Comp.KeyInput.init
, customFieldsModel = Comp.CustomFieldMultiInput.initWith []
, customFieldSavingIcon = Dict.empty
, customFieldThrottle = Throttle.create 1
, allTags = []
, allPersons = Dict.empty
, attachmentDropdownOpen = False
@ -285,7 +282,6 @@ type Msg
| GetOrgResp (Result Http.Error ReferenceList)
| GetPersonResp (Result Http.Error PersonList)
| GetEquipResp (Result Http.Error EquipmentList)
| SetName String
| SetNotes String
| ToggleEditNotes
| NotesEditMsg Comp.MarkdownInput.Msg
@ -349,7 +345,6 @@ type Msg
| StartEditEquipModal
| ResetHiddenMsg Field (Result Http.Error BasicResult)
| SaveNameResp (Result Http.Error BasicResult)
| UpdateThrottle
| KeyInputMsg Comp.KeyInput.Msg
| ToggleAttachMenu
| UiSettingsUpdated
@ -371,6 +366,7 @@ type Msg
| ToggleShowQrItem String
| ToggleShowQrAttach String
| PrintElement String
| SetNameMsg Comp.SimpleTextInput.Msg
type SaveNameState

View File

@ -23,14 +23,13 @@ import Api.Model.FolderList exposing (FolderList)
import Api.Model.IdName exposing (IdName)
import Api.Model.PersonList exposing (PersonList)
import Api.Model.ReferenceList exposing (ReferenceList)
import Api.Model.Tag exposing (Tag)
import Api.Model.TagList exposing (TagList)
import Comp.CustomFieldMultiInput
import Comp.DatePicker
import Comp.DetailEdit
import Comp.Dropdown exposing (isDropdownChangeMsg)
import Comp.ItemDetail.FieldTabState as FTabState exposing (EditTab(..), tabName)
import Comp.ItemDetail.FormChange exposing (FormChange(..))
import Comp.SimpleTextInput
import Comp.Tabs as TB
import Comp.TagDropdown
import Data.CustomFieldChange exposing (CustomFieldChange(..))
@ -43,24 +42,19 @@ import Data.FolderOrder
import Data.Icons as Icons
import Data.PersonOrder
import Data.PersonUse
import Data.TagOrder
import Data.UiSettings exposing (UiSettings)
import DatePicker exposing (DatePicker)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick, onInput)
import Html.Events exposing (onClick)
import Http
import Markdown
import Messages.Comp.ItemDetail.MultiEditMenu exposing (Texts)
import Page exposing (Page(..))
import Set exposing (Set)
import Styles as S
import Task
import Throttle exposing (Throttle)
import Time
import Util.Folder
import Util.List
import Util.Maybe
@ -81,8 +75,7 @@ type TagEditMode
type alias Model =
{ tagModel : Comp.TagDropdown.Model
, nameModel : String
, nameSaveThrottle : Throttle Msg
, nameInput : Comp.SimpleTextInput.Model
, folderModel : Comp.Dropdown.Model IdName
, allFolders : List FolderItem
, directionModel : Comp.Dropdown.Model Direction
@ -104,9 +97,7 @@ type alias Model =
type Msg
= ItemDatePickerMsg Comp.DatePicker.Msg
| DueDatePickerMsg Comp.DatePicker.Msg
| SetName String
| SaveName
| UpdateThrottle
| SetNameMsg Comp.SimpleTextInput.Msg
| RemoveDueDate
| RemoveDate
| ConfirmMsg Bool
@ -140,8 +131,7 @@ init =
, concEquipModel = Comp.Dropdown.makeSingle
, folderModel = Comp.Dropdown.makeSingle
, allFolders = []
, nameModel = ""
, nameSaveThrottle = Throttle.create 1
, nameInput = Comp.SimpleTextInput.initDefault Nothing
, itemDatePicker = Comp.DatePicker.emptyModel
, itemDate = Nothing
, dueDate = Nothing
@ -490,51 +480,24 @@ update flags msg model =
RemoveDueDate ->
resultNoCmd (DueDateChange Nothing) { model | dueDate = Nothing }
SetName str ->
case Util.Maybe.fromString str of
Just newName ->
let
cmd_ =
Task.succeed ()
|> Task.perform (\_ -> SaveName)
( newThrottle, cmd ) =
Throttle.try cmd_ model.nameSaveThrottle
newModel =
{ model
| nameSaveThrottle = newThrottle
, nameModel = newName
}
sub =
nameThrottleSub newModel
in
UpdateResult newModel cmd sub NoFormChange
Nothing ->
resultNone { model | nameModel = str }
SaveName ->
case Util.Maybe.fromString model.nameModel of
Just n ->
resultNoCmd (NameChange n) model
Nothing ->
resultNone model
UpdateThrottle ->
SetNameMsg lm ->
let
( newThrottle, cmd ) =
Throttle.update model.nameSaveThrottle
result =
Comp.SimpleTextInput.update lm model.nameInput
newModel =
{ model | nameSaveThrottle = newThrottle }
formChange =
case result.change of
Comp.SimpleTextInput.ValueUpdated v ->
NameChange <| Maybe.withDefault "" v
sub =
nameThrottleSub newModel
Comp.SimpleTextInput.ValueUnchanged ->
NoFormChange
in
UpdateResult newModel cmd sub NoFormChange
{ model = { model | nameInput = result.model }
, cmd = Cmd.batch [ Cmd.map SetNameMsg result.cmd ]
, sub = Sub.map SetNameMsg result.sub
, change = formChange
}
CustomFieldMsg lm ->
let
@ -547,6 +510,9 @@ update flags msg model =
cmd_ =
Cmd.map CustomFieldMsg res.cmd
sub_ =
Sub.map CustomFieldMsg res.sub
change =
case res.result of
NoFieldChange ->
@ -561,7 +527,7 @@ update flags msg model =
FieldCreateNew ->
NoFormChange
in
UpdateResult model_ cmd_ Sub.none change
UpdateResult model_ cmd_ sub_ change
ToggleAkkordionTab name ->
let
@ -575,13 +541,6 @@ update flags msg model =
UpdateResult { model | openTabs = tabs } Cmd.none Sub.none NoFormChange
nameThrottleSub : Model -> Sub Msg
nameThrottleSub model =
Throttle.ifNeeded
(Time.every 400 (\_ -> UpdateThrottle))
model.nameSaveThrottle
--- View
@ -913,13 +872,8 @@ renderEditForm2 texts flags cfg settings model =
, info = Nothing
, body =
[ div [ class "relative" ]
[ input
[ type_ "text"
, value model.nameModel
, onInput SetName
, class S.textInputSidebar
]
[]
[ Html.map SetNameMsg
(Comp.SimpleTextInput.view [ class S.textInputSidebar ] model.nameInput)
, span [ class S.inputLeftIconOnly ]
[ i
[ classList

View File

@ -54,6 +54,7 @@ import Comp.MarkdownInput
import Comp.OrgForm
import Comp.PersonForm
import Comp.SentMails
import Comp.SimpleTextInput
import Comp.TagDropdown
import Data.CustomFieldChange exposing (CustomFieldChange(..))
import Data.Direction
@ -73,7 +74,6 @@ import Http
import Page exposing (Page(..))
import Ports
import Set exposing (Set)
import Throttle
import Time
import Util.File exposing (makeFileId)
import Util.List
@ -239,6 +239,7 @@ update key flags inav settings msg model =
{ model =
{ lastModel
| item = item
, nameInput = Comp.SimpleTextInput.initDefault (Just item.name)
, nameModel = item.name
, nameState = SaveSuccess
, notesModel = item.notes
@ -459,29 +460,25 @@ update key flags inav settings msg model =
in
resultModelCmd ( newModel, Cmd.batch [ save, Cmd.map ConcEquipMsg c2 ] )
SetName str ->
case Util.Maybe.fromString str of
Just newName ->
let
nm =
{ model | nameModel = newName }
SetNameMsg lm ->
let
result =
Comp.SimpleTextInput.update lm model.nameInput
cmd_ =
setName flags nm
( setter, value, save ) =
case result.change of
Comp.SimpleTextInput.ValueUpdated v ->
( setName flags { model | nameModel = Maybe.withDefault "" v }, v, Saving )
( newThrottle, cmd ) =
Throttle.try cmd_ nm.nameSaveThrottle
in
withSub
( { nm
| nameState = Saving
, nameSaveThrottle = newThrottle
}
, cmd
)
Nothing ->
resultModel { model | nameModel = str, nameState = SaveFailed }
Comp.SimpleTextInput.ValueUnchanged ->
( Cmd.none, Nothing, model.nameState )
in
{ model = { model | nameInput = result.model, nameState = save, nameModel = Maybe.withDefault model.nameModel value }
, cmd = Cmd.batch [ Cmd.map SetNameMsg result.cmd, setter ]
, sub = Sub.map SetNameMsg result.sub
, linkTarget = Comp.LinkTarget.LinkNone
, removedItem = Nothing
}
SetNotes str ->
resultModel
@ -1363,19 +1360,6 @@ update key flags inav settings msg model =
ResetHiddenMsg _ _ ->
resultModel model
UpdateThrottle ->
let
( newSaveName, cmd1 ) =
Throttle.update model.nameSaveThrottle
( newCustomField, cmd2 ) =
Throttle.update model.customFieldThrottle
in
withSub
( { model | nameSaveThrottle = newSaveName, customFieldThrottle = newCustomField }
, Cmd.batch [ cmd1, cmd2 ]
)
KeyInputMsg lm ->
let
( km, keys ) =
@ -1408,9 +1392,7 @@ update key flags inav settings msg model =
resultModel model_
else
-- withSub because the keypress may be inside the name
-- field and requires to activate the throttle
withSub ( model_, Cmd.none )
resultModelCmd ( model_, Cmd.none )
ToggleAttachMenu ->
resultModel
@ -1444,10 +1426,13 @@ update key flags inav settings msg model =
cmd_ =
Cmd.map CustomFieldMsg result.cmd
sub_ =
Sub.map CustomFieldMsg result.sub
loadingIcon =
"refresh loading icon"
( action_, icons ) =
( action, icons ) =
case result.result of
NoFieldChange ->
( Cmd.none, model.customFieldSavingIcon )
@ -1478,22 +1463,14 @@ update key flags inav settings msg model =
else
Nothing
( throttle, action ) =
if action_ == Cmd.none then
( model.customFieldThrottle, action_ )
else
Throttle.try action_ model.customFieldThrottle
model_ =
{ model
| customFieldsModel = result.model
, customFieldThrottle = throttle
, modalEdit = modalEdit
, customFieldSavingIcon = icons
}
in
withSub ( model_, Cmd.batch [ cmd_, action ] )
resultModelCmdSub ( model_, Cmd.batch [ cmd_, action ], sub_ )
CustomFieldSaveResp cf fv (Ok res) ->
let
@ -1609,7 +1586,7 @@ update key flags inav settings msg model =
SelectView _ ->
( SimpleView, Cmd.none )
in
withSub
resultModelCmd
( { model
| viewMode = nextView
}
@ -1776,24 +1753,6 @@ setErrored model fileid =
Set.insert fileid model.errored
withSub : ( Model, Cmd Msg ) -> UpdateResult
withSub ( m, c ) =
{ model = m
, cmd = c
, sub =
Sub.batch
[ Throttle.ifNeeded
(Time.every 200 (\_ -> UpdateThrottle))
m.nameSaveThrottle
, Throttle.ifNeeded
(Time.every 200 (\_ -> UpdateThrottle))
m.customFieldThrottle
]
, linkTarget = Comp.LinkTarget.LinkNone
, removedItem = Nothing
}
resetField : Flags -> String -> (Field -> Result Http.Error BasicResult -> msg) -> Field -> Cmd msg
resetField flags item tagger field =
case field of

View File

@ -196,7 +196,7 @@ makeSettings model =
query =
let
qstr =
model.queryModel.input
Comp.PowerSearchInput.getSearchString model.queryModel
bm =
Comp.BookmarkDropdown.getSelectedId model.bookmarkDropdown
@ -409,7 +409,6 @@ view texts extraClasses settings model =
[ Html.map QueryMsg
(Comp.PowerSearchInput.viewInput
{ placeholder = texts.queryLabel
, extraAttrs = []
}
model.queryModel
)

View File

@ -10,6 +10,7 @@ module Comp.PowerSearchInput exposing
, Model
, Msg
, ViewSettings
, getSearchString
, init
, initWith
, isValid
@ -85,6 +86,11 @@ setSearchString q =
SetSearch q
getSearchString : Model -> Maybe String
getSearchString model =
model.input
--- Update
@ -165,24 +171,21 @@ throttleUpdate model =
type alias ViewSettings =
{ placeholder : String
, extraAttrs : List (Attribute Msg)
}
viewInput : ViewSettings -> Model -> Html Msg
viewInput cfg model =
input
(cfg.extraAttrs
++ [ type_ "text"
, placeholder cfg.placeholder
, onInput SetSearch
, Util.Html.onKeyUpCode KeyUpMsg
, Maybe.map value model.input
|> Maybe.withDefault (value "")
, class S.textInput
, class "text-sm "
]
)
[ type_ "text"
, placeholder cfg.placeholder
, onInput SetSearch
, Util.Html.onKeyUpCode KeyUpMsg
, Maybe.map value model.input
|> Maybe.withDefault (value "")
, class S.textInput
, class "text-sm "
]
[]

View File

@ -446,6 +446,7 @@ linkTargetMsg linkTarget =
type alias NextState =
{ model : Model
, cmd : Cmd Msg
, sub : Sub Msg
, stateChange : Bool
, dragDrop : DD.DragDropData
}
@ -479,6 +480,7 @@ updateDrop ddm flags settings msg model =
in
{ model = set.model
, cmd = set.cmd
, sub = Sub.none
, stateChange = True
, dragDrop = set.dragDrop
}
@ -520,6 +522,7 @@ updateDrop ddm flags settings msg model =
, cdp
, Api.getBookmarks flags AllBookmarksResp
]
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -527,6 +530,7 @@ updateDrop ddm flags settings msg model =
ResetForm ->
{ model = resetModel model
, cmd = Api.itemSearchStats flags Api.Model.ItemQuery.empty GetAllTagsResp
, sub = Sub.none
, stateChange = True
, dragDrop = DD.DragDropData ddm Nothing
}
@ -548,6 +552,7 @@ updateDrop ddm flags settings msg model =
Nothing ->
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -578,6 +583,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { nextModel | selectedBookmarks = sel }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = sel /= model.selectedBookmarks
, dragDrop = DD.DragDropData ddm Nothing
}
@ -591,6 +597,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | tagSelectModel = tagSel }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -598,6 +605,7 @@ updateDrop ddm flags settings msg model =
GetAllTagsResp (Err _) ->
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -644,7 +652,7 @@ updateDrop ddm flags settings msg model =
Util.CustomField.statsToFields stats
fieldOpts =
Comp.CustomFieldMultiInput.update flags
Comp.CustomFieldMultiInput.updateSearch flags
(Comp.CustomFieldMultiInput.setOptions fields)
model.customFieldModel
|> .model
@ -665,6 +673,7 @@ updateDrop ddm flags settings msg model =
in
{ model = model_
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -672,6 +681,7 @@ updateDrop ddm flags settings msg model =
GetStatsResp (Err _) ->
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -686,6 +696,7 @@ updateDrop ddm flags settings msg model =
GetEquipResp (Err _) ->
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -700,6 +711,7 @@ updateDrop ddm flags settings msg model =
GetOrgResp (Err _) ->
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -734,6 +746,7 @@ updateDrop ddm flags settings msg model =
GetPersonResp (Err _) ->
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -749,6 +762,7 @@ updateDrop ddm flags settings msg model =
, tagSelection = sel
}
, cmd = Cmd.none
, sub = Sub.none
, stateChange = sel /= model.tagSelection
, dragDrop = ddd
}
@ -760,6 +774,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | directionModel = m2 }
, cmd = Cmd.map DirectionMsg c2
, sub = Sub.none
, stateChange = isDropdownChangeMsg m
, dragDrop = DD.DragDropData ddm Nothing
}
@ -771,6 +786,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | orgModel = m2 }
, cmd = Cmd.map OrgMsg c2
, sub = Sub.none
, stateChange = isDropdownChangeMsg m
, dragDrop = DD.DragDropData ddm Nothing
}
@ -782,6 +798,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | corrPersonModel = m2 }
, cmd = Cmd.map CorrPersonMsg c2
, sub = Sub.none
, stateChange = isDropdownChangeMsg m
, dragDrop = DD.DragDropData ddm Nothing
}
@ -793,6 +810,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | concPersonModel = m2 }
, cmd = Cmd.map ConcPersonMsg c2
, sub = Sub.none
, stateChange = isDropdownChangeMsg m
, dragDrop = DD.DragDropData ddm Nothing
}
@ -804,6 +822,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | concEquipmentModel = m2 }
, cmd = Cmd.map ConcEquipmentMsg c2
, sub = Sub.none
, stateChange = isDropdownChangeMsg m
, dragDrop = DD.DragDropData ddm Nothing
}
@ -815,6 +834,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | inboxCheckbox = not current }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = True
, dragDrop = DD.DragDropData ddm Nothing
}
@ -833,6 +853,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | searchMode = next }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = True
, dragDrop = DD.DragDropData ddm Nothing
}
@ -852,6 +873,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | fromDateModel = dp, fromDate = nextDate }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = model.fromDate /= nextDate
, dragDrop = DD.DragDropData ddm Nothing
}
@ -871,6 +893,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | untilDateModel = dp, untilDate = nextDate }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = model.untilDate /= nextDate
, dragDrop = DD.DragDropData ddm Nothing
}
@ -890,6 +913,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | fromDueDateModel = dp, fromDueDate = nextDate }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = model.fromDueDate /= nextDate
, dragDrop = DD.DragDropData ddm Nothing
}
@ -909,6 +933,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | untilDueDateModel = dp, untilDueDate = nextDate }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = model.untilDueDate /= nextDate
, dragDrop = DD.DragDropData ddm Nothing
}
@ -920,6 +945,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | nameModel = next }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -927,6 +953,7 @@ updateDrop ddm flags settings msg model =
SetTextSearch str ->
{ model = { model | textSearchModel = updateTextSearch str model.textSearchModel }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -935,6 +962,7 @@ updateDrop ddm flags settings msg model =
if flags.config.fullTextSearchEnabled then
{ model = { model | textSearchModel = swapTextSearch model.textSearchModel }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -942,6 +970,7 @@ updateDrop ddm flags settings msg model =
else
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -951,6 +980,7 @@ updateDrop ddm flags settings msg model =
Fulltext _ ->
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -958,6 +988,7 @@ updateDrop ddm flags settings msg model =
Names s ->
{ model = { model | textSearchModel = Fulltext s }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -967,6 +998,7 @@ updateDrop ddm flags settings msg model =
Fulltext s ->
{ model = { model | textSearchModel = Names s }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -974,6 +1006,7 @@ updateDrop ddm flags settings msg model =
Names _ ->
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -981,6 +1014,7 @@ updateDrop ddm flags settings msg model =
KeyUpMsg (Just Enter) ->
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = True
, dragDrop = DD.DragDropData ddm Nothing
}
@ -988,6 +1022,7 @@ updateDrop ddm flags settings msg model =
KeyUpMsg _ ->
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -1003,6 +1038,7 @@ updateDrop ddm flags settings msg model =
, selectedFolder = sel
}
, cmd = Cmd.none
, sub = Sub.none
, stateChange = model.selectedFolder /= sel
, dragDrop = ddd
}
@ -1018,6 +1054,7 @@ updateDrop ddm flags settings msg model =
, customValues = Data.CustomFieldChange.collectValues res.result model.customValues
}
, cmd = Cmd.map CustomFieldMsg res.cmd
, sub = Sub.map CustomFieldMsg res.sub
, stateChange =
Data.CustomFieldChange.isValueChange res.result
, dragDrop = DD.DragDropData ddm Nothing
@ -1046,6 +1083,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | sourceModel = next }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -1064,6 +1102,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | openTabs = tabs }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -1083,6 +1122,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | openTabs = next }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -1090,13 +1130,15 @@ updateDrop ddm flags settings msg model =
AllBookmarksResp (Ok bm) ->
{ model = { model | allBookmarks = Comp.BookmarkChooser.init bm }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = model.allBookmarks /= Comp.BookmarkChooser.init bm
, dragDrop = DD.DragDropData ddm Nothing
}
AllBookmarksResp (Err err) ->
AllBookmarksResp (Err _) ->
{ model = model
, cmd = Cmd.none
, sub = Sub.none
, stateChange = False
, dragDrop = DD.DragDropData ddm Nothing
}
@ -1108,6 +1150,7 @@ updateDrop ddm flags settings msg model =
in
{ model = { model | allBookmarks = next, selectedBookmarks = sel }
, cmd = Cmd.none
, sub = Sub.none
, stateChange = sel /= model.selectedBookmarks || model.allBookmarks /= next
, dragDrop = DD.DragDropData ddm Nothing
}

View File

@ -100,7 +100,7 @@ getShare model =
( model.share.id
, { name = model.name
, query =
model.queryModel.input
Comp.PowerSearchInput.getSearchString model.queryModel
|> Maybe.withDefault ""
, enabled = model.enabled
, password = model.password
@ -211,7 +211,6 @@ view texts model =
[ Html.map QueryMsg
(Comp.PowerSearchInput.viewInput
{ placeholder = texts.queryLabel
, extraAttrs = []
}
model.queryModel
)

View File

@ -0,0 +1,254 @@
{-
Copyright 2020 Eike K. & Contributors
SPDX-License-Identifier: AGPL-3.0-or-later
-}
module Comp.SimpleTextInput exposing
( Config
, Model
, Msg
, ValueChange(..)
, defaultConfig
, getValue
, init
, initDefault
, onEnterOnly
, setValue
, update
, view
, viewMap
)
import Html exposing (Attribute, Html, input)
import Html.Attributes exposing (type_, value)
import Html.Events exposing (onBlur, onInput)
import Task
import Throttle exposing (Throttle)
import Time
import Util.Html exposing (KeyCode, onKeyUpCode)
import Util.Maybe
type Model
= Model InnerModel
type alias Config =
{ delay : Float
, setOnTyping : Bool
, setOnEnter : Bool
, setOnBlur : Bool
}
defaultConfig : Config
defaultConfig =
{ delay = 1500
, setOnTyping = True
, setOnEnter = True
, setOnBlur = True
}
onEnterOnly : Config
onEnterOnly =
{ defaultConfig | setOnTyping = False, setOnBlur = False }
type alias InnerModel =
{ cfg : Config
, throttle : Throttle Msg
, value : Maybe String
, lastPublished : Maybe String
}
init : Config -> Maybe String -> Model
init cfg str =
Model
{ cfg = cfg
, throttle = Throttle.create 1
, value = str
, lastPublished = str
}
initDefault : Maybe String -> Model
initDefault str =
init defaultConfig str
getValue : Model -> Maybe String
getValue (Model model) =
model.lastPublished
setValue : Model -> String -> ( Model, Sub Msg )
setValue (Model model) str =
let
v =
Util.Maybe.fromString str
inner =
{ model | value = v, lastPublished = v }
in
( Model inner, makeSub inner inner.throttle )
type Msg
= SetText String
| DelayedSet
| UpdateThrottle
| KeyPressed (Maybe KeyCode)
| FocusRemoved
--- Update
type ValueChange
= ValueUpdated (Maybe String)
| ValueUnchanged
type alias Result =
{ model : Model
, change : ValueChange
, cmd : Cmd Msg
, sub : Sub Msg
}
update : Msg -> Model -> Result
update msg (Model model) =
case msg of
SetText str ->
let
maybeStr =
Util.Maybe.fromString str
cmd_ =
Task.succeed () |> Task.perform (\_ -> DelayedSet)
( newThrottle, cmd ) =
if model.cfg.setOnTyping then
Throttle.try cmd_ model.throttle
else
( model.throttle, Cmd.none )
in
{ model = Model { model | value = maybeStr, throttle = newThrottle }
, change = ValueUnchanged
, cmd = cmd
, sub = makeSub model newThrottle
}
UpdateThrottle ->
let
( newThrottle, cmd ) =
Throttle.update model.throttle
in
{ model = Model { model | throttle = newThrottle }
, change = ValueUnchanged
, cmd = cmd
, sub = makeSub model newThrottle
}
DelayedSet ->
if model.lastPublished == model.value then
unit model
else
publishChange model
FocusRemoved ->
if model.cfg.setOnBlur then
publishChange model
else
unit model
KeyPressed (Just Util.Html.Enter) ->
if model.cfg.setOnEnter then
publishChange model
else
unit model
KeyPressed _ ->
unit model
publishChange : InnerModel -> Result
publishChange model =
if model.lastPublished == model.value then
unit model
else
Result (Model { model | lastPublished = model.value })
(ValueUpdated model.value)
Cmd.none
(makeSub model model.throttle)
unit : InnerModel -> Result
unit model =
{ model = Model model
, change = ValueUnchanged
, cmd = Cmd.none
, sub = makeSub model model.throttle
}
makeSub : InnerModel -> Throttle Msg -> Sub Msg
makeSub model newThrottle =
if model.cfg.setOnTyping then
Throttle.ifNeeded
(Time.every model.cfg.delay (\_ -> UpdateThrottle))
newThrottle
else
Sub.none
--- View
inputAttrs : InnerModel -> List (Attribute Msg)
inputAttrs model =
List.filterMap identity
[ type_ "text" |> Just
, onInput SetText |> Just
, if model.cfg.setOnEnter then
Just (onKeyUpCode KeyPressed)
else
Nothing
, onBlur FocusRemoved |> Just
, value (Maybe.withDefault "" model.value) |> Just
]
view : List (Attribute Msg) -> Model -> Html Msg
view extra (Model model) =
let
attrs =
inputAttrs model
in
input
(attrs ++ extra)
[]
viewMap : (Msg -> msg) -> List (Attribute msg) -> Model -> Html msg
viewMap f extra (Model model) =
let
attrs =
inputAttrs model
|> List.map (Html.Attributes.map f)
in
input (attrs ++ extra) []

View File

@ -298,7 +298,7 @@ createQuery : Model -> Maybe Q.ItemQuery
createQuery model =
Q.and
[ Comp.SearchMenu.getItemQuery model.searchMenuModel
, Maybe.map Q.Fragment model.powerSearchInput.input
, Maybe.map Q.Fragment (Comp.PowerSearchInput.getSearchString model.powerSearchInput)
]

View File

@ -115,7 +115,7 @@ update bookmarkId mId key flags texts settings msg model =
doSearch (SearchParam flags BasicSearch settings.itemSearchPageSize 0 False) newModel
else
withSub ( newModel, Cmd.none )
resultModelCmd ( newModel, Cmd.none )
in
{ result
| cmd =
@ -124,6 +124,7 @@ update bookmarkId mId key flags texts settings msg model =
, Cmd.map SearchMenuMsg nextState.cmd
, dropCmd
]
, sub = Sub.map SearchMenuMsg nextState.sub
}
SetLinkTarget lt ->
@ -166,7 +167,7 @@ update bookmarkId mId key flags texts settings msg model =
Nothing ->
model.itemRowsOpen
in
withSub
resultModelCmd
( { model
| itemListModel = result.model
, viewMode = nextView
@ -185,7 +186,7 @@ update bookmarkId mId key flags texts settings msg model =
else
Set.empty
in
noSub ( { model | itemRowsOpen = itemRows, viewMenuOpen = False }, Cmd.none )
resultModelCmd ( { model | itemRowsOpen = itemRows, viewMenuOpen = False }, Cmd.none )
ItemSearchResp scroll (Ok list) ->
let
@ -226,7 +227,7 @@ update bookmarkId mId key flags texts settings msg model =
update bookmarkId mId key flags texts settings (ItemCardListMsg (Comp.ItemCardList.AddResults list)) m
ItemSearchAddResp (Err _) ->
withSub
resultModelCmd
( { model
| moreInProgress = False
}
@ -234,7 +235,7 @@ update bookmarkId mId key flags texts settings msg model =
)
ItemSearchResp _ (Err _) ->
withSub
resultModelCmd
( { model
| searchInProgress = False
}
@ -255,7 +256,7 @@ update bookmarkId mId key flags texts settings msg model =
}
in
if model.searchInProgress then
withSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
else
doSearch param nm
@ -271,7 +272,7 @@ update bookmarkId mId key flags texts settings msg model =
}
in
if model.searchInProgress then
withSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
else
doSearch param model
@ -289,7 +290,7 @@ update bookmarkId mId key flags texts settings msg model =
PublishView q ->
( PublishView q, Cmd.none )
in
withSub
resultModelCmd
( { model
| viewMode = nextView
}
@ -298,10 +299,10 @@ update bookmarkId mId key flags texts settings msg model =
LoadMore ->
if model.moreAvailable then
doSearchMore flags settings model |> withSub
doSearchMore flags settings model |> resultModelCmd
else
withSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
SetBasicSearch str ->
let
@ -322,17 +323,17 @@ update bookmarkId mId key flags texts settings msg model =
update bookmarkId mId key flags texts settings (DoSearch model.searchTypeDropdownValue) model
KeyUpSearchbarMsg _ ->
withSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
ScrollResult _ ->
let
cmd =
Process.sleep 800 |> Task.perform (always ClearItemDetailId)
in
withSub ( model, cmd )
resultModelCmd ( model, cmd )
ClearItemDetailId ->
noSub ( { model | scrollToCard = Nothing }, Cmd.none )
resultModelCmd ( { model | scrollToCard = Nothing }, Cmd.none )
SelectAllItems ->
case model.viewMode of
@ -344,13 +345,13 @@ update bookmarkId mId key flags texts settings msg model =
svm_ =
{ svm | ids = Set.union svm.ids visible }
in
noSub
resultModelCmd
( { model | viewMode = SelectView svm_ }
, Cmd.none
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
SelectNoItems ->
case model.viewMode of
@ -359,13 +360,13 @@ update bookmarkId mId key flags texts settings msg model =
svm_ =
{ svm | ids = Set.empty }
in
noSub
resultModelCmd
( { model | viewMode = SelectView svm_ }
, Cmd.none
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
DeleteSelectedConfirmed ->
case model.viewMode of
@ -374,7 +375,7 @@ update bookmarkId mId key flags texts settings msg model =
cmd =
Api.deleteAllItems flags svm.ids DeleteAllResp
in
noSub
resultModelCmd
( { model
| viewMode =
SelectView
@ -387,7 +388,7 @@ update bookmarkId mId key flags texts settings msg model =
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
RestoreSelectedConfirmed ->
case model.viewMode of
@ -396,7 +397,7 @@ update bookmarkId mId key flags texts settings msg model =
cmd =
Api.restoreAllItems flags svm.ids DeleteAllResp
in
noSub
resultModelCmd
( { model
| viewMode =
SelectView
@ -409,7 +410,7 @@ update bookmarkId mId key flags texts settings msg model =
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
DeleteAllResp (Ok res) ->
if res.success then
@ -428,16 +429,16 @@ update bookmarkId mId key flags texts settings msg model =
doSearch param nm
else
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
DeleteAllResp (Err _) ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
RequestReprocessSelected ->
case model.viewMode of
SelectView svm ->
if svm.ids == Set.empty then
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
else
let
@ -451,15 +452,15 @@ update bookmarkId mId key flags texts settings msg model =
}
}
in
noSub ( model_, Cmd.none )
resultModelCmd ( model_, Cmd.none )
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
CloseConfirmModal ->
case model.viewMode of
SelectView svm ->
noSub
resultModelCmd
( { model
| viewMode = SelectView { svm | confirmModal = Nothing, action = NoneAction }
}
@ -467,20 +468,20 @@ update bookmarkId mId key flags texts settings msg model =
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
ReprocessSelectedConfirmed ->
case model.viewMode of
SelectView svm ->
if svm.ids == Set.empty then
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
else
let
cmd =
Api.reprocessMultiple flags svm.ids DeleteAllResp
in
noSub
resultModelCmd
( { model
| viewMode =
SelectView
@ -493,13 +494,13 @@ update bookmarkId mId key flags texts settings msg model =
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
RequestDeleteSelected ->
case model.viewMode of
SelectView svm ->
if svm.ids == Set.empty then
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
else
let
@ -513,16 +514,16 @@ update bookmarkId mId key flags texts settings msg model =
}
}
in
noSub ( model_, Cmd.none )
resultModelCmd ( model_, Cmd.none )
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
RequestRestoreSelected ->
case model.viewMode of
SelectView svm ->
if svm.ids == Set.empty then
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
else
let
@ -536,37 +537,37 @@ update bookmarkId mId key flags texts settings msg model =
}
}
in
noSub ( model_, Cmd.none )
resultModelCmd ( model_, Cmd.none )
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
EditSelectedItems ->
case model.viewMode of
SelectView svm ->
if svm.action == EditSelected then
noSub
resultModelCmd
( { model | viewMode = SelectView { svm | action = NoneAction } }
, Cmd.none
)
else if svm.ids == Set.empty then
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
else
noSub
resultModelCmd
( { model | viewMode = SelectView { svm | action = EditSelected } }
, Cmd.none
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
MergeSelectedItems ->
case model.viewMode of
SelectView svm ->
if svm.action == MergeSelected then
noSub
resultModelCmd
( { model
| viewMode =
SelectView
@ -579,7 +580,7 @@ update bookmarkId mId key flags texts settings msg model =
)
else if svm.ids == Set.empty then
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
else
let
@ -589,7 +590,7 @@ update bookmarkId mId key flags texts settings msg model =
model.searchMenuModel.searchMode
(Q.ItemIdIn (Set.toList svm.ids))
in
noSub
resultModelCmd
( { model
| viewMode =
SelectView
@ -602,7 +603,7 @@ update bookmarkId mId key flags texts settings msg model =
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
MergeItemsMsg lmsg ->
case model.viewMode of
@ -636,13 +637,13 @@ update bookmarkId mId key flags texts settings msg model =
model_
else
noSub
resultModelCmd
( model_
, Cmd.map MergeItemsMsg result.cmd
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
PublishSelectedItems ->
case model.viewMode of
@ -652,7 +653,7 @@ update bookmarkId mId key flags texts settings msg model =
( mm, mc ) =
Comp.PublishItems.init flags
in
noSub
resultModelCmd
( { model
| viewMode =
SelectView
@ -665,7 +666,7 @@ update bookmarkId mId key flags texts settings msg model =
)
else if svm.ids == Set.empty then
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
else
let
@ -673,7 +674,7 @@ update bookmarkId mId key flags texts settings msg model =
Comp.PublishItems.initQuery flags
(Q.ItemIdIn (Set.toList svm.ids))
in
noSub
resultModelCmd
( { model
| viewMode =
SelectView
@ -686,7 +687,7 @@ update bookmarkId mId key flags texts settings msg model =
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
PublishItemsMsg lmsg ->
case model.viewMode of
@ -717,13 +718,13 @@ update bookmarkId mId key flags texts settings msg model =
model_
else
noSub
resultModelCmd
( model_
, Cmd.map PublishItemsMsg result.cmd
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
EditMenuMsg lmsg ->
case model.viewMode of
@ -773,7 +774,7 @@ update bookmarkId mId key flags texts settings msg model =
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
MultiUpdateResp change (Ok res) ->
let
@ -784,13 +785,13 @@ update bookmarkId mId key flags texts settings msg model =
case model.viewMode of
SelectView svm ->
-- replace changed items in the view
noSub ( nm, loadChangedItems flags model.searchMenuModel.searchMode svm.ids )
resultModelCmd ( nm, loadChangedItems flags model.searchMenuModel.searchMode svm.ids )
_ ->
noSub ( nm, Cmd.none )
resultModelCmd ( nm, Cmd.none )
else
noSub ( nm, Cmd.none )
resultModelCmd ( nm, Cmd.none )
MultiUpdateResp change (Err _) ->
makeResult
@ -800,10 +801,10 @@ update bookmarkId mId key flags texts settings msg model =
)
ReplaceChangedItemsResp (Ok items) ->
noSub ( replaceItems model items, Cmd.none )
resultModelCmd ( replaceItems model items, Cmd.none )
ReplaceChangedItemsResp (Err _) ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
UiSettingsUpdated ->
let
@ -841,7 +842,7 @@ update bookmarkId mId key flags texts settings msg model =
cmd =
Api.saveUserClientSettingsBy flags newSettings ClientSettingsSaveResp
in
noSub ( { model | viewMenuOpen = False }, cmd )
resultModelCmd ( { model | viewMenuOpen = False }, cmd )
ClientSettingsSaveResp (Ok res) ->
if res.success then
@ -852,10 +853,10 @@ update bookmarkId mId key flags texts settings msg model =
}
else
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
ClientSettingsSaveResp (Err _) ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
PowerSearchMsg lm ->
let
@ -879,7 +880,7 @@ update bookmarkId mId key flags texts settings msg model =
update bookmarkId mId key flags texts settings (DoSearch model.searchTypeDropdownValue) model
KeyUpPowerSearchbarMsg _ ->
withSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
RemoveItem id ->
update bookmarkId mId key flags texts settings (ItemCardListMsg (Comp.ItemCardList.RemoveItem id)) model
@ -891,30 +892,30 @@ update bookmarkId mId key flags texts settings msg model =
( pm, pc ) =
Comp.PublishItems.initQuery flags q
in
noSub ( { model | viewMode = PublishView pm, viewMenuOpen = False }, Cmd.map PublishViewMsg pc )
resultModelCmd ( { model | viewMode = PublishView pm, viewMenuOpen = False }, Cmd.map PublishViewMsg pc )
Nothing ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
ToggleBookmarkCurrentQueryView ->
case createQuery model of
Just q ->
case model.topWidgetModel of
BookmarkQuery _ ->
noSub ( { model | topWidgetModel = TopWidgetHidden, viewMenuOpen = False }, Cmd.none )
resultModelCmd ( { model | topWidgetModel = TopWidgetHidden, viewMenuOpen = False }, Cmd.none )
TopWidgetHidden ->
let
( qm, qc ) =
Comp.BookmarkQueryManage.init (Q.render q)
in
noSub
resultModelCmd
( { model | topWidgetModel = BookmarkQuery qm, viewMenuOpen = False }
, Cmd.map BookmarkQueryMsg qc
)
Nothing ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
BookmarkQueryMsg lm ->
case model.topWidgetModel of
@ -952,7 +953,7 @@ update bookmarkId mId key flags texts settings msg model =
)
TopWidgetHidden ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
PublishViewMsg lmsg ->
case model.viewMode of
@ -963,22 +964,22 @@ update bookmarkId mId key flags texts settings msg model =
in
case result.outcome of
Comp.PublishItems.OutcomeInProgress ->
noSub
resultModelCmd
( { model | viewMode = PublishView result.model }
, Cmd.map PublishViewMsg result.cmd
)
Comp.PublishItems.OutcomeDone ->
noSub
resultModelCmd
( { model | viewMode = SearchView }
, Cmd.map SearchMenuMsg (Comp.SearchMenu.refreshBookmarks flags)
)
_ ->
noSub ( model, Cmd.none )
resultModelCmd ( model, Cmd.none )
ToggleViewMenu ->
noSub ( { model | viewMenuOpen = not model.viewMenuOpen }, Cmd.none )
resultModelCmd ( { model | viewMenuOpen = not model.viewMenuOpen }, Cmd.none )
ToggleShowGroups ->
let
@ -988,7 +989,7 @@ update bookmarkId mId key flags texts settings msg model =
cmd =
Api.saveUserClientSettingsBy flags newSettings ClientSettingsSaveResp
in
noSub ( { model | viewMenuOpen = False }, cmd )
resultModelCmd ( { model | viewMenuOpen = False }, cmd )
ToggleArrange am ->
let
@ -998,7 +999,7 @@ update bookmarkId mId key flags texts settings msg model =
cmd =
Api.saveUserClientSettingsBy flags newSettings ClientSettingsSaveResp
in
noSub ( { model | viewMenuOpen = False }, cmd )
resultModelCmd ( { model | viewMenuOpen = False }, cmd )
@ -1115,7 +1116,7 @@ doSearch param model =
searchCmd =
doSearchCmd param_ model
in
withSub
resultModelCmd
( { model
| searchInProgress = True
, searchOffset = 0
@ -1149,17 +1150,8 @@ doSearchMore flags settings model =
)
withSub : ( Model, Cmd Msg ) -> UpdateResult
withSub ( m, c ) =
makeResult
( m
, c
, Sub.none
)
noSub : ( Model, Cmd Msg ) -> UpdateResult
noSub ( m, c ) =
resultModelCmd : ( Model, Cmd Msg ) -> UpdateResult
resultModelCmd ( m, c ) =
makeResult ( m, c, Sub.none )

View File

@ -250,7 +250,6 @@ defaultMenuBar texts flags settings model =
[ Html.map PowerSearchMsg
(Comp.PowerSearchInput.viewInput
{ placeholder = texts.powerSearchPlaceholder
, extraAttrs = []
}
model.powerSearchInput
)

View File

@ -31,7 +31,6 @@ view texts flags model =
[ Html.map PowerSearchMsg
(Comp.PowerSearchInput.viewInput
{ placeholder = texts.powerSearchPlaceholder
, extraAttrs = []
}
model.powerSearchInput
)

View File

@ -266,7 +266,7 @@ makeSearchCmd flags doInit model =
, Maybe.map Q.Fragment <|
case model.searchMode of
SearchBarNormal ->
model.powerSearchInput.input
Comp.PowerSearchInput.getSearchString model.powerSearchInput
SearchBarContent ->
if flags.config.fullTextSearchEnabled then

View File

@ -87,7 +87,6 @@ elmApp.ports.checkSearchQueryString.subscribe(function(args) {
messages: []
};
}
console.log("Sending: " + answer.success);
elmApp.ports.receiveCheckQueryResult.send(answer);
}
});