diff --git a/modules/webapp/src/main/elm/Comp/SearchMenu.elm b/modules/webapp/src/main/elm/Comp/SearchMenu.elm index 8c65c6fb..ab57fcbf 100644 --- a/modules/webapp/src/main/elm/Comp/SearchMenu.elm +++ b/modules/webapp/src/main/elm/Comp/SearchMenu.elm @@ -2,8 +2,12 @@ module Comp.SearchMenu exposing ( Model , Msg(..) , NextState + , TextSearchModel , getItemSearch , init + , isFulltextSearch + , isNamesSearch + , textSearchString , update , updateDrop , view @@ -66,18 +70,21 @@ type alias Model = , untilDueDateModel : DatePicker , untilDueDate : Maybe Int , nameModel : Maybe String - , allNameModel : Maybe String - , fulltextModel : Maybe String + , textSearchModel : TextSearchModel , datePickerInitialized : Bool - , showNameHelp : Bool , customFieldModel : Comp.CustomFieldMultiInput.Model , customValues : CustomFieldValueCollect , sourceModel : Maybe String } -init : Model -init = +type TextSearchModel + = Fulltext (Maybe String) + | Names (Maybe String) + + +init : Flags -> Model +init flags = { tagSelectModel = Comp.TagSelect.init Comp.TagSelect.emptySelection [] , tagSelection = Comp.TagSelect.emptySelection , directionModel = @@ -124,16 +131,87 @@ init = , untilDueDateModel = Comp.DatePicker.emptyModel , untilDueDate = Nothing , nameModel = Nothing - , allNameModel = Nothing - , fulltextModel = Nothing + , textSearchModel = + if flags.config.fullTextSearchEnabled then + Fulltext Nothing + + else + Names Nothing , datePickerInitialized = False - , showNameHelp = False , customFieldModel = Comp.CustomFieldMultiInput.initWith [] , customValues = Data.CustomFieldChange.emptyCollect , sourceModel = Nothing } +updateTextSearch : String -> TextSearchModel -> TextSearchModel +updateTextSearch str model = + let + next = + Util.Maybe.fromString str + in + case model of + Fulltext _ -> + Fulltext next + + Names _ -> + Names next + + +swapTextSearch : TextSearchModel -> TextSearchModel +swapTextSearch model = + case model of + Fulltext s -> + Names s + + Names s -> + Fulltext s + + +textSearchValue : TextSearchModel -> { nameSearch : Maybe String, fullText : Maybe String } +textSearchValue model = + case model of + Fulltext s -> + { nameSearch = Nothing + , fullText = s + } + + Names s -> + { nameSearch = s + , fullText = Nothing + } + + +textSearchString : TextSearchModel -> Maybe String +textSearchString model = + case model of + Fulltext s -> + s + + Names s -> + s + + +isFulltextSearch : Model -> Bool +isFulltextSearch model = + case model.textSearchModel of + Fulltext _ -> + True + + Names _ -> + False + + +isNamesSearch : Model -> Bool +isNamesSearch model = + case model.textSearchModel of + Fulltext _ -> + False + + Names _ -> + True + + getDirection : Model -> Maybe Direction getDirection model = let @@ -164,6 +242,9 @@ getItemSearch model = else "*" ++ s ++ "*" + + textSearch = + textSearchValue model.textSearchModel in { e | tagsInclude = model.tagSelection.includeTags |> List.map .tag |> List.map .id @@ -186,9 +267,9 @@ getItemSearch model = model.nameModel |> Maybe.map amendWildcards , allNames = - model.allNameModel + textSearch.nameSearch |> Maybe.map amendWildcards - , fullText = model.fulltextModel + , fullText = textSearch.fullText , tagCategoriesInclude = model.tagSelection.includeCats |> List.map .name , tagCategoriesExclude = model.tagSelection.excludeCats |> List.map .name , customValues = Data.CustomFieldChange.toFieldValues model.customValues @@ -225,8 +306,13 @@ resetModel model = , fromDueDate = Nothing , untilDueDate = Nothing , nameModel = Nothing - , allNameModel = Nothing - , fulltextModel = Nothing + , textSearchModel = + case model.textSearchModel of + Fulltext _ -> + Fulltext Nothing + + Names _ -> + Names Nothing , customFieldModel = Comp.CustomFieldMultiInput.reset model.customFieldModel @@ -257,11 +343,12 @@ type Msg | GetEquipResp (Result Http.Error EquipmentList) | GetPersonResp (Result Http.Error PersonList) | SetName String - | SetAllName String - | SetFulltext String + | SetTextSearch String + | SwapTextSearch + | SetFulltextSearch + | SetNamesSearch | ResetForm | KeyUpMsg (Maybe KeyCode) - | ToggleNameHelp | FolderSelectMsg Comp.FolderSelect.Msg | GetFolderResp (Result Http.Error FolderList) | SetCorrOrg IdName @@ -641,27 +728,59 @@ updateDrop ddm flags settings msg model = , dragDrop = DD.DragDropData ddm Nothing } - SetAllName str -> - let - next = - Util.Maybe.fromString str - in - { model = { model | allNameModel = next } + SetTextSearch str -> + { model = { model | textSearchModel = updateTextSearch str model.textSearchModel } , cmd = Cmd.none , stateChange = False , dragDrop = DD.DragDropData ddm Nothing } - SetFulltext str -> - let - next = - Util.Maybe.fromString str - in - { model = { model | fulltextModel = next } - , cmd = Cmd.none - , stateChange = False - , dragDrop = DD.DragDropData ddm Nothing - } + SwapTextSearch -> + if flags.config.fullTextSearchEnabled then + { model = { model | textSearchModel = swapTextSearch model.textSearchModel } + , cmd = Cmd.none + , stateChange = False + , dragDrop = DD.DragDropData ddm Nothing + } + + else + { model = model + , cmd = Cmd.none + , stateChange = False + , dragDrop = DD.DragDropData ddm Nothing + } + + SetFulltextSearch -> + case model.textSearchModel of + Fulltext _ -> + { model = model + , cmd = Cmd.none + , stateChange = False + , dragDrop = DD.DragDropData ddm Nothing + } + + Names s -> + { model = { model | textSearchModel = Fulltext s } + , cmd = Cmd.none + , stateChange = False + , dragDrop = DD.DragDropData ddm Nothing + } + + SetNamesSearch -> + case model.textSearchModel of + Fulltext s -> + { model = { model | textSearchModel = Names s } + , cmd = Cmd.none + , stateChange = False + , dragDrop = DD.DragDropData ddm Nothing + } + + Names _ -> + { model = model + , cmd = Cmd.none + , stateChange = False + , dragDrop = DD.DragDropData ddm Nothing + } KeyUpMsg (Just Enter) -> { model = model @@ -677,13 +796,6 @@ updateDrop ddm flags settings msg model = , dragDrop = DD.DragDropData ddm Nothing } - ToggleNameHelp -> - { model = { model | showNameHelp = not model.showNameHelp } - , cmd = Cmd.none - , stateChange = False - , dragDrop = DD.DragDropData ddm Nothing - } - GetFolderResp (Ok fs) -> let model_ = @@ -804,6 +916,54 @@ viewDrop ddd flags settings model = ] ] ] + , div [ class segmentClass ] + [ div + [ class "field" + ] + [ label [] + [ text + (case model.textSearchModel of + Fulltext _ -> + "Fulltext Search" + + Names _ -> + "Search in names" + ) + , a + [ classList + [ ( "right-float", True ) + , ( "invisible hidden", not flags.config.fullTextSearchEnabled ) + ] + , href "#" + , onClick SwapTextSearch + , title "Switch between text search modes" + ] + [ i [ class "small grey exchange alternate icon" ] [] + ] + ] + , input + [ type_ "text" + , onInput SetTextSearch + , Util.Html.onKeyUpCode KeyUpMsg + , textSearchString model.textSearchModel |> Maybe.withDefault "" |> value + , case model.textSearchModel of + Fulltext _ -> + placeholder "Content search…" + + Names _ -> + placeholder "Search in various names…" + ] + [] + , span [ class "small-info" ] + [ case model.textSearchModel of + Fulltext _ -> + text "Fulltext search in document contents and notes." + + Names _ -> + text "Looks in correspondents, concerned entities, item name and notes." + ] + ] + ] , div [ classList [ ( segmentClass, True ) @@ -883,68 +1043,6 @@ viewDrop ddd flags settings model = model.customFieldModel ) ] - , div [ class segmentClass ] - [ formHeader (Icons.searchIcon "") "Text Search" - , div - [ classList - [ ( "field", True ) - , ( "invisible hidden", not flags.config.fullTextSearchEnabled ) - ] - ] - [ label [] [ text "Fulltext Search" ] - , input - [ type_ "text" - , onInput SetFulltext - , Util.Html.onKeyUpCode KeyUpMsg - , model.fulltextModel |> Maybe.withDefault "" |> value - , placeholder "Fulltext search in results…" - ] - [] - , span [ class "small-info" ] - [ text "Fulltext search in document contents and notes." - ] - ] - , div [ class "field" ] - [ label [] - [ text "Names" - , a - [ class "right-float" - , href "#" - , onClick ToggleNameHelp - ] - [ i [ class "small grey help link icon" ] [] - ] - ] - , input - [ type_ "text" - , onInput SetAllName - , Util.Html.onKeyUpCode KeyUpMsg - , model.allNameModel |> Maybe.withDefault "" |> value - , placeholder "Search in various names…" - ] - [] - , span - [ classList - [ ( "small-info", True ) - ] - ] - [ text "Looks in correspondents, concerned entities, item name and notes." - ] - , p - [ classList - [ ( "small-info", True ) - , ( "invisible hidden", not model.showNameHelp ) - ] - ] - [ text "Use wildcards " - , code [] [ text "*" ] - , text " at beginning or end. They are added automatically on both sides " - , text "if not present in the search term and the term is not quoted. Press " - , em [] [ text "Enter" ] - , text " to start searching." - ] - ] - ] , div [ classList [ ( segmentClass, True ) diff --git a/modules/webapp/src/main/elm/Page/Home/Data.elm b/modules/webapp/src/main/elm/Page/Home/Data.elm index 7837b5b8..6c328b6d 100644 --- a/modules/webapp/src/main/elm/Page/Home/Data.elm +++ b/modules/webapp/src/main/elm/Page/Home/Data.elm @@ -6,7 +6,6 @@ module Page.Home.Data exposing , SelectActionMode(..) , SelectViewModel , ViewMode(..) - , defaultSearchType , doSearchCmd , init , initSelectViewModel @@ -20,7 +19,6 @@ module Page.Home.Data exposing import Api import Api.Model.BasicResult exposing (BasicResult) import Api.Model.ItemLightList exposing (ItemLightList) -import Api.Model.ItemSearch import Browser.Dom as Dom import Comp.FixedDropdown import Comp.ItemCardList @@ -52,7 +50,6 @@ type alias Model = , searchTypeDropdown : Comp.FixedDropdown.Model SearchType , searchTypeDropdownValue : SearchType , lastSearchType : SearchType - , contentOnlySearch : Maybe String , dragDropData : DD.DragDropData , scrollToCard : Maybe String } @@ -88,6 +85,9 @@ type ViewMode init : Flags -> ViewMode -> Model init flags viewMode = let + searchMenuModel = + Comp.SearchMenu.init flags + searchTypeOptions = if flags.config.fullTextSearchEnabled then [ BasicSearch, ContentOnlySearch ] @@ -95,7 +95,7 @@ init flags viewMode = else [ BasicSearch ] in - { searchMenuModel = Comp.SearchMenu.init + { searchMenuModel = searchMenuModel , itemListModel = Comp.ItemCardList.init , searchInProgress = False , searchOffset = 0 @@ -105,9 +105,13 @@ init flags viewMode = , searchTypeDropdown = Comp.FixedDropdown.initMap searchTypeString searchTypeOptions - , searchTypeDropdownValue = defaultSearchType flags + , searchTypeDropdownValue = + if Comp.SearchMenu.isFulltextSearch searchMenuModel then + ContentOnlySearch + + else + BasicSearch , lastSearchType = BasicSearch - , contentOnlySearch = Nothing , dragDropData = DD.DragDropData DD.init Nothing , scrollToCard = Nothing @@ -115,15 +119,6 @@ init flags viewMode = } -defaultSearchType : Flags -> SearchType -defaultSearchType flags = - if flags.config.fullTextSearchEnabled then - ContentOnlySearch - - else - BasicSearch - - menuCollapsed : Model -> Bool menuCollapsed model = case model.viewMode of @@ -165,7 +160,6 @@ type Msg | SetBasicSearch String | SearchTypeMsg (Comp.FixedDropdown.Msg SearchType) | KeyUpSearchbarMsg (Maybe KeyCode) - | SetContentOnly String | ScrollResult (Result Dom.Error ()) | ClearItemDetailId | SelectAllItems @@ -227,12 +221,7 @@ itemNav id model = doSearchCmd : SearchParam -> Model -> Cmd Msg doSearchCmd param model = - case param.searchType of - BasicSearch -> - doSearchDefaultCmd param model - - ContentOnlySearch -> - doSearchIndexCmd param model + doSearchDefaultCmd param model doSearchDefaultCmd : SearchParam -> Model -> Cmd Msg @@ -254,36 +243,6 @@ doSearchDefaultCmd param model = Api.itemSearch param.flags mask ItemSearchAddResp -doSearchIndexCmd : SearchParam -> Model -> Cmd Msg -doSearchIndexCmd param model = - case model.contentOnlySearch of - Just q -> - let - mask = - { query = q - , limit = param.pageSize - , offset = param.offset - } - in - if param.offset == 0 then - Api.itemIndexSearch param.flags mask (ItemSearchResp param.scroll) - - else - Api.itemIndexSearch param.flags mask ItemSearchAddResp - - Nothing -> - -- If there is no fulltext query, render simply the most - -- current ones - let - emptyMask = - Api.Model.ItemSearch.empty - - mask = - { emptyMask | limit = param.pageSize } - in - Api.itemSearch param.flags mask (ItemSearchResp param.scroll) - - resultsBelowLimit : UiSettings -> Model -> Bool resultsBelowLimit settings model = let diff --git a/modules/webapp/src/main/elm/Page/Home/Update.elm b/modules/webapp/src/main/elm/Page/Home/Update.elm index a2f5dc6d..6b01115f 100644 --- a/modules/webapp/src/main/elm/Page/Home/Update.elm +++ b/modules/webapp/src/main/elm/Page/Home/Update.elm @@ -52,10 +52,7 @@ update mId key flags settings msg model = ResetSearch -> let nm = - { model - | searchOffset = 0 - , contentOnlySearch = Nothing - } + { model | searchOffset = 0 } in update mId key flags settings (SearchMenuMsg Comp.SearchMenu.ResetForm) nm @@ -76,6 +73,12 @@ update mId key flags settings msg model = { model | searchMenuModel = nextState.model , dragDropData = nextState.dragDrop + , searchTypeDropdownValue = + if Comp.SearchMenu.isFulltextSearch nextState.model then + ContentOnlySearch + + else + BasicSearch } ( m2, c2, s2 ) = @@ -261,21 +264,10 @@ update mId key flags settings msg model = SetBasicSearch str -> let smMsg = - case model.searchTypeDropdownValue of - BasicSearch -> - SearchMenuMsg (Comp.SearchMenu.SetAllName str) - - ContentOnlySearch -> - SetContentOnly str + SearchMenuMsg (Comp.SearchMenu.SetTextSearch str) in update mId key flags settings smMsg model - SetContentOnly str -> - withSub - ( { model | contentOnlySearch = Util.Maybe.fromString str } - , Cmd.none - ) - SearchTypeMsg lm -> let ( sm, mv ) = @@ -293,23 +285,17 @@ update mId key flags settings msg model = next = case mvChange of Just BasicSearch -> - Just - ( { m0 | contentOnlySearch = Nothing } - , Maybe.withDefault "" model.contentOnlySearch - ) + Just Comp.SearchMenu.SetNamesSearch Just ContentOnlySearch -> - Just - ( { m0 | contentOnlySearch = model.searchMenuModel.allNameModel } - , "" - ) + Just Comp.SearchMenu.SetFulltextSearch _ -> Nothing in case next of - Just ( m_, nstr ) -> - update mId key flags settings (SearchMenuMsg (Comp.SearchMenu.SetAllName nstr)) m_ + Just lm_ -> + update mId key flags settings (SearchMenuMsg lm_) m0 Nothing -> withSub ( m0, Cmd.none ) diff --git a/modules/webapp/src/main/elm/Page/Home/View.elm b/modules/webapp/src/main/elm/Page/Home/View.elm index f2adfe63..b59fcb8e 100644 --- a/modules/webapp/src/main/elm/Page/Home/View.elm +++ b/modules/webapp/src/main/elm/Page/Home/View.elm @@ -285,12 +285,8 @@ viewSearchBar flags model = (searchTypeString model.searchTypeDropdownValue) searchInput = - case model.searchTypeDropdownValue of - BasicSearch -> - model.searchMenuModel.allNameModel - - ContentOnlySearch -> - model.contentOnlySearch + Comp.SearchMenu.textSearchString + model.searchMenuModel.textSearchModel searchTypeClass = if flags.config.fullTextSearchEnabled then @@ -328,7 +324,7 @@ viewSearchBar flags model = , href "#" , onClick (DoSearch model.searchTypeDropdownValue) ] - (if hasMoreSearch model && model.searchTypeDropdownValue == BasicSearch then + (if hasMoreSearch model then [ i [ class "icons search-corner-icons" ] [ i [ class "tiny blue circle icon" ] [] ] @@ -339,7 +335,14 @@ viewSearchBar flags model = ) , input [ type_ "text" - , placeholder "Quick Search …" + , placeholder + (case model.searchTypeDropdownValue of + ContentOnlySearch -> + "Content search…" + + BasicSearch -> + "Search in names…" + ) , onInput SetBasicSearch , Util.Html.onKeyUpCode KeyUpSearchbarMsg , Maybe.map value searchInput @@ -381,12 +384,7 @@ hasMoreSearch model = Comp.SearchMenu.getItemSearch model.searchMenuModel is_ = - case model.lastSearchType of - BasicSearch -> - { is | allNames = Nothing } - - ContentOnlySearch -> - Api.Model.ItemSearch.empty + { is | allNames = Nothing, fullText = Nothing } in is_ /= Api.Model.ItemSearch.empty