mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-05 22:55:58 +00:00
Start search by pressing enter and not on each stroke
This reduces (unecessary) requests and eases the restless list rendering. Throttling is still in place to avoid too many requests when e.g. holding the enter-key.
This commit is contained in:
parent
6c8abf4cd7
commit
5e77ff0fc5
@ -25,8 +25,9 @@ import Data.UiSettings exposing (UiSettings)
|
|||||||
import DatePicker exposing (DatePicker)
|
import DatePicker exposing (DatePicker)
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onCheck, onInput)
|
import Html.Events exposing (onCheck, onClick, onInput)
|
||||||
import Http
|
import Http
|
||||||
|
import Util.Html exposing (KeyCode(..))
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
import Util.Tag
|
import Util.Tag
|
||||||
import Util.Update
|
import Util.Update
|
||||||
@ -57,6 +58,7 @@ type alias Model =
|
|||||||
, allNameModel : Maybe String
|
, allNameModel : Maybe String
|
||||||
, fulltextModel : Maybe String
|
, fulltextModel : Maybe String
|
||||||
, datePickerInitialized : Bool
|
, datePickerInitialized : Bool
|
||||||
|
, showNameHelp : Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -114,6 +116,7 @@ init =
|
|||||||
, allNameModel = Nothing
|
, allNameModel = Nothing
|
||||||
, fulltextModel = Nothing
|
, fulltextModel = Nothing
|
||||||
, datePickerInitialized = False
|
, datePickerInitialized = False
|
||||||
|
, showNameHelp = False
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -139,6 +142,8 @@ type Msg
|
|||||||
| SetAllName String
|
| SetAllName String
|
||||||
| SetFulltext String
|
| SetFulltext String
|
||||||
| ResetForm
|
| ResetForm
|
||||||
|
| KeyUpMsg (Maybe KeyCode)
|
||||||
|
| ToggleNameHelp
|
||||||
|
|
||||||
|
|
||||||
getDirection : Model -> Maybe Direction
|
getDirection : Model -> Maybe Direction
|
||||||
@ -475,7 +480,7 @@ update flags settings msg model =
|
|||||||
( { model | nameModel = next }
|
( { model | nameModel = next }
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
(model.nameModel /= next)
|
(model.nameModel /= Nothing && str == "")
|
||||||
|
|
||||||
SetAllName str ->
|
SetAllName str ->
|
||||||
let
|
let
|
||||||
@ -486,7 +491,7 @@ update flags settings msg model =
|
|||||||
( { model | allNameModel = next }
|
( { model | allNameModel = next }
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
(model.allNameModel /= next)
|
(model.allNameModel /= Nothing && str == "")
|
||||||
|
|
||||||
SetFulltext str ->
|
SetFulltext str ->
|
||||||
let
|
let
|
||||||
@ -497,7 +502,16 @@ update flags settings msg model =
|
|||||||
( { model | fulltextModel = next }
|
( { model | fulltextModel = next }
|
||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
(model.fulltextModel /= next)
|
(model.fulltextModel /= Nothing && str == "")
|
||||||
|
|
||||||
|
KeyUpMsg (Just Enter) ->
|
||||||
|
NextState ( model, Cmd.none ) True
|
||||||
|
|
||||||
|
KeyUpMsg _ ->
|
||||||
|
NextState ( model, Cmd.none ) False
|
||||||
|
|
||||||
|
ToggleNameHelp ->
|
||||||
|
NextState ( { model | showNameHelp = not model.showNameHelp }, Cmd.none ) False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -515,6 +529,21 @@ view flags settings model =
|
|||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
formHeaderHelp icon headline tagger =
|
||||||
|
div [ class "ui small dividing header" ]
|
||||||
|
[ a
|
||||||
|
[ class "right-float"
|
||||||
|
, href "#"
|
||||||
|
, onClick tagger
|
||||||
|
]
|
||||||
|
[ i [ class "small grey help link icon" ] []
|
||||||
|
]
|
||||||
|
, icon
|
||||||
|
, div [ class "content" ]
|
||||||
|
[ text headline
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
nameIcon =
|
nameIcon =
|
||||||
i [ class "left align icon" ] []
|
i [ class "left align icon" ] []
|
||||||
in
|
in
|
||||||
@ -542,6 +571,7 @@ view flags settings model =
|
|||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, onInput SetFulltext
|
, onInput SetFulltext
|
||||||
|
, Util.Html.onKeyUpCode KeyUpMsg
|
||||||
, model.fulltextModel |> Maybe.withDefault "" |> value
|
, model.fulltextModel |> Maybe.withDefault "" |> value
|
||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
@ -549,17 +579,36 @@ view flags settings model =
|
|||||||
[ text "Fulltext search in document contents."
|
[ text "Fulltext search in document contents."
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, formHeader nameIcon "Names"
|
, formHeaderHelp nameIcon "Names" ToggleNameHelp
|
||||||
|
, span
|
||||||
|
[ classList
|
||||||
|
[ ( "small-info", True )
|
||||||
|
, ( "invisible hidden", not model.showNameHelp )
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[ text "Use wildcards "
|
||||||
|
, code [] [ text "*" ]
|
||||||
|
, text " at beginning or end. Added automatically if not "
|
||||||
|
, text "present and not quoted. Press "
|
||||||
|
, em [] [ text "Enter" ]
|
||||||
|
, text " to start searching."
|
||||||
|
]
|
||||||
, div [ class "field" ]
|
, div [ class "field" ]
|
||||||
[ label [] [ text "All Names" ]
|
[ label [] [ text "All Names" ]
|
||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, onInput SetAllName
|
, onInput SetAllName
|
||||||
|
, Util.Html.onKeyUpCode KeyUpMsg
|
||||||
, model.allNameModel |> Maybe.withDefault "" |> value
|
, model.allNameModel |> Maybe.withDefault "" |> value
|
||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
, span [ class "small-info" ]
|
, span
|
||||||
[ text "Looks in correspondents, concerned, item name and notes."
|
[ classList
|
||||||
|
[ ( "small-info", True )
|
||||||
|
, ( "invisible hidden", not model.showNameHelp )
|
||||||
|
]
|
||||||
|
]
|
||||||
|
[ text "Looks in correspondents, concerned entities, item name and notes."
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "field" ]
|
, div [ class "field" ]
|
||||||
@ -567,18 +616,18 @@ view flags settings model =
|
|||||||
, input
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, onInput SetName
|
, onInput SetName
|
||||||
|
, Util.Html.onKeyUpCode KeyUpMsg
|
||||||
, model.nameModel |> Maybe.withDefault "" |> value
|
, model.nameModel |> Maybe.withDefault "" |> value
|
||||||
]
|
]
|
||||||
[]
|
[]
|
||||||
, span [ class "small-info" ]
|
, span
|
||||||
[ text "Looks in item name."
|
[ classList
|
||||||
|
[ ( "small-info", True )
|
||||||
|
, ( "invisible hidden", not model.showNameHelp )
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, span [ class "small-info" ]
|
[ text "Looks in item name only."
|
||||||
[ text "Use wildcards "
|
]
|
||||||
, code [] [ text "*" ]
|
|
||||||
, text " at beginning or end. Added automatically if not "
|
|
||||||
, text "present and not quoted."
|
|
||||||
]
|
]
|
||||||
, formHeader (Icons.tagsIcon "") "Tags"
|
, formHeader (Icons.tagsIcon "") "Tags"
|
||||||
, div [ class "field" ]
|
, div [ class "field" ]
|
||||||
|
@ -20,6 +20,7 @@ import Data.Items
|
|||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
import Http
|
import Http
|
||||||
import Throttle exposing (Throttle)
|
import Throttle exposing (Throttle)
|
||||||
|
import Util.Html exposing (KeyCode(..))
|
||||||
|
|
||||||
|
|
||||||
type alias Model =
|
type alias Model =
|
||||||
@ -83,6 +84,7 @@ type Msg
|
|||||||
| UpdateThrottle
|
| UpdateThrottle
|
||||||
| SetBasicSearch String
|
| SetBasicSearch String
|
||||||
| SearchTypeMsg (Comp.FixedDropdown.Msg SearchType)
|
| SearchTypeMsg (Comp.FixedDropdown.Msg SearchType)
|
||||||
|
| KeyUpMsg (Maybe KeyCode)
|
||||||
|
|
||||||
|
|
||||||
type SearchType
|
type SearchType
|
||||||
|
@ -10,6 +10,7 @@ import Page exposing (Page(..))
|
|||||||
import Page.Home.Data exposing (..)
|
import Page.Home.Data exposing (..)
|
||||||
import Throttle
|
import Throttle
|
||||||
import Time
|
import Time
|
||||||
|
import Util.Html exposing (KeyCode(..))
|
||||||
import Util.Update
|
import Util.Update
|
||||||
|
|
||||||
|
|
||||||
@ -177,6 +178,12 @@ update key flags settings msg model =
|
|||||||
, Cmd.none
|
, Cmd.none
|
||||||
)
|
)
|
||||||
|
|
||||||
|
KeyUpMsg (Just Enter) ->
|
||||||
|
update key flags settings DoSearch model
|
||||||
|
|
||||||
|
KeyUpMsg _ ->
|
||||||
|
withSub ( model, Cmd.none )
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- Helpers
|
--- Helpers
|
||||||
@ -218,6 +225,6 @@ withSub ( m, c ) =
|
|||||||
( m
|
( m
|
||||||
, c
|
, c
|
||||||
, Throttle.ifNeeded
|
, Throttle.ifNeeded
|
||||||
(Time.every 150 (\_ -> UpdateThrottle))
|
(Time.every 500 (\_ -> UpdateThrottle))
|
||||||
m.throttle
|
m.throttle
|
||||||
)
|
)
|
||||||
|
@ -11,6 +11,7 @@ import Html.Attributes exposing (..)
|
|||||||
import Html.Events exposing (onClick, onInput)
|
import Html.Events exposing (onClick, onInput)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Page.Home.Data exposing (..)
|
import Page.Home.Data exposing (..)
|
||||||
|
import Util.Html
|
||||||
|
|
||||||
|
|
||||||
view : Flags -> UiSettings -> Model -> Html Msg
|
view : Flags -> UiSettings -> Model -> Html Msg
|
||||||
@ -165,12 +166,22 @@ viewSearchBar flags model =
|
|||||||
span [ class "hidden invisible" ] []
|
span [ class "hidden invisible" ] []
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
, div [ class "ui category search item" ]
|
, div [ class "item" ]
|
||||||
[ div [ class "ui action input" ]
|
[ div [ class "ui left icon right action input" ]
|
||||||
[ input
|
[ i
|
||||||
|
[ classList
|
||||||
|
[ ( "search link icon", not model.searchInProgress )
|
||||||
|
, ( "loading spinner icon", model.searchInProgress )
|
||||||
|
]
|
||||||
|
, href "#"
|
||||||
|
, onClick DoSearch
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
, input
|
||||||
[ type_ "text"
|
[ type_ "text"
|
||||||
, placeholder "Search …"
|
, placeholder "Search …"
|
||||||
, onInput SetBasicSearch
|
, onInput SetBasicSearch
|
||||||
|
, Util.Html.onKeyUpCode KeyUpMsg
|
||||||
, Maybe.map value searchInput
|
, Maybe.map value searchInput
|
||||||
|> Maybe.withDefault (value "")
|
|> Maybe.withDefault (value "")
|
||||||
]
|
]
|
||||||
@ -180,19 +191,6 @@ viewSearchBar flags model =
|
|||||||
(Just searchTypeItem)
|
(Just searchTypeItem)
|
||||||
model.searchTypeDropdown
|
model.searchTypeDropdown
|
||||||
)
|
)
|
||||||
, a
|
|
||||||
[ class "ui basic icon button"
|
|
||||||
, href "#"
|
|
||||||
, onClick DoSearch
|
|
||||||
]
|
|
||||||
[ i
|
|
||||||
[ classList
|
|
||||||
[ ( "search link icon", not model.searchInProgress )
|
|
||||||
, ( "loading spinner icon", model.searchInProgress )
|
|
||||||
]
|
|
||||||
]
|
|
||||||
[]
|
|
||||||
]
|
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
@ -205,6 +203,14 @@ hasMoreSearch model =
|
|||||||
Comp.SearchMenu.getItemSearch model.searchMenuModel
|
Comp.SearchMenu.getItemSearch model.searchMenuModel
|
||||||
|
|
||||||
is_ =
|
is_ =
|
||||||
{ is | allNames = Nothing, fullText = Nothing }
|
case model.searchType of
|
||||||
|
BasicSearch ->
|
||||||
|
{ is | allNames = Nothing }
|
||||||
|
|
||||||
|
ContentSearch ->
|
||||||
|
{ is | fullText = Nothing }
|
||||||
|
|
||||||
|
ContentOnlySearch ->
|
||||||
|
Debug.todo "implement"
|
||||||
in
|
in
|
||||||
is_ /= Api.Model.ItemSearch.empty
|
is_ /= Api.Model.ItemSearch.empty
|
||||||
|
@ -9,6 +9,7 @@ module Util.Html exposing
|
|||||||
, onDragOver
|
, onDragOver
|
||||||
, onDropFiles
|
, onDropFiles
|
||||||
, onKeyUp
|
, onKeyUp
|
||||||
|
, onKeyUpCode
|
||||||
)
|
)
|
||||||
|
|
||||||
import File exposing (File)
|
import File exposing (File)
|
||||||
@ -76,6 +77,11 @@ onKeyUp tagger =
|
|||||||
on "keyup" (D.map tagger keyCode)
|
on "keyup" (D.map tagger keyCode)
|
||||||
|
|
||||||
|
|
||||||
|
onKeyUpCode : (Maybe KeyCode -> msg) -> Attribute msg
|
||||||
|
onKeyUpCode tagger =
|
||||||
|
onKeyUp (intToKeyCode >> tagger)
|
||||||
|
|
||||||
|
|
||||||
onClickk : msg -> Attribute msg
|
onClickk : msg -> Attribute msg
|
||||||
onClickk msg =
|
onClickk msg =
|
||||||
Html.Events.preventDefaultOn "click" (D.map alwaysPreventDefault (D.succeed msg))
|
Html.Events.preventDefaultOn "click" (D.map alwaysPreventDefault (D.succeed msg))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user