diff --git a/modules/webapp/src/main/elm/App/Update.elm b/modules/webapp/src/main/elm/App/Update.elm index 66002c92..de687444 100644 --- a/modules/webapp/src/main/elm/App/Update.elm +++ b/modules/webapp/src/main/elm/App/Update.elm @@ -478,14 +478,14 @@ updateUserSettings lmsg model = updateCollSettings : Page.CollectiveSettings.Data.Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) updateCollSettings lmsg model = let - ( lm, lc ) = + ( lm, lc, ls ) = Page.CollectiveSettings.Update.update model.flags lmsg model.collSettingsModel in ( { model | collSettingsModel = lm } , Cmd.map CollSettingsMsg lc - , Sub.none + , Sub.map CollSettingsMsg ls ) diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/SingleAttachment.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/SingleAttachment.elm index 52f935f9..56d63635 100644 --- a/modules/webapp/src/main/elm/Comp/ItemDetail/SingleAttachment.elm +++ b/modules/webapp/src/main/elm/Comp/ItemDetail/SingleAttachment.elm @@ -153,6 +153,7 @@ attachHeader texts settings model _ attach = [ href "#" , onClick ToggleAttachMenu , class S.secondaryBasicButton + , class "mr-2" , classList [ ( "bg-gray-200 dark:bg-bluegray-600 ", model.attachMenuOpen ) , ( "hidden", not multiAttach ) @@ -160,12 +161,16 @@ attachHeader texts settings model _ attach = , ( "hidden sm:block", multiAttach && not mobile ) ] ] - [ i [ class "fa fa-images font-thin" ] [] + [ if model.attachMenuOpen then + i [ class "fa fa-chevron-up" ] [] + + else + i [ class "fa fa-chevron-down" ] [] ] in div [ class "flex flex-col sm:flex-row items-center w-full" ] [ attachSelectToggle False - , div [ class "ml-2 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-center sm:text-left break-all" ] [ text attachName , text " (" , text (Util.Size.bytesReadable Util.Size.B (toFloat attach.size)) diff --git a/modules/webapp/src/main/elm/Comp/PowerSearchInput.elm b/modules/webapp/src/main/elm/Comp/PowerSearchInput.elm index e06ef8c9..1036452d 100644 --- a/modules/webapp/src/main/elm/Comp/PowerSearchInput.elm +++ b/modules/webapp/src/main/elm/Comp/PowerSearchInput.elm @@ -11,6 +11,8 @@ module Comp.PowerSearchInput exposing , Msg , ViewSettings , init + , isValid + , setSearchString , update , viewInput , viewResult @@ -43,6 +45,11 @@ init = } +isValid : Model -> Bool +isValid model = + model.input /= Nothing && model.result.success + + type Msg = SetSearch String | KeyUpMsg (Maybe KeyCode) @@ -63,6 +70,11 @@ type alias Result = } +setSearchString : String -> Msg +setSearchString q = + SetSearch q + + --- Update diff --git a/modules/webapp/src/main/elm/Comp/PublishItems.elm b/modules/webapp/src/main/elm/Comp/PublishItems.elm index 2a491f15..a098d29a 100644 --- a/modules/webapp/src/main/elm/Comp/PublishItems.elm +++ b/modules/webapp/src/main/elm/Comp/PublishItems.elm @@ -108,6 +108,7 @@ type Outcome type alias UpdateResult = { model : Model , cmd : Cmd Msg + , sub : Sub Msg , outcome : Outcome } @@ -118,16 +119,18 @@ update flags msg model = CancelPublish -> { model = model , cmd = Cmd.none + , sub = Sub.none , outcome = OutcomeDone } FormMsg lm -> let - ( fm, fc ) = + ( fm, fc, fs ) = Comp.ShareForm.update flags lm model.formModel in { model = { model | formModel = fm } , cmd = Cmd.map FormMsg fc + , sub = Sub.map FormMsg fs , outcome = OutcomeInProgress } @@ -136,12 +139,14 @@ update flags msg model = Just ( _, data ) -> { model = { model | loading = True } , cmd = Api.addShare flags data PublishResp + , sub = Sub.none , outcome = OutcomeInProgress } Nothing -> { model = { model | formError = FormErrorInvalid } , cmd = Cmd.none + , sub = Sub.none , outcome = OutcomeInProgress } @@ -149,18 +154,21 @@ update flags msg model = if res.success then { model = model , cmd = Api.getShare flags res.id GetShareResp + , sub = Sub.none , outcome = OutcomeInProgress } else { model = { model | formError = FormErrorSubmit res.message, loading = False } , cmd = Cmd.none + , sub = Sub.none , outcome = OutcomeInProgress } PublishResp (Err err) -> { model = { model | formError = FormErrorHttp err, loading = False } , cmd = Cmd.none + , sub = Sub.none , outcome = OutcomeInProgress } @@ -172,12 +180,14 @@ update flags msg model = , viewMode = ViewModeInfo share } , cmd = Ports.initClipboard (Comp.ShareView.clipboardData share) + , sub = Sub.none , outcome = OutcomeInProgress } GetShareResp (Err err) -> { model = { model | formError = FormErrorHttp err, loading = False } , cmd = Cmd.none + , sub = Sub.none , outcome = OutcomeInProgress } diff --git a/modules/webapp/src/main/elm/Comp/ShareForm.elm b/modules/webapp/src/main/elm/Comp/ShareForm.elm index d07e74a4..ee08a7d8 100644 --- a/modules/webapp/src/main/elm/Comp/ShareForm.elm +++ b/modules/webapp/src/main/elm/Comp/ShareForm.elm @@ -12,6 +12,7 @@ import Api.Model.ShareDetail exposing (ShareDetail) import Comp.Basic as B import Comp.DatePicker import Comp.PasswordInput +import Comp.PowerSearchInput import Data.Flags exposing (Flags) import DatePicker exposing (DatePicker) import Html exposing (..) @@ -25,7 +26,7 @@ import Util.Maybe type alias Model = { share : ShareDetail , name : Maybe String - , query : String + , queryModel : Comp.PowerSearchInput.Model , enabled : Bool , passwordModel : Comp.PasswordInput.Model , password : Maybe String @@ -41,10 +42,15 @@ initQuery q = let ( dp, dpc ) = Comp.DatePicker.init + + res = + Comp.PowerSearchInput.update + (Comp.PowerSearchInput.setSearchString q) + Comp.PowerSearchInput.init in ( { share = Api.Model.ShareDetail.empty , name = Nothing - , query = q + , queryModel = res.model , enabled = True , passwordModel = Comp.PasswordInput.init , password = Nothing @@ -53,7 +59,10 @@ initQuery q = , untilModel = dp , untilDate = Nothing } - , Cmd.map UntilDateMsg dpc + , Cmd.batch + [ Cmd.map UntilDateMsg dpc + , Cmd.map QueryMsg res.cmd + ] ) @@ -64,17 +73,19 @@ init = isValid : Model -> Bool isValid model = - model.query /= "" && model.untilDate /= Nothing + Comp.PowerSearchInput.isValid model.queryModel + && model.untilDate + /= Nothing type Msg = SetName String - | SetQuery String | SetShare ShareDetail | ToggleEnabled | ToggleClearPassword | PasswordMsg Comp.PasswordInput.Msg | UntilDateMsg Comp.DatePicker.Msg + | QueryMsg Comp.PowerSearchInput.Msg setShare : ShareDetail -> Msg @@ -88,7 +99,9 @@ getShare model = Just ( model.share.id , { name = model.name - , query = model.query + , query = + model.queryModel.input + |> Maybe.withDefault "" , enabled = model.enabled , password = model.password , removePassword = @@ -105,14 +118,20 @@ getShare model = Nothing -update : Flags -> Msg -> Model -> ( Model, Cmd Msg ) +update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) update _ msg model = case msg of SetShare s -> + let + res = + Comp.PowerSearchInput.update + (Comp.PowerSearchInput.setSearchString s.query) + model.queryModel + in ( { model | share = s , name = s.name - , query = s.query + , queryModel = res.model , enabled = s.enabled , password = Nothing , passwordSet = s.password @@ -124,20 +143,18 @@ update _ msg model = else Nothing } - , Cmd.none + , Cmd.map QueryMsg res.cmd + , Sub.map QueryMsg res.subs ) SetName n -> - ( { model | name = Util.Maybe.fromString n }, Cmd.none ) - - SetQuery n -> - ( { model | query = n }, Cmd.none ) + ( { model | name = Util.Maybe.fromString n }, Cmd.none, Sub.none ) ToggleEnabled -> - ( { model | enabled = not model.enabled }, Cmd.none ) + ( { model | enabled = not model.enabled }, Cmd.none, Sub.none ) ToggleClearPassword -> - ( { model | clearPassword = not model.clearPassword }, Cmd.none ) + ( { model | clearPassword = not model.clearPassword }, Cmd.none, Sub.none ) PasswordMsg lm -> let @@ -149,6 +166,7 @@ update _ msg model = , password = pw } , Cmd.none + , Sub.none ) UntilDateMsg lm -> @@ -166,6 +184,17 @@ update _ msg model = in ( { model | untilModel = dp, untilDate = nextDate } , Cmd.none + , Sub.none + ) + + QueryMsg lm -> + let + res = + Comp.PowerSearchInput.update lm model.queryModel + in + ( { model | queryModel = res.model } + , Cmd.map QueryMsg res.cmd + , Sub.map QueryMsg res.subs ) @@ -175,6 +204,21 @@ update _ msg model = view : Texts -> Model -> Html Msg view texts model = + let + queryInput = + div + [ class "relative flex flex-grow flex-row" ] + [ Html.map QueryMsg + (Comp.PowerSearchInput.viewInput + { placeholder = texts.queryLabel + , extraAttrs = [] + } + model.queryModel + ) + , Html.map QueryMsg + (Comp.PowerSearchInput.viewResult [] model.queryModel) + ] + in div [ class "flex flex-col" ] [ div [ class "mb-4" ] @@ -202,20 +246,7 @@ view texts model = [ text texts.queryLabel , B.inputRequired ] - , input - [ type_ "text" - , onInput SetQuery - , placeholder texts.queryLabel - , value model.query - , id "sharequery" - , class S.textInput - , classList - [ ( S.inputErrorBorder - , model.query == "" - ) - ] - ] - [] + , queryInput ] , div [ class "mb-4" ] [ label diff --git a/modules/webapp/src/main/elm/Comp/ShareManage.elm b/modules/webapp/src/main/elm/Comp/ShareManage.elm index 472680c4..c3f31e64 100644 --- a/modules/webapp/src/main/elm/Comp/ShareManage.elm +++ b/modules/webapp/src/main/elm/Comp/ShareManage.elm @@ -98,7 +98,7 @@ loadShares = --- update -update : Flags -> Msg -> Model -> ( Model, Cmd Msg ) +update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) update flags msg model = case msg of InitNewShare -> @@ -118,14 +118,18 @@ update flags msg model = else Cmd.none + , Sub.none ) FormMsg lm -> let - ( fm, fc ) = + ( fm, fc, fs ) = Comp.ShareForm.update flags lm model.formModel in - ( { model | formModel = fm }, Cmd.map FormMsg fc ) + ( { model | formModel = fm, formError = FormErrorNone } + , Cmd.map FormMsg fc + , Sub.map FormMsg fs + ) TableMsg lm -> let @@ -137,75 +141,79 @@ update flags msg model = setShare share flags model RequestDelete -> - ( { model | deleteConfirm = DeleteConfirmOn }, Cmd.none ) + ( { model | deleteConfirm = DeleteConfirmOn }, Cmd.none, Sub.none ) CancelDelete -> - ( { model | deleteConfirm = DeleteConfirmOff }, Cmd.none ) + ( { model | deleteConfirm = DeleteConfirmOff }, Cmd.none, Sub.none ) DeleteShareNow id -> ( { model | deleteConfirm = DeleteConfirmOff, loading = True } , Api.deleteShare flags id DeleteShareResp + , Sub.none ) LoadShares -> - ( { model | loading = True }, Api.getShares flags LoadSharesResp ) + ( { model | loading = True }, Api.getShares flags LoadSharesResp, Sub.none ) LoadSharesResp (Ok list) -> - ( { model | loading = False, shares = list.items, formError = FormErrorNone }, Cmd.none ) + ( { model | loading = False, shares = list.items, formError = FormErrorNone } + , Cmd.none + , Sub.none + ) LoadSharesResp (Err err) -> - ( { model | loading = False, formError = FormErrorHttp err }, Cmd.none ) + ( { model | loading = False, formError = FormErrorHttp err }, Cmd.none, Sub.none ) Submit -> case Comp.ShareForm.getShare model.formModel of Just ( id, data ) -> if id == "" then - ( { model | loading = True }, Api.addShare flags data AddShareResp ) + ( { model | loading = True }, Api.addShare flags data AddShareResp, Sub.none ) else - ( { model | loading = True }, Api.updateShare flags id data UpdateShareResp ) + ( { model | loading = True }, Api.updateShare flags id data UpdateShareResp, Sub.none ) Nothing -> - ( { model | formError = FormErrorInvalid }, Cmd.none ) + ( { model | formError = FormErrorInvalid }, Cmd.none, Sub.none ) AddShareResp (Ok res) -> if res.success then - ( model, Api.getShare flags res.id GetShareResp ) + ( model, Api.getShare flags res.id GetShareResp, Sub.none ) else - ( { model | loading = False, formError = FormErrorSubmit res.message }, Cmd.none ) + ( { model | loading = False, formError = FormErrorSubmit res.message }, Cmd.none, Sub.none ) AddShareResp (Err err) -> - ( { model | loading = False, formError = FormErrorHttp err }, Cmd.none ) + ( { model | loading = False, formError = FormErrorHttp err }, Cmd.none, Sub.none ) UpdateShareResp (Ok res) -> if res.success then - ( model, Api.getShare flags model.formModel.share.id GetShareResp ) + ( model, Api.getShare flags model.formModel.share.id GetShareResp, Sub.none ) else - ( { model | loading = False, formError = FormErrorSubmit res.message }, Cmd.none ) + ( { model | loading = False, formError = FormErrorSubmit res.message }, Cmd.none, Sub.none ) UpdateShareResp (Err err) -> - ( { model | loading = False, formError = FormErrorHttp err }, Cmd.none ) + ( { model | loading = False, formError = FormErrorHttp err }, Cmd.none, Sub.none ) GetShareResp (Ok share) -> setShare share flags model GetShareResp (Err err) -> - ( { model | formError = FormErrorHttp err }, Cmd.none ) + ( { model | formError = FormErrorHttp err }, Cmd.none, Sub.none ) DeleteShareResp (Ok res) -> if res.success then update flags (SetViewMode Table) { model | loading = False } else - ( { model | formError = FormErrorSubmit res.message, loading = False }, Cmd.none ) + ( { model | formError = FormErrorSubmit res.message, loading = False }, Cmd.none, Sub.none ) DeleteShareResp (Err err) -> - ( { model | formError = FormErrorHttp err, loading = False }, Cmd.none ) + ( { model | formError = FormErrorHttp err, loading = False }, Cmd.none, Sub.none ) -setShare : ShareDetail -> Flags -> Model -> ( Model, Cmd Msg ) +setShare : ShareDetail -> Flags -> Model -> ( Model, Cmd Msg, Sub Msg ) setShare share flags model = let nextModel = @@ -214,10 +222,10 @@ setShare share flags model = initClipboard = Ports.initClipboard (Comp.ShareView.clipboardData share) - ( nm, nc ) = + ( nm, nc, ns ) = update flags (FormMsg <| Comp.ShareForm.setShare share) nextModel in - ( nm, Cmd.batch [ initClipboard, nc ] ) + ( nm, Cmd.batch [ initClipboard, nc ], ns ) diff --git a/modules/webapp/src/main/elm/Page/CollectiveSettings/Update.elm b/modules/webapp/src/main/elm/Page/CollectiveSettings/Update.elm index 1e711acd..b8a63d74 100644 --- a/modules/webapp/src/main/elm/Page/CollectiveSettings/Update.elm +++ b/modules/webapp/src/main/elm/Page/CollectiveSettings/Update.elm @@ -16,7 +16,7 @@ import Data.Flags exposing (Flags) import Page.CollectiveSettings.Data exposing (..) -update : Flags -> Msg -> Model -> ( Model, Cmd Msg ) +update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) update flags msg model = case msg of SetTab t -> @@ -45,21 +45,21 @@ update flags msg model = ( m2, c2 ) = Comp.SourceManage.update flags m model.sourceModel in - ( { model | sourceModel = m2 }, Cmd.map SourceMsg c2 ) + ( { model | sourceModel = m2 }, Cmd.map SourceMsg c2, Sub.none ) ShareMsg lm -> let - ( sm, sc ) = + ( sm, sc, ss ) = Comp.ShareManage.update flags lm model.shareModel in - ( { model | shareModel = sm }, Cmd.map ShareMsg sc ) + ( { model | shareModel = sm }, Cmd.map ShareMsg sc, Sub.map ShareMsg ss ) UserMsg m -> let ( m2, c2 ) = Comp.UserManage.update flags m model.userModel in - ( { model | userModel = m2 }, Cmd.map UserMsg c2 ) + ( { model | userModel = m2 }, Cmd.map UserMsg c2, Sub.none ) SettingsFormMsg m -> let @@ -76,6 +76,7 @@ update flags msg model = in ( { model | settingsModel = m2, formState = InitialState } , Cmd.batch [ cmd, Cmd.map SettingsFormMsg c2 ] + , Sub.none ) Init -> @@ -84,13 +85,14 @@ update flags msg model = [ Api.getInsights flags GetInsightsResp , Api.getCollectiveSettings flags CollectiveSettingsResp ] + , Sub.none ) GetInsightsResp (Ok data) -> - ( { model | insights = data }, Cmd.none ) + ( { model | insights = data }, Cmd.none, Sub.none ) GetInsightsResp (Err _) -> - ( model, Cmd.none ) + ( model, Cmd.none, Sub.none ) CollectiveSettingsResp (Ok data) -> let @@ -99,10 +101,11 @@ update flags msg model = in ( { model | settingsModel = cm } , Cmd.map SettingsFormMsg cc + , Sub.none ) CollectiveSettingsResp (Err _) -> - ( model, Cmd.none ) + ( model, Cmd.none, Sub.none ) SubmitResp (Ok res) -> ( { model @@ -114,7 +117,8 @@ update flags msg model = SubmitFailed res.message } , Cmd.none + , Sub.none ) SubmitResp (Err err) -> - ( { model | formState = SubmitError err }, Cmd.none ) + ( { model | formState = SubmitError err }, Cmd.none, Sub.none )