diff --git a/modules/store/src/main/scala/docspell/store/queries/QItem.scala b/modules/store/src/main/scala/docspell/store/queries/QItem.scala index 66203292..b5f456c4 100644 --- a/modules/store/src/main/scala/docspell/store/queries/QItem.scala +++ b/modules/store/src/main/scala/docspell/store/queries/QItem.scala @@ -442,7 +442,7 @@ object QItem { cfields <- Stream.eval(findCustomFieldValuesForItem(item.id)) } yield ListItemWithTags( item, - ftags.toList.sortBy(_.name), + RTag.sort(ftags.toList), attachs.sortBy(_.position), cfields.toList ) diff --git a/modules/store/src/main/scala/docspell/store/records/RTag.scala b/modules/store/src/main/scala/docspell/store/records/RTag.scala index 44b0e617..b9e9ab27 100644 --- a/modules/store/src/main/scala/docspell/store/records/RTag.scala +++ b/modules/store/src/main/scala/docspell/store/records/RTag.scala @@ -164,4 +164,23 @@ object RTag { def delete(tagId: Ident, coll: Ident): ConnectionIO[Int] = DML.delete(T, T.tid === tagId && T.cid === coll) + + def sort(tags: List[RTag]): List[RTag] = + tags match { + case Nil => tags + case _ => + val byCat = tags + .groupBy(_.category) + .view + .mapValues(_.sortBy(_.name)) + .toList + .sortBy(_._1) + + byCat match { + case (None, tags) :: rest => + rest.flatMap(_._2) ++ tags + case _ => + byCat.flatMap(_._2) + } + } } diff --git a/modules/webapp/src/main/elm/Comp/BookmarkManage.elm b/modules/webapp/src/main/elm/Comp/BookmarkManage.elm index bbec3aa7..a57dcb65 100644 --- a/modules/webapp/src/main/elm/Comp/BookmarkManage.elm +++ b/modules/webapp/src/main/elm/Comp/BookmarkManage.elm @@ -257,6 +257,7 @@ viewTable texts model = } ] , rootClasses = "mb-4" + , sticky = True } , div [ class "flex flex-col" @@ -301,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 = @@ -334,6 +335,7 @@ viewForm texts _ _ model = else [] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/BookmarkQueryForm.elm b/modules/webapp/src/main/elm/Comp/BookmarkQueryForm.elm index 1cf6d8ea..61b47f1e 100644 --- a/modules/webapp/src/main/elm/Comp/BookmarkQueryForm.elm +++ b/modules/webapp/src/main/elm/Comp/BookmarkQueryForm.elm @@ -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 -> @@ -153,19 +166,9 @@ update flags msg model = , Sub.none ) - NameExistsResp (Err err) -> + 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" diff --git a/modules/webapp/src/main/elm/Comp/BoxSearchQueryInput.elm b/modules/webapp/src/main/elm/Comp/BoxSearchQueryInput.elm index 217c0bdc..ad270ca4 100644 --- a/modules/webapp/src/main/elm/Comp/BoxSearchQueryInput.elm +++ b/modules/webapp/src/main/elm/Comp/BoxSearchQueryInput.elm @@ -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" ] diff --git a/modules/webapp/src/main/elm/Comp/CollectiveSettingsForm.elm b/modules/webapp/src/main/elm/Comp/CollectiveSettingsForm.elm index f7994b4a..f1bf41a9 100644 --- a/modules/webapp/src/main/elm/Comp/CollectiveSettingsForm.elm +++ b/modules/webapp/src/main/elm/Comp/CollectiveSettingsForm.elm @@ -352,6 +352,7 @@ view2 flags texts settings model = ] , end = [] , rootClasses = "mb-4" + , sticky = True } , h2 [ class S.header2 ] [ text texts.documentLanguage diff --git a/modules/webapp/src/main/elm/Comp/CustomFieldForm.elm b/modules/webapp/src/main/elm/Comp/CustomFieldForm.elm index aaffa2a1..a07a1506 100644 --- a/modules/webapp/src/main/elm/Comp/CustomFieldForm.elm +++ b/modules/webapp/src/main/elm/Comp/CustomFieldForm.elm @@ -416,4 +416,5 @@ viewButtons2 texts model = else [] , rootClasses = "mb-4" + , sticky = True } diff --git a/modules/webapp/src/main/elm/Comp/CustomFieldInput.elm b/modules/webapp/src/main/elm/Comp/CustomFieldInput.elm index e55d8fc6..b7d26faf 100644 --- a/modules/webapp/src/main/elm/Comp/CustomFieldInput.elm +++ b/modules/webapp/src/main/elm/Comp/CustomFieldInput.elm @@ -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) diff --git a/modules/webapp/src/main/elm/Comp/CustomFieldManage.elm b/modules/webapp/src/main/elm/Comp/CustomFieldManage.elm index ab0a8796..e648b9c2 100644 --- a/modules/webapp/src/main/elm/Comp/CustomFieldManage.elm +++ b/modules/webapp/src/main/elm/Comp/CustomFieldManage.elm @@ -233,6 +233,7 @@ viewTable2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.CustomFieldTable.view2 texts.fieldTable diff --git a/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm b/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm index 6a60260e..59079f16 100644 --- a/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm +++ b/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm @@ -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 diff --git a/modules/webapp/src/main/elm/Comp/DashboardEdit.elm b/modules/webapp/src/main/elm/Comp/DashboardEdit.elm index e025079d..354ea035 100644 --- a/modules/webapp/src/main/elm/Comp/DashboardEdit.elm +++ b/modules/webapp/src/main/elm/Comp/DashboardEdit.elm @@ -347,6 +347,7 @@ view texts flags settings model = } ] , rootClasses = "mb-2" + , sticky = True } , div [ class (gridStyle model.dashboard) diff --git a/modules/webapp/src/main/elm/Comp/DashboardManage.elm b/modules/webapp/src/main/elm/Comp/DashboardManage.elm index ee8f63e7..096bf849 100644 --- a/modules/webapp/src/main/elm/Comp/DashboardManage.elm +++ b/modules/webapp/src/main/elm/Comp/DashboardManage.elm @@ -285,6 +285,7 @@ view texts flags cfg settings model = } ] , rootClasses = "" + , sticky = True } , div [ class S.errorMessage diff --git a/modules/webapp/src/main/elm/Comp/DueItemsTaskForm.elm b/modules/webapp/src/main/elm/Comp/DueItemsTaskForm.elm index da412623..fe9268ce 100644 --- a/modules/webapp/src/main/elm/Comp/DueItemsTaskForm.elm +++ b/modules/webapp/src/main/elm/Comp/DueItemsTaskForm.elm @@ -483,6 +483,7 @@ view2 texts extraClasses settings model = [ startOnceBtn ] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/DueItemsTaskManage.elm b/modules/webapp/src/main/elm/Comp/DueItemsTaskManage.elm index 3846b9b4..346482e2 100644 --- a/modules/webapp/src/main/elm/Comp/DueItemsTaskManage.elm +++ b/modules/webapp/src/main/elm/Comp/DueItemsTaskManage.elm @@ -296,6 +296,7 @@ viewList2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map ListMsg (Comp.DueItemsTaskList.view2 texts.notificationTable diff --git a/modules/webapp/src/main/elm/Comp/EmailSettingsManage.elm b/modules/webapp/src/main/elm/Comp/EmailSettingsManage.elm index 415a5dac..1cecc4f4 100644 --- a/modules/webapp/src/main/elm/Comp/EmailSettingsManage.elm +++ b/modules/webapp/src/main/elm/Comp/EmailSettingsManage.elm @@ -251,6 +251,7 @@ viewTable2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.EmailSettingsTable.view2 texts.settingsTable @@ -296,6 +297,7 @@ viewForm2 texts settings model = else [] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/EquipmentManage.elm b/modules/webapp/src/main/elm/Comp/EquipmentManage.elm index 76d3034c..40035e25 100644 --- a/modules/webapp/src/main/elm/Comp/EquipmentManage.elm +++ b/modules/webapp/src/main/elm/Comp/EquipmentManage.elm @@ -268,6 +268,7 @@ viewTable2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.EquipmentTable.view2 texts.equipmentTable @@ -347,6 +348,7 @@ viewForm2 texts model = else [] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/FolderDetail.elm b/modules/webapp/src/main/elm/Comp/FolderDetail.elm index 2253d747..ed3049f3 100644 --- a/modules/webapp/src/main/elm/Comp/FolderDetail.elm +++ b/modules/webapp/src/main/elm/Comp/FolderDetail.elm @@ -373,91 +373,91 @@ view2 texts flags model = texts.basics.no in div [ class "flex flex-col md:relative" ] - (viewButtons2 texts model - :: [ Html.map DeleteMsg - (Comp.YesNoDimmer.viewN - True - dimmerSettings - model.deleteDimmer - ) - , div - [ class "py-2 text-lg opacity-75" - , classList [ ( "hidden", model.folder.id /= "" ) ] + ([ viewButtons2 texts model + , Html.map DeleteMsg + (Comp.YesNoDimmer.viewN + True + dimmerSettings + model.deleteDimmer + ) + , div + [ class "py-2 text-lg opacity-75" + , classList [ ( "hidden", model.folder.id /= "" ) ] + ] + [ text texts.autoOwnerInfo + ] + , div + [ class "py-2 text-lg opacity-75" + , classList [ ( "hidden", model.folder.id == "" ) ] + ] + [ text texts.modifyInfo + ] + , div + [ class S.message + , classList [ ( "hidden", model.folder.id == "" || isOwner ) ] + ] + [ text texts.notOwnerInfo + ] + , div [ class "mb-4 flex flex-col" ] + [ label + [ class S.inputLabel + , for "folder-name" + ] + [ text texts.basics.name + , B.inputRequired + ] + , div [ class "flex flex-row space-x-2" ] + [ input + [ type_ "text" + , onInput SetName + , Maybe.withDefault "" model.name + |> value + , classList [ ( S.inputErrorBorder, model.name == Nothing ) ] + , class S.textInput + , id "folder-name" ] - [ text texts.autoOwnerInfo + [] + , a + [ class S.primaryButton + , class "rounded-r -ml-1" + , onClick SaveName + , href "#" ] - , div - [ class "py-2 text-lg opacity-75" - , classList [ ( "hidden", model.folder.id == "" ) ] - ] - [ text texts.modifyInfo - ] - , div - [ class S.message - , classList [ ( "hidden", model.folder.id == "" || isOwner ) ] - ] - [ text texts.notOwnerInfo - ] - , div [ class "mb-4 flex flex-col" ] - [ label - [ class S.inputLabel - , for "folder-name" - ] - [ text texts.basics.name - , B.inputRequired - ] - , div [ class "flex flex-row space-x-2" ] - [ input - [ type_ "text" - , onInput SetName - , Maybe.withDefault "" model.name - |> value - , classList [ ( S.inputErrorBorder, model.name == Nothing ) ] - , class S.textInput - , id "folder-name" - ] - [] - , a - [ class S.primaryButton - , class "rounded-r -ml-1" - , onClick SaveName - , href "#" - ] - [ i [ class "fa fa-save" ] [] - , span [ class "ml-2 hidden sm:inline" ] - [ text texts.basics.submit - ] - ] + [ i [ class "fa fa-save" ] [] + , span [ class "ml-2 hidden sm:inline" ] + [ text texts.basics.submit ] ] - , div - [ classList - [ ( "hidden", model.formState == FormStateInitial ) - , ( S.errorMessage, isError model.formState ) - , ( S.successMessage, isSuccess model.formState ) - ] - , class "my-4" - ] - [ case model.formState of - FormStateInitial -> - text "" + ] + ] + , div + [ classList + [ ( "hidden", model.formState == FormStateInitial ) + , ( S.errorMessage, isError model.formState ) + , ( S.successMessage, isSuccess model.formState ) + ] + , class "my-4" + ] + [ case model.formState of + FormStateInitial -> + text "" - FormStateHttpError err -> - text (texts.httpError err) + FormStateHttpError err -> + text (texts.httpError err) - FormStateGenericError m -> - text m + FormStateGenericError m -> + text m - FormStateFolderCreated -> - text texts.folderCreated + FormStateFolderCreated -> + text texts.folderCreated - FormStateNameChangeSuccessful -> - text texts.nameChangeSuccessful + FormStateNameChangeSuccessful -> + text texts.nameChangeSuccessful - FormStateDeleteSuccessful -> - text texts.deleteSuccessful - ] - ] + FormStateDeleteSuccessful -> + text texts.deleteSuccessful + ] + ] ++ viewMembers2 texts model ) @@ -558,4 +558,5 @@ viewButtons2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } diff --git a/modules/webapp/src/main/elm/Comp/FolderManage.elm b/modules/webapp/src/main/elm/Comp/FolderManage.elm index 33e9cb1d..5770ef17 100644 --- a/modules/webapp/src/main/elm/Comp/FolderManage.elm +++ b/modules/webapp/src/main/elm/Comp/FolderManage.elm @@ -265,6 +265,7 @@ viewTable2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.FolderTable.view2 diff --git a/modules/webapp/src/main/elm/Comp/ImapSettingsManage.elm b/modules/webapp/src/main/elm/Comp/ImapSettingsManage.elm index bcde7af6..300c12a8 100644 --- a/modules/webapp/src/main/elm/Comp/ImapSettingsManage.elm +++ b/modules/webapp/src/main/elm/Comp/ImapSettingsManage.elm @@ -251,6 +251,7 @@ viewTable2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.ImapSettingsTable.view2 @@ -297,6 +298,7 @@ viewForm2 texts settings model = else [] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/ItemCardList.elm b/modules/webapp/src/main/elm/Comp/ItemCardList.elm index f9f2967b..7d37664a 100644 --- a/modules/webapp/src/main/elm/Comp/ItemCardList.elm +++ b/modules/webapp/src/main/elm/Comp/ItemCardList.elm @@ -33,7 +33,6 @@ import Html exposing (..) import Html.Attributes exposing (..) import Messages.Comp.ItemCardList exposing (Texts) import Page exposing (Page(..)) -import Set exposing (Set) import Styles as S import Util.ItemDragDrop as DD import Util.List diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/AddFilesForm.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/AddFilesForm.elm index 4d0090ed..8f6b3baf 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/AddFilesForm.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/AddFilesForm.elm @@ -56,6 +56,14 @@ view texts model = ] [ text texts.reset ] + , div [ class "flex-grow" ] [] + , button + [ class S.secondaryButton + , href "#" + , onClick AddFilesToggle + ] + [ text texts.basics.cancel + ] ] , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/EditForm.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/EditForm.elm index 397b0ce8..6fc9dcec 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/EditForm.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/EditForm.elm @@ -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 @@ -388,7 +386,7 @@ formTabs texts flags settings model = , titleRight = [] , info = Nothing , body = - [ div [ class "mb-4" ] + [ div [ class "mb-24" ] [ Html.map DirDropdownMsg (Comp.Dropdown.view2 directionCfg diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/ItemInfoHeader.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/ItemInfoHeader.elm index 75a85108..40cb6bc9 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/ItemInfoHeader.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/ItemInfoHeader.elm @@ -25,11 +25,10 @@ import Html.Attributes exposing (..) import Messages.Comp.ItemDetail.ItemInfoHeader exposing (Texts) import Page exposing (Page(..)) import Styles as S -import Util.Maybe -view : Texts -> UiSettings -> Model -> Html Msg -view texts settings model = +view : Texts -> UiSettings -> Model -> Html Msg -> Html Msg +view texts settings model beforeTags = let date = ( div @@ -45,24 +44,27 @@ view texts settings model = ) itemStyle = - "ml-2 sm:ml-4 py-1 whitespace-nowrap " + "ml-2 sm:ml-4 py-1 whitespace-nowrap truncate" linkStyle = - "opacity-75 hover:opacity-100" + "opacity-75 hover:opacity-100 " duedate = ( div - [ class "ml-2 sm:ml-4 py-1 max-w-min whitespace-nowrap opacity-100" - , class S.basicLabel + [ class "ml-2 sm:ml-0 py-1 whitespace-nowrap " + , classList + [ ( "dark:text-amber-400 text-amber-800 italic underline" + , model.item.dueDate /= Nothing + ) + ] , title texts.dueDate ] [ Icons.dueDateIcon2 "mr-2" , Maybe.map texts.formatDate model.item.dueDate - |> Maybe.withDefault "" + |> Maybe.withDefault "-" |> text ] , Data.UiSettings.fieldVisible settings Data.Fields.DueDate - && Util.Maybe.nonEmpty model.item.dueDate ) corr = @@ -126,7 +128,7 @@ view texts settings model = model.item.state == "created" in div [ class "flex flex-col pb-2" ] - [ div [ class "flex flex-row items-center text-2xl" ] + [ div [ class "flex flex-row items-center text-2xl order-1" ] [ if isDeleted then div [ classList @@ -172,34 +174,39 @@ view texts settings model = ] ] ] - , ul [ class "flex flex-col sm:flex-row flex-wrap text-base " ] + , div [ class "flex flex-col sm:flex-row flex-wrap text-base order-2" ] (List.filter Tuple.second [ date , corr , conc , itemfolder , src - , duedate ] |> List.map Tuple.first ) + , div [ class "flex flex-col sm:flex-row flex-wrap text-base order-3" ] + (List.filter Tuple.second [ duedate ] |> List.map Tuple.first) + , div [ class "order-4 md:order-5" ] + [ beforeTags + ] , renderTagsAndFields settings model ] renderTagsAndFields : UiSettings -> Model -> Html Msg renderTagsAndFields settings model = - div [ class "flex flex-row flex-wrap items-center font-semibold sm:justify-end mt-1 min-h-7" ] + div [ class "flex flex-row flex-wrap items-center font-semibold justify-end mt-1 min-h-7 order-5 md:order-4" ] (renderTags settings model ++ renderCustomValues settings model) renderTags : UiSettings -> Model -> List (Html Msg) renderTags settings model = let - tagView t = + tagView index t = Comp.LinkTarget.makeTagLink (IdName t.id t.name) - [ ( "label md:text-sm inline-flex ml-2 hover:opacity-90 mt-1 items-center", True ) + [ ( "label md:text-sm inline-flex hover:opacity-90 mt-1 items-center", True ) + , ( "mr-0 ml-2", index > 0 ) , ( Data.UiSettings.tagColorString2 t settings, True ) ] SetLinkTarget @@ -208,7 +215,7 @@ renderTags settings model = [] else - List.map tagView model.item.tags + List.indexedMap tagView model.item.tags renderCustomValues : UiSettings -> Model -> List (Html Msg) diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/Model.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/Model.elm index aa5bacaf..b3a58c4a 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/Model.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/Model.elm @@ -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,10 +113,10 @@ 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 + , mobileItemMenuOpen : Bool , editMenuTabsOpen : Set String , viewMode : ViewMode , showQrModel : ShowQrModel @@ -217,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 @@ -249,10 +248,10 @@ emptyModel = , keyInputModel = Comp.KeyInput.init , customFieldsModel = Comp.CustomFieldMultiInput.initWith [] , customFieldSavingIcon = Dict.empty - , customFieldThrottle = Throttle.create 1 , allTags = [] , allPersons = Dict.empty , attachmentDropdownOpen = False + , mobileItemMenuOpen = False , editMenuTabsOpen = Set.empty , viewMode = SimpleView , showQrModel = initShowQrModel @@ -283,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 @@ -347,7 +345,6 @@ type Msg | StartEditEquipModal | ResetHiddenMsg Field (Result Http.Error BasicResult) | SaveNameResp (Result Http.Error BasicResult) - | UpdateThrottle | KeyInputMsg Comp.KeyInput.Msg | ToggleAttachMenu | UiSettingsUpdated @@ -356,6 +353,7 @@ type Msg | CustomFieldSaveResp CustomField String (Result Http.Error BasicResult) | CustomFieldRemoveResp String (Result Http.Error BasicResult) | ToggleAttachmentDropdown + | ToggleMobileItemMenu | ToggleAkkordionTab String | ToggleOpenAllAkkordionTabs | RequestReprocessFile String @@ -368,6 +366,7 @@ type Msg | ToggleShowQrItem String | ToggleShowQrAttach String | PrintElement String + | SetNameMsg Comp.SimpleTextInput.Msg type SaveNameState diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/MultiEditMenu.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/MultiEditMenu.elm index adc27eab..bd86479f 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/MultiEditMenu.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/MultiEditMenu.elm @@ -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 diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/ShowQrCode.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/ShowQrCode.elm index a6e3a96f..7631d5b6 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/ShowQrCode.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/ShowQrCode.elm @@ -8,13 +8,11 @@ module Comp.ItemDetail.ShowQrCode exposing (UrlId(..), qrCodeElementId, view, view1) import Api -import Comp.Basic as B import Comp.ItemDetail.Model exposing (Model, Msg(..), isShowQrAttach, isShowQrItem) import Comp.MenuBar as MB import Data.Flags exposing (Flags) import Html exposing (..) import Html.Attributes exposing (..) -import Html.Events exposing (onClick) import QRCode import Styles as S import Svg.Attributes as SvgA @@ -72,16 +70,17 @@ view1 flags classes urlId = , icon = Just "fa fa-print" , label = "Print" } - ] - , end = - [ MB.SecondaryButton + , MB.SecondaryButton { tagger = toggleShowQr , title = "Close" , icon = Just "fa fa-times" , label = "Close" } ] + , end = + [] , rootClasses = "w-full mt-2 mb-4" + , sticky = True } , div [ class "flex flex-col sm:flex-row sm:space-x-2" ] [ div diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/SingleAttachment.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/SingleAttachment.elm index 52942e49..e6690153 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/SingleAttachment.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/SingleAttachment.elm @@ -170,13 +170,13 @@ attachHeader texts settings model _ attach = in div [ class "flex flex-col sm:flex-row items-center w-full" ] [ attachSelectToggle False - , div [ class "text-base font-bold flex-grow w-full text-center sm:text-left break-all" ] + , div [ class "text-base font-bold flex-grow w-full text-left break-all" ] [ text attachName , text " (" , text (Util.Size.bytesReadable Util.Size.B (toFloat attach.size)) , text ")" ] - , div [ class "flex flex-row justify-end items-center" ] + , div [ class "flex flex-row justify-end items-center w-full" ] [ attachSelectToggle True , a [ href fileUrl diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm index 8ec84d32..39bbee54 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/Update.elm @@ -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 @@ -519,10 +516,16 @@ update key flags inav settings msg model = resetCmds = resetHiddenFields settings flags model.item.id ResetHiddenMsg in - resultModelCmd ( model, Cmd.batch (Api.setConfirmed flags model.item.id SaveResp :: resetCmds) ) + resultModelCmd + ( { model | mobileItemMenuOpen = False } + , Cmd.batch (Api.setConfirmed flags model.item.id SaveResp :: resetCmds) + ) UnconfirmItem -> - resultModelCmd ( model, Api.setUnconfirmed flags model.item.id SaveResp ) + resultModelCmd + ( { model | mobileItemMenuOpen = False } + , Api.setUnconfirmed flags model.item.id SaveResp + ) ItemDatePickerMsg m -> let @@ -573,7 +576,11 @@ update key flags inav settings msg model = resultModel { model | itemModal = Nothing } RequestDelete -> - resultModel { model | itemModal = Just (ConfirmModalDeleteItem DeleteItemConfirmed) } + resultModel + { model + | itemModal = Just (ConfirmModalDeleteItem DeleteItemConfirmed) + , mobileItemMenuOpen = False + } SetCorrOrgSuggestion idname -> resultModelCmd ( model, setCorrOrg flags model (Just idname) ) @@ -819,6 +826,7 @@ update key flags inav settings msg model = | mailOpen = newOpen , addFilesOpen = filesOpen , mailSendResult = sendResult + , mobileItemMenuOpen = False } SendMailResp (Ok br) -> @@ -983,6 +991,7 @@ update key flags inav settings msg model = resultModel { model | addFilesOpen = not model.addFilesOpen + , mobileItemMenuOpen = False , mailOpen = if model.addFilesOpen == False then False @@ -1351,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 ) = @@ -1396,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 @@ -1432,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 ) @@ -1466,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 @@ -1520,6 +1509,9 @@ update key flags inav settings msg model = ToggleAttachmentDropdown -> resultModel { model | attachmentDropdownOpen = not model.attachmentDropdownOpen } + ToggleMobileItemMenu -> + resultModel { model | mobileItemMenuOpen = not model.mobileItemMenuOpen } + ToggleAkkordionTab name -> let tabs = @@ -1572,6 +1564,7 @@ update key flags inav settings msg model = { model | attachmentDropdownOpen = False , itemModal = Just (ConfirmModalReprocessItem ReprocessItemConfirmed) + , mobileItemMenuOpen = False } in resultModel model_ @@ -1593,7 +1586,7 @@ update key flags inav settings msg model = SelectView _ -> ( SimpleView, Cmd.none ) in - withSub + resultModelCmd ( { model | viewMode = nextView } @@ -1611,7 +1604,7 @@ update key flags inav settings msg model = next = { sqm | item = not sqm.item } in - resultModel { model | showQrModel = next } + resultModel { model | showQrModel = next, mobileItemMenuOpen = False } ToggleShowQrAttach id -> let @@ -1760,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 diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/View2.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/View2.elm index 0b8af10f..a321744b 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/View2.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/View2.elm @@ -42,8 +42,9 @@ import Styles as S view : Texts -> Flags -> ItemNav -> UiSettings -> Model -> Html Msg view texts flags inav settings model = div [ class "flex flex-col h-full" ] - [ header texts settings model - , menuBar texts inav settings model + [ header texts settings inav model + + -- , menuBar texts inav settings model , body texts flags inav settings model , itemModal texts model ] @@ -59,10 +60,14 @@ itemModal texts model = span [ class "hidden" ] [] -header : Texts -> UiSettings -> Model -> Html Msg -header texts settings model = +header : Texts -> UiSettings -> ItemNav -> Model -> Html Msg +header texts settings inav model = div [ class "my-3" ] - [ Comp.ItemDetail.ItemInfoHeader.view texts.itemInfoHeader settings model ] + [ Comp.ItemDetail.ItemInfoHeader.view texts.itemInfoHeader + settings + model + (menuBar texts inav settings model) + ] menuBar : Texts -> ItemNav -> UiSettings -> Model -> Html Msg @@ -136,6 +141,7 @@ menuBar texts inav settings model = [ classList [ ( "bg-gray-200 dark:bg-slate-600", model.mailOpen ) ] + , class "hidden md:block" , title texts.sendMail , onClick ToggleMail , class S.secondaryBasicButton @@ -148,6 +154,7 @@ menuBar texts inav settings model = [ classList [ ( "bg-gray-200 dark:bg-slate-600", model.addFilesOpen ) ] + , class "hidden md:block" , if model.addFilesOpen then title texts.close @@ -164,6 +171,7 @@ menuBar texts inav settings model = [ classList [ ( "bg-gray-200 dark:bg-slate-600", isShowQrItem model.showQrModel ) ] + , class "hidden md:block" , if isShowQrItem model.showQrModel then title texts.close @@ -175,6 +183,11 @@ menuBar texts inav settings model = ] [ Icons.showQrIcon "" ] + , MB.CustomElement <| + div + [ class "flex flex-grow md:hidden" + ] + [] , MB.CustomElement <| a [ class S.primaryButton @@ -183,9 +196,88 @@ menuBar texts inav settings model = , title texts.confirmItemMetadata , classList [ ( "hidden", model.item.state /= "created" ) ] ] - [ i [ class "fa fa-check mr-2" ] [] - , text texts.confirm + [ i [ class "fa fa-check" ] [] + , span [ class "hidden ml-0 sm:ml-2 sm:inline" ] + [ text texts.confirm ] ] + , MB.Dropdown + { linkIcon = "fa fa-bars" + , label = "" + , linkClass = + [ ( "md:hidden", True ) + , ( S.secondaryBasicButton, True ) + ] + , toggleMenu = ToggleMobileItemMenu + , menuOpen = model.mobileItemMenuOpen + , items = + [ { icon = i [ class "fa fa-envelope font-thin" ] [] + , label = texts.sendMail + , disabled = False + , attrs = + [ href "#" + , onClick ToggleMail + ] + } + , { icon = Icons.addFilesIcon2 "" + , label = texts.addMoreFiles + , disabled = False + , attrs = + [ href "#" + , onClick AddFilesToggle + ] + } + , { icon = Icons.showQrIcon "" + , label = texts.showQrCode + , disabled = False + , attrs = + [ href "#" + , onClick (ToggleShowQrItem model.item.id) + ] + } + , { icon = i [] [] + , label = "separator" + , disabled = False + , attrs = + [] + } + , { icon = i [ class "fa fa-eye-slash font-thin" ] [] + , label = texts.unconfirmItemMetadata + , disabled = False + , attrs = + [ href "#" + , onClick UnconfirmItem + , classList [ ( "hidden", model.item.state == "created" ) ] + ] + } + , { icon = i [ class "fa fa-redo" ] [] + , label = texts.reprocessItem + , disabled = False + , attrs = + [ href "#" + , onClick RequestReprocessItem + ] + } + , if model.item.state == "deleted" then + { icon = i [ class "fa fa-trash-restore" ] [] + , label = texts.undeleteThisItem + , disabled = False + , attrs = + [ href "#" + , onClick RestoreItem + ] + } + + else + { icon = i [ class "fa fa-trash", class "text-red-500 dark:text-orange-500" ] [] + , label = texts.deleteThisItem + , disabled = False + , attrs = + [ href "#" + , onClick RequestDelete + ] + } + ] + } ] , end = [ MB.CustomElement <| @@ -195,12 +287,14 @@ menuBar texts inav settings model = , onClick UnconfirmItem , title texts.unconfirmItemMetadata , classList [ ( "hidden", model.item.state == "created" ) ] + , class "hidden md:block" ] [ i [ class "fa fa-eye-slash font-thin" ] [] ] , MB.CustomElement <| a [ class S.secondaryBasicButton + , class "hidden md:block" , href "#" , onClick RequestReprocessItem , title texts.reprocessItem @@ -211,6 +305,7 @@ menuBar texts inav settings model = MB.CustomElement <| a [ class S.undeleteButton + , class "hidden md:block" , href "#" , onClick RestoreItem , title texts.undeleteThisItem @@ -222,6 +317,7 @@ menuBar texts inav settings model = MB.CustomElement <| a [ class S.deleteButton + , class "hidden md:block" , href "#" , onClick RequestDelete , title texts.deleteThisItem @@ -229,21 +325,39 @@ menuBar texts inav settings model = [ i [ class "fa fa-trash" ] [] ] ] - , rootClasses = "mb-2" + , rootClasses = "mb-2 md:mt-2" + , sticky = False } body : Texts -> Flags -> ItemNav -> UiSettings -> Model -> Html Msg body texts flags _ settings model = div [ class "grid gap-2 grid-cols-1 md:grid-cols-3 h-full" ] - [ leftArea texts flags settings model - , rightArea texts flags settings model + [ div [ class "flex flex-col hidden md:block h-full" ] + [ itemActions texts flags settings model "" + , notesAndSentMails texts flags settings model "h-full" + ] + , attachmentView texts flags settings model "order-2 col-span-2" + , itemActions texts flags settings model "order-1 md:hidden" + , notesAndSentMails texts flags settings model "order-3 md:hidden" ] -leftArea : Texts -> Flags -> UiSettings -> Model -> Html Msg -leftArea texts flags settings model = - div [ class "w-full md:order-first md:mr-2 flex flex-col" ] +attachmentView : Texts -> Flags -> UiSettings -> Model -> String -> Html Msg +attachmentView texts flags settings model classes = + div + [ class "h-full" + , class classes + ] + (attachmentsBody texts flags settings model) + + +itemActions : Texts -> Flags -> UiSettings -> Model -> String -> Html Msg +itemActions texts flags settings model classes = + div + [ class "w-full md:mr-2 flex flex-col" + , class classes + ] [ addDetailForm texts settings model , sendMailForm texts settings model , Comp.ItemDetail.AddFilesForm.view texts.addFilesForm model @@ -251,7 +365,16 @@ leftArea texts flags settings model = (S.border ++ " mb-4") model (Comp.ItemDetail.ShowQrCode.Item model.item.id) - , Comp.ItemDetail.Notes.view texts.notes model + ] + + +notesAndSentMails : Texts -> Flags -> UiSettings -> Model -> String -> Html Msg +notesAndSentMails texts _ _ model classes = + div + [ class "w-full md:mr-2 flex flex-col" + , class classes + ] + [ Comp.ItemDetail.Notes.view texts.notes model , div [ classList [ ( "hidden", Comp.SentMails.isEmpty model.sentMails ) @@ -268,12 +391,6 @@ leftArea texts flags settings model = ] -rightArea : Texts -> Flags -> UiSettings -> Model -> Html Msg -rightArea texts flags settings model = - div [ class "md:col-span-2 h-full" ] - (attachmentsBody texts flags settings model) - - attachmentsBody : Texts -> Flags -> UiSettings -> Model -> List (Html Msg) attachmentsBody texts flags settings model = List.indexedMap (Comp.ItemDetail.SingleAttachment.view texts.singleAttachment flags settings model) diff --git a/modules/webapp/src/main/elm/Comp/ItemMail.elm b/modules/webapp/src/main/elm/Comp/ItemMail.elm index e7a47b80..4a87fbe6 100644 --- a/modules/webapp/src/main/elm/Comp/ItemMail.elm +++ b/modules/webapp/src/main/elm/Comp/ItemMail.elm @@ -31,7 +31,7 @@ import Data.Flags exposing (Flags) import Data.UiSettings exposing (UiSettings) import Html exposing (..) import Html.Attributes exposing (..) -import Html.Events exposing (onClick, onFocus, onInput) +import Html.Events exposing (onClick, onInput) import Http import Messages.Comp.ItemMail exposing (Texts) import Styles as S diff --git a/modules/webapp/src/main/elm/Comp/ItemMerge.elm b/modules/webapp/src/main/elm/Comp/ItemMerge.elm index 03b52e8e..6206e03d 100644 --- a/modules/webapp/src/main/elm/Comp/ItemMerge.elm +++ b/modules/webapp/src/main/elm/Comp/ItemMerge.elm @@ -272,6 +272,7 @@ view texts settings model = ] , end = [] , rootClasses = "my-4" + , sticky = True } , renderFormState texts model , div [ class "flex-col px-2" ] diff --git a/modules/webapp/src/main/elm/Comp/MenuBar.elm b/modules/webapp/src/main/elm/Comp/MenuBar.elm index 825b9bcd..d9d2ef0f 100644 --- a/modules/webapp/src/main/elm/Comp/MenuBar.elm +++ b/modules/webapp/src/main/elm/Comp/MenuBar.elm @@ -41,6 +41,7 @@ type alias MenuBar msg = { start : List (Item msg) , end : List (Item msg) , rootClasses : String + , sticky : Bool } @@ -125,7 +126,8 @@ view1 classes mb = in div [ class mb.rootClasses - , class "flex flex-col sm:flex-row space-y-1 sm:space-y-0 sticky top-0 z-40" + , class "flex flex-col md:flex-row space-y-1 md:space-y-0" + , classList [ ( "sticky top-0 z-40", mb.sticky ) ] , class classes ] [ left @@ -296,7 +298,7 @@ makeButton btnType model = [] else - [ span [ class (iconMargin ++ " hidden sm:inline") ] + [ span [ class (iconMargin ++ " hidden md:inline") ] [ text model.label ] ] diff --git a/modules/webapp/src/main/elm/Comp/NotificationChannelManage.elm b/modules/webapp/src/main/elm/Comp/NotificationChannelManage.elm index 27af5a51..dd302da6 100644 --- a/modules/webapp/src/main/elm/Comp/NotificationChannelManage.elm +++ b/modules/webapp/src/main/elm/Comp/NotificationChannelManage.elm @@ -391,6 +391,7 @@ viewForm texts settings outerModel model = else [] , rootClasses = "mb-4" + , sticky = True } , div [ class "mt-2" ] [ viewState texts outerModel @@ -445,6 +446,7 @@ viewList texts model = [ Comp.ChannelMenu.channelMenu texts.channelType menuModel ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.NotificationChannelTable.view texts.notificationTable diff --git a/modules/webapp/src/main/elm/Comp/NotificationHookManage.elm b/modules/webapp/src/main/elm/Comp/NotificationHookManage.elm index 921d5f2f..6b4a8096 100644 --- a/modules/webapp/src/main/elm/Comp/NotificationHookManage.elm +++ b/modules/webapp/src/main/elm/Comp/NotificationHookManage.elm @@ -358,6 +358,7 @@ viewForm texts settings outerModel model = else [] , rootClasses = "mb-4" + , sticky = True } , div [ class "mt-2" ] [ viewState texts outerModel @@ -409,6 +410,7 @@ viewList texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.NotificationHookTable.view texts.notificationTable diff --git a/modules/webapp/src/main/elm/Comp/NotificationTest.elm b/modules/webapp/src/main/elm/Comp/NotificationTest.elm index 5af2c2a9..ec14c1a9 100644 --- a/modules/webapp/src/main/elm/Comp/NotificationTest.elm +++ b/modules/webapp/src/main/elm/Comp/NotificationTest.elm @@ -126,6 +126,7 @@ view cfg model = } ] , rootClasses = "mb-1" + , sticky = True } , case model of ModelResp res -> @@ -137,7 +138,7 @@ view cfg model = [ text (String.join "\n" res.messages) ] - ModelHttpError err -> + ModelHttpError _ -> div [ class "" ] [] diff --git a/modules/webapp/src/main/elm/Comp/OrgManage.elm b/modules/webapp/src/main/elm/Comp/OrgManage.elm index 5dccc8b0..b0ecb8ab 100644 --- a/modules/webapp/src/main/elm/Comp/OrgManage.elm +++ b/modules/webapp/src/main/elm/Comp/OrgManage.elm @@ -272,6 +272,7 @@ viewTable2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.OrgTable.view2 texts.orgTable model.order model.tableModel) , B.loadingDimmer @@ -343,6 +344,7 @@ viewForm2 texts settings model = else [] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskForm.elm b/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskForm.elm index 76f6618f..c6fa1ee8 100644 --- a/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskForm.elm +++ b/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskForm.elm @@ -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 ) @@ -490,6 +489,7 @@ view texts extraClasses settings model = [ startOnceBtn ] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskManage.elm b/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskManage.elm index 03647749..5f2192ca 100644 --- a/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskManage.elm +++ b/modules/webapp/src/main/elm/Comp/PeriodicQueryTaskManage.elm @@ -16,11 +16,9 @@ module Comp.PeriodicQueryTaskManage exposing import Api import Api.Model.BasicResult exposing (BasicResult) import Api.Model.PeriodicQuerySettings exposing (PeriodicQuerySettings) -import Comp.ChannelMenu import Comp.MenuBar as MB import Comp.PeriodicQueryTaskForm import Comp.PeriodicQueryTaskList -import Data.ChannelType exposing (ChannelType) import Data.Flags exposing (Flags) import Data.UiSettings exposing (UiSettings) import Html exposing (..) @@ -305,6 +303,7 @@ viewList2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map ListMsg (Comp.PeriodicQueryTaskList.view2 texts.notificationTable diff --git a/modules/webapp/src/main/elm/Comp/PersonManage.elm b/modules/webapp/src/main/elm/Comp/PersonManage.elm index 92451a22..bd66507c 100644 --- a/modules/webapp/src/main/elm/Comp/PersonManage.elm +++ b/modules/webapp/src/main/elm/Comp/PersonManage.elm @@ -305,6 +305,7 @@ viewTable2 texts model = , label = texts.newPerson } ] + , sticky = True , rootClasses = "mb-4" } , Html.map TableMsg (Comp.PersonTable.view2 texts.personTable model.order model.tableModel) @@ -377,6 +378,7 @@ viewForm2 texts settings model = else [] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/PowerSearchInput.elm b/modules/webapp/src/main/elm/Comp/PowerSearchInput.elm index 9dedaa91..ce9c5e04 100644 --- a/modules/webapp/src/main/elm/Comp/PowerSearchInput.elm +++ b/modules/webapp/src/main/elm/Comp/PowerSearchInput.elm @@ -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 " + ] [] diff --git a/modules/webapp/src/main/elm/Comp/PublishItems.elm b/modules/webapp/src/main/elm/Comp/PublishItems.elm index 5679f80a..05b52835 100644 --- a/modules/webapp/src/main/elm/Comp/PublishItems.elm +++ b/modules/webapp/src/main/elm/Comp/PublishItems.elm @@ -290,6 +290,7 @@ viewInfo texts settings flags model share = ] , end = [] , rootClasses = "my-4" + , sticky = True } , div [] [ Comp.ShareView.view cfg texts.shareView flags share @@ -346,6 +347,7 @@ viewForm texts model = ] , end = [] , rootClasses = "my-4" + , sticky = True } , div [] [ Html.map FormMsg (Comp.ShareForm.view texts.shareForm model.formModel) diff --git a/modules/webapp/src/main/elm/Comp/ScanMailboxForm.elm b/modules/webapp/src/main/elm/Comp/ScanMailboxForm.elm index 60d7d5e3..2c12cc58 100644 --- a/modules/webapp/src/main/elm/Comp/ScanMailboxForm.elm +++ b/modules/webapp/src/main/elm/Comp/ScanMailboxForm.elm @@ -22,7 +22,6 @@ import Api.Model.IdName exposing (IdName) import Api.Model.ImapSettingsList exposing (ImapSettingsList) import Api.Model.ScanMailboxSettings exposing (ScanMailboxSettings) import Api.Model.StringList exposing (StringList) -import Api.Model.Tag import Api.Model.TagList exposing (TagList) import Comp.Basic as B import Comp.CalEventInput @@ -823,6 +822,7 @@ view2 texts flags extraClasses settings model = [ startOnceBtn ] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/ScanMailboxManage.elm b/modules/webapp/src/main/elm/Comp/ScanMailboxManage.elm index 51af73b4..88c7d998 100644 --- a/modules/webapp/src/main/elm/Comp/ScanMailboxManage.elm +++ b/modules/webapp/src/main/elm/Comp/ScanMailboxManage.elm @@ -297,6 +297,7 @@ viewList2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map ListMsg (Comp.ScanMailboxList.view2 texts.table diff --git a/modules/webapp/src/main/elm/Comp/SearchMenu.elm b/modules/webapp/src/main/elm/Comp/SearchMenu.elm index 2be3e90e..35739d6b 100644 --- a/modules/webapp/src/main/elm/Comp/SearchMenu.elm +++ b/modules/webapp/src/main/elm/Comp/SearchMenu.elm @@ -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 } diff --git a/modules/webapp/src/main/elm/Comp/ShareForm.elm b/modules/webapp/src/main/elm/Comp/ShareForm.elm index ee08a7d8..d949e420 100644 --- a/modules/webapp/src/main/elm/Comp/ShareForm.elm +++ b/modules/webapp/src/main/elm/Comp/ShareForm.elm @@ -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 ) diff --git a/modules/webapp/src/main/elm/Comp/ShareManage.elm b/modules/webapp/src/main/elm/Comp/ShareManage.elm index 2a4915d4..f452a972 100644 --- a/modules/webapp/src/main/elm/Comp/ShareManage.elm +++ b/modules/webapp/src/main/elm/Comp/ShareManage.elm @@ -329,6 +329,7 @@ viewTable texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.ShareTable.view texts.shareTable model.shares) , B.loadingDimmer @@ -406,6 +407,7 @@ viewForm texts settings flags model = else [] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/SimpleTextInput.elm b/modules/webapp/src/main/elm/Comp/SimpleTextInput.elm new file mode 100644 index 00000000..ce48747c --- /dev/null +++ b/modules/webapp/src/main/elm/Comp/SimpleTextInput.elm @@ -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) [] diff --git a/modules/webapp/src/main/elm/Comp/SourceManage.elm b/modules/webapp/src/main/elm/Comp/SourceManage.elm index c936069d..b9ce852b 100644 --- a/modules/webapp/src/main/elm/Comp/SourceManage.elm +++ b/modules/webapp/src/main/elm/Comp/SourceManage.elm @@ -261,6 +261,7 @@ viewTable2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.SourceTable.view2 texts.sourceTable model.sources) , B.loadingDimmer @@ -302,6 +303,7 @@ viewLinks2 texts flags _ source = ] , end = [] , rootClasses = "mb-4" + , sticky = True } , p [ class "text-lg pt-2 opacity-75" ] [ text texts.sourceInfoText @@ -449,6 +451,7 @@ viewForm2 texts flags settings model = else [] , rootClasses = "mb-4" + , sticky = True } , Html.map FormMsg (Comp.SourceForm.view2 flags texts.sourceForm settings model.formModel) diff --git a/modules/webapp/src/main/elm/Comp/TagManage.elm b/modules/webapp/src/main/elm/Comp/TagManage.elm index 7881003b..e9ae7e2c 100644 --- a/modules/webapp/src/main/elm/Comp/TagManage.elm +++ b/modules/webapp/src/main/elm/Comp/TagManage.elm @@ -284,6 +284,7 @@ viewTable2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.TagTable.view2 texts.tagTable model.order model.tagTableModel) , div @@ -359,6 +360,7 @@ viewForm2 texts settings model = else [] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm b/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm index 26757edb..89fd76f6 100644 --- a/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm +++ b/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm @@ -339,6 +339,7 @@ view2 texts flags _ classes model = } ] , rootClasses = "mb-4" + , sticky = True } , div [ classList diff --git a/modules/webapp/src/main/elm/Comp/UserManage.elm b/modules/webapp/src/main/elm/Comp/UserManage.elm index 47a6d0a6..e3d162c5 100644 --- a/modules/webapp/src/main/elm/Comp/UserManage.elm +++ b/modules/webapp/src/main/elm/Comp/UserManage.elm @@ -271,6 +271,7 @@ viewTable2 texts model = } ] , rootClasses = "mb-4" + , sticky = True } , Html.map TableMsg (Comp.UserTable.view2 texts.userTable model.tableModel) , B.loadingDimmer @@ -281,7 +282,7 @@ viewTable2 texts model = renderDeleteConfirm : Texts -> UiSettings -> Model -> Html Msg -renderDeleteConfirm texts settings model = +renderDeleteConfirm texts _ model = case model.deleteConfirm of DimmerOff -> span [ class "hidden" ] [] @@ -397,6 +398,7 @@ viewForm2 texts settings model = else [] , rootClasses = "mb-4" + , sticky = True } , Html.map FormMsg (Comp.UserForm.view2 texts.userForm settings model.formModel) , div diff --git a/modules/webapp/src/main/elm/Messages/Comp/ItemDetail.elm b/modules/webapp/src/main/elm/Messages/Comp/ItemDetail.elm index b5ab6b0b..59af72d8 100644 --- a/modules/webapp/src/main/elm/Messages/Comp/ItemDetail.elm +++ b/modules/webapp/src/main/elm/Messages/Comp/ItemDetail.elm @@ -77,7 +77,7 @@ gb = , nextItem = "Next item" , sendMail = "Send Mail" , addMoreFiles = "Add more files to this item" - , confirmItemMetadata = "Confirm item metadata" + , confirmItemMetadata = "Confirm metadata" , confirm = "Confirm" , unconfirmItemMetadata = "Un-confirm item metadata" , reprocessItem = "Reprocess this item" @@ -91,7 +91,7 @@ gb = , sendingMailNow = "Sending e-mail…" , formatDateTime = DF.formatDateTimeLong Messages.UiLanguage.English , mailSendSuccessful = "Mail sent." - , showQrCode = "Show the URL to this page as QR code" + , showQrCode = "Show URL as QR code" , close = "Close" } @@ -127,6 +127,6 @@ de = , sendingMailNow = "E-Mail wird gesendet…" , formatDateTime = DF.formatDateTimeLong Messages.UiLanguage.German , mailSendSuccessful = "E-Mail wurde versendet." - , showQrCode = "Den Link zu dieser Seite als QR code anzeigen" + , showQrCode = "Link als QR code anzeigen" , close = "Schließen" } diff --git a/modules/webapp/src/main/elm/Messages/Comp/ItemDetail/MultiEditMenu.elm b/modules/webapp/src/main/elm/Messages/Comp/ItemDetail/MultiEditMenu.elm index f63b5041..b46a81d1 100644 --- a/modules/webapp/src/main/elm/Messages/Comp/ItemDetail/MultiEditMenu.elm +++ b/modules/webapp/src/main/elm/Messages/Comp/ItemDetail/MultiEditMenu.elm @@ -44,7 +44,7 @@ gb = , tagModeRemoveInfo = "Tags chosen here are *removed* from all selected items." , tagModeReplaceInfo = "Tags chosen here *replace* those on selected items." , chooseDirection = "Choose a direction…" - , confirmUnconfirm = "Confirm/Unconfirm item metadata" + , confirmUnconfirm = "Confirm/Unconfirm metadata" , confirm = "Confirm" , unconfirm = "Unconfirm" , changeTagMode = "Change tag edit mode" diff --git a/modules/webapp/src/main/elm/Page/ItemDetail/View2.elm b/modules/webapp/src/main/elm/Page/ItemDetail/View2.elm index e71157b5..00ab403a 100644 --- a/modules/webapp/src/main/elm/Page/ItemDetail/View2.elm +++ b/modules/webapp/src/main/elm/Page/ItemDetail/View2.elm @@ -54,6 +54,7 @@ viewSidebar texts visible flags settings model = ] , end = [] , rootClasses = "text-sm mb-3 " + , sticky = True } , Html.map ItemDetailMsg (Comp.ItemDetail.EditForm.view2 texts.editForm flags settings model.detail) diff --git a/modules/webapp/src/main/elm/Page/Search/Data.elm b/modules/webapp/src/main/elm/Page/Search/Data.elm index 694eff8f..ca830f94 100644 --- a/modules/webapp/src/main/elm/Page/Search/Data.elm +++ b/modules/webapp/src/main/elm/Page/Search/Data.elm @@ -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) ] diff --git a/modules/webapp/src/main/elm/Page/Search/SideMenu.elm b/modules/webapp/src/main/elm/Page/Search/SideMenu.elm index 65b5d61f..556858cd 100644 --- a/modules/webapp/src/main/elm/Page/Search/SideMenu.elm +++ b/modules/webapp/src/main/elm/Page/Search/SideMenu.elm @@ -49,6 +49,7 @@ view texts flags settings model = ] , start = [] , rootClasses = "text-sm w-full bg-blue-50 pt-2 hidden" + , sticky = True } , div [ class "flex flex-col" ] (case model.viewMode of @@ -81,6 +82,7 @@ viewSearch texts flags settings model = ] , end = [] , rootClasses = "my-1 text-xs hidden sm:flex" + , sticky = True } , let searchMenuCfg = @@ -140,6 +142,7 @@ viewEditMenu texts flags svm settings = ] , end = [] , rootClasses = "mt-2 text-sm" + , sticky = True } , Html.map EditMenuMsg (Comp.ItemDetail.MultiEditMenu.view2 diff --git a/modules/webapp/src/main/elm/Page/Search/Update.elm b/modules/webapp/src/main/elm/Page/Search/Update.elm index 83dde95c..73d3510e 100644 --- a/modules/webapp/src/main/elm/Page/Search/Update.elm +++ b/modules/webapp/src/main/elm/Page/Search/Update.elm @@ -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 ) diff --git a/modules/webapp/src/main/elm/Page/Search/View2.elm b/modules/webapp/src/main/elm/Page/Search/View2.elm index 534c2707..34ecd498 100644 --- a/modules/webapp/src/main/elm/Page/Search/View2.elm +++ b/modules/webapp/src/main/elm/Page/Search/View2.elm @@ -250,7 +250,6 @@ defaultMenuBar texts flags settings model = [ Html.map PowerSearchMsg (Comp.PowerSearchInput.viewInput { placeholder = texts.powerSearchPlaceholder - , extraAttrs = [] } model.powerSearchInput ) @@ -424,6 +423,7 @@ defaultMenuBar texts flags settings model = } ] , rootClasses = "mb-2 pt-1 dark:bg-slate-700 items-center text-sm" + , sticky = True } @@ -551,6 +551,7 @@ editMenuBar texts model svm = } ] , rootClasses = "mb-2 pt-2 sticky top-0 text-sm" + , sticky = True } diff --git a/modules/webapp/src/main/elm/Page/Share/Menubar.elm b/modules/webapp/src/main/elm/Page/Share/Menubar.elm index 5df6db84..dde29feb 100644 --- a/modules/webapp/src/main/elm/Page/Share/Menubar.elm +++ b/modules/webapp/src/main/elm/Page/Share/Menubar.elm @@ -31,7 +31,6 @@ view texts flags model = [ Html.map PowerSearchMsg (Comp.PowerSearchInput.viewInput { placeholder = texts.powerSearchPlaceholder - , extraAttrs = [] } model.powerSearchInput ) @@ -151,4 +150,5 @@ view texts flags model = } ] , rootClasses = "mb-2 pt-1 dark:bg-slate-700 items-center text-sm" + , sticky = True } diff --git a/modules/webapp/src/main/elm/Page/Share/Update.elm b/modules/webapp/src/main/elm/Page/Share/Update.elm index a3482580..85f8008c 100644 --- a/modules/webapp/src/main/elm/Page/Share/Update.elm +++ b/modules/webapp/src/main/elm/Page/Share/Update.elm @@ -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 diff --git a/modules/webapp/src/main/webjar/docspell.js b/modules/webapp/src/main/webjar/docspell.js index 0b81ff02..3176e162 100644 --- a/modules/webapp/src/main/webjar/docspell.js +++ b/modules/webapp/src/main/webjar/docspell.js @@ -87,7 +87,6 @@ elmApp.ports.checkSearchQueryString.subscribe(function(args) { messages: [] }; } - console.log("Sending: " + answer.success); elmApp.ports.receiveCheckQueryResult.send(answer); } });