From 79fc5a30a1fbbe325f2c440ccc53e6080b55c30e Mon Sep 17 00:00:00 2001 From: Eike Kettner Date: Sun, 7 Jun 2020 00:51:11 +0200 Subject: [PATCH] Introduce ui settings and let user set page size for item search --- modules/webapp/src/main/elm/App/Data.elm | 2 + modules/webapp/src/main/elm/App/Update.elm | 26 +++- .../src/main/elm/Comp/UiSettingsForm.elm | 93 ++++++++++++++ .../src/main/elm/Comp/UiSettingsManage.elm | 119 ++++++++++++++++++ .../webapp/src/main/elm/Data/UiSettings.elm | 63 ++++++++++ modules/webapp/src/main/elm/Main.elm | 13 +- .../webapp/src/main/elm/Page/Home/Data.elm | 25 ++-- .../webapp/src/main/elm/Page/Home/Update.elm | 40 ++++-- .../src/main/elm/Page/UserSettings/Data.elm | 7 ++ .../src/main/elm/Page/UserSettings/Update.elm | 99 +++++++++------ .../src/main/elm/Page/UserSettings/View.elm | 19 +++ modules/webapp/src/main/elm/Ports.elm | 52 +++++++- modules/webapp/src/main/webjar/docspell.js | 38 ++++++ 13 files changed, 530 insertions(+), 66 deletions(-) create mode 100644 modules/webapp/src/main/elm/Comp/UiSettingsForm.elm create mode 100644 modules/webapp/src/main/elm/Comp/UiSettingsManage.elm create mode 100644 modules/webapp/src/main/elm/Data/UiSettings.elm diff --git a/modules/webapp/src/main/elm/App/Data.elm b/modules/webapp/src/main/elm/App/Data.elm index 01aacda2..863d7048 100644 --- a/modules/webapp/src/main/elm/App/Data.elm +++ b/modules/webapp/src/main/elm/App/Data.elm @@ -11,6 +11,7 @@ import Api.Model.VersionInfo exposing (VersionInfo) import Browser exposing (UrlRequest) import Browser.Navigation exposing (Key) import Data.Flags exposing (Flags) +import Data.UiSettings exposing (UiSettings) import Http import Page exposing (Page(..)) import Page.CollectiveSettings.Data @@ -90,6 +91,7 @@ type Msg | LogoutResp (Result Http.Error ()) | SessionCheckResp (Result Http.Error AuthResult) | ToggleNavMenu + | GetUiSettings UiSettings isSignedIn : Flags -> Bool diff --git a/modules/webapp/src/main/elm/App/Update.elm b/modules/webapp/src/main/elm/App/Update.elm index 60a7ffd1..596583f9 100644 --- a/modules/webapp/src/main/elm/App/Update.elm +++ b/modules/webapp/src/main/elm/App/Update.elm @@ -40,7 +40,7 @@ update msg model = ( m, c, s ) = updateWithSub msg model in - ( { m | subs = s }, c ) + ( { m | subs = Sub.batch [ m.subs, s ] }, c ) updateWithSub : Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) @@ -92,7 +92,10 @@ updateWithSub msg model = ) LogoutResp _ -> - ( { model | loginModel = Page.Login.Data.emptyModel }, Page.goto (LoginPage Nothing), Sub.none ) + ( { model | loginModel = Page.Login.Data.emptyModel } + , Page.goto (LoginPage Nothing) + , Sub.none + ) SessionCheckResp res -> case res of @@ -171,6 +174,14 @@ updateWithSub msg model = ToggleNavMenu -> ( { model | navMenuOpen = not model.navMenuOpen }, Cmd.none, Sub.none ) + GetUiSettings settings -> + Util.Update.andThen1 + [ updateUserSettings (Page.UserSettings.Data.GetUiSettings settings) + , updateHome (Page.Home.Data.GetUiSettings settings) + ] + model + |> noSub + updateItemDetail : Page.ItemDetail.Data.Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) updateItemDetail lmsg model = @@ -241,10 +252,17 @@ updateQueue lmsg model = updateUserSettings : Page.UserSettings.Data.Msg -> Model -> ( Model, Cmd Msg ) updateUserSettings lmsg model = let - ( lm, lc ) = + ( lm, lc, ls ) = Page.UserSettings.Update.update model.flags lmsg model.userSettingsModel in - ( { model | userSettingsModel = lm } + ( { model + | userSettingsModel = lm + , subs = + Sub.batch + [ model.subs + , Sub.map UserSettingsMsg ls + ] + } , Cmd.map UserSettingsMsg lc ) diff --git a/modules/webapp/src/main/elm/Comp/UiSettingsForm.elm b/modules/webapp/src/main/elm/Comp/UiSettingsForm.elm new file mode 100644 index 00000000..7ed59c81 --- /dev/null +++ b/modules/webapp/src/main/elm/Comp/UiSettingsForm.elm @@ -0,0 +1,93 @@ +module Comp.UiSettingsForm exposing + ( Model + , Msg + , init + , initWith + , update + , view + ) + +import Comp.IntField +import Data.UiSettings exposing (StoredUiSettings, UiSettings) +import Html exposing (..) +import Html.Attributes exposing (..) + + +type alias Model = + { defaults : UiSettings + , input : StoredUiSettings + , searchPageSizeModel : Comp.IntField.Model + } + + +initWith : UiSettings -> Model +initWith defaults = + { defaults = defaults + , input = Data.UiSettings.toStoredUiSettings defaults + , searchPageSizeModel = + Comp.IntField.init + (Just 10) + (Just 500) + False + "Item search page" + } + + +init : Model +init = + initWith Data.UiSettings.defaults + + +changeInput : (StoredUiSettings -> StoredUiSettings) -> Model -> StoredUiSettings +changeInput change model = + change model.input + + +type Msg + = SearchPageSizeMsg Comp.IntField.Msg + + +getSettings : Model -> UiSettings +getSettings model = + Data.UiSettings.merge model.input model.defaults + + + +--- Update + + +update : Msg -> Model -> ( Model, Maybe UiSettings ) +update msg model = + case msg of + SearchPageSizeMsg lm -> + let + ( m, n ) = + Comp.IntField.update lm model.searchPageSizeModel + + model_ = + { model + | searchPageSizeModel = m + , input = changeInput (\s -> { s | itemSearchPageSize = n }) model + } + + nextSettings = + Maybe.map (\_ -> getSettings model_) n + in + ( model_, nextSettings ) + + + +--- View + + +view : Model -> Html Msg +view model = + div [ class "ui form" ] + [ Html.map SearchPageSizeMsg + (Comp.IntField.viewWithInfo + "Maximum results in one page when searching items." + model.input.itemSearchPageSize + "" + model.searchPageSizeModel + ) + ] diff --git a/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm b/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm new file mode 100644 index 00000000..579b88c3 --- /dev/null +++ b/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm @@ -0,0 +1,119 @@ +module Comp.UiSettingsManage exposing + ( Model + , Msg + , init + , update + , view + ) + +import Api.Model.BasicResult exposing (BasicResult) +import Comp.UiSettingsForm +import Data.Flags exposing (Flags) +import Data.UiSettings exposing (UiSettings) +import Html exposing (..) +import Html.Attributes exposing (..) +import Html.Events exposing (onClick) +import Ports + + +type alias Model = + { formModel : Comp.UiSettingsForm.Model + , settings : Maybe UiSettings + , message : Maybe BasicResult + } + + +type Msg + = UiSettingsFormMsg Comp.UiSettingsForm.Msg + | Submit + | SettingsSaved + + +init : UiSettings -> Model +init defaults = + { formModel = Comp.UiSettingsForm.initWith defaults + , settings = Nothing + , message = Nothing + } + + + +--- update + + +update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg ) +update flags msg model = + case msg of + UiSettingsFormMsg lm -> + let + ( m_, sett ) = + Comp.UiSettingsForm.update lm model.formModel + in + ( { model + | formModel = m_ + , settings = sett + , message = Nothing + } + , Cmd.none + , Sub.none + ) + + Submit -> + case model.settings of + Just s -> + ( { model | message = Nothing } + , Ports.storeUiSettings flags s + , Ports.onUiSettingsSaved SettingsSaved + ) + + Nothing -> + ( { model | message = Just (BasicResult False "Settings unchanged or invalid.") } + , Cmd.none + , Sub.none + ) + + SettingsSaved -> + ( { model | message = Just (BasicResult True "Settings saved.") } + , Cmd.none + , Sub.none + ) + + + +--- View + + +isError : Model -> Bool +isError model = + Maybe.map .success model.message == Just False + + +isSuccess : Model -> Bool +isSuccess model = + Maybe.map .success model.message == Just True + + +view : String -> Model -> Html Msg +view classes model = + div [ class classes ] + [ Html.map UiSettingsFormMsg (Comp.UiSettingsForm.view model.formModel) + , div [ class "ui divider" ] [] + , button + [ class "ui primary button" + , onClick Submit + ] + [ text "Submit" + ] + , div + [ classList + [ ( "ui message", True ) + , ( "success", isSuccess model ) + , ( "error", isError model ) + , ( "hidden invisible", model.message == Nothing ) + ] + ] + [ Maybe.map .message model.message + |> Maybe.withDefault "" + |> text + ] + ] diff --git a/modules/webapp/src/main/elm/Data/UiSettings.elm b/modules/webapp/src/main/elm/Data/UiSettings.elm new file mode 100644 index 00000000..7498f088 --- /dev/null +++ b/modules/webapp/src/main/elm/Data/UiSettings.elm @@ -0,0 +1,63 @@ +module Data.UiSettings exposing + ( StoredUiSettings + , UiSettings + , defaults + , merge + , mergeDefaults + , toStoredUiSettings + ) + +{-| Settings for the web ui. All fields should be optional, since it +is loaded from local storage. + +Making fields optional, allows it to evolve without breaking previous +versions. Also if a user is logged out, an empty object is send to +force default settings. + +-} + + +type alias StoredUiSettings = + { itemSearchPageSize : Maybe Int + } + + +{-| Settings for the web ui. These fields are all mandatory, since +there is always a default value. + +When loaded from local storage, all optional fields can fallback to a +default value, converting the StoredUiSettings into a UiSettings. + +-} +type alias UiSettings = + { itemSearchPageSize : Int + } + + +defaults : UiSettings +defaults = + { itemSearchPageSize = 90 + } + + +merge : StoredUiSettings -> UiSettings -> UiSettings +merge given fallback = + { itemSearchPageSize = + choose given.itemSearchPageSize fallback.itemSearchPageSize + } + + +mergeDefaults : StoredUiSettings -> UiSettings +mergeDefaults given = + merge given defaults + + +toStoredUiSettings : UiSettings -> StoredUiSettings +toStoredUiSettings settings = + { itemSearchPageSize = Just settings.itemSearchPageSize + } + + +choose : Maybe a -> a -> a +choose m1 m2 = + Maybe.withDefault m2 m1 diff --git a/modules/webapp/src/main/elm/Main.elm b/modules/webapp/src/main/elm/Main.elm index 0206cee9..fea343a8 100644 --- a/modules/webapp/src/main/elm/Main.elm +++ b/modules/webapp/src/main/elm/Main.elm @@ -11,6 +11,7 @@ import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (..) import Page +import Ports import Url exposing (Url) @@ -59,7 +60,12 @@ init flags url key = Cmd.none in ( m - , Cmd.batch [ cmd, Api.versionInfo flags VersionResp, sessionCheck ] + , Cmd.batch + [ cmd + , Api.versionInfo flags VersionResp + , sessionCheck + , Ports.getUiSettings flags + ] ) @@ -76,4 +82,7 @@ viewDoc model = subscriptions : Model -> Sub Msg subscriptions model = - model.subs + Sub.batch + [ model.subs + , Ports.loadUiSettings GetUiSettings + ] diff --git a/modules/webapp/src/main/elm/Page/Home/Data.elm b/modules/webapp/src/main/elm/Page/Home/Data.elm index baab5e9a..0dc9baf0 100644 --- a/modules/webapp/src/main/elm/Page/Home/Data.elm +++ b/modules/webapp/src/main/elm/Page/Home/Data.elm @@ -6,7 +6,6 @@ module Page.Home.Data exposing , init , itemNav , resultsBelowLimit - , searchLimit ) import Api @@ -15,6 +14,7 @@ import Comp.ItemCardList import Comp.SearchMenu import Data.Flags exposing (Flags) import Data.Items +import Data.UiSettings exposing (UiSettings) import Http @@ -27,6 +27,7 @@ type alias Model = , searchOffset : Int , moreAvailable : Bool , moreInProgress : Bool + , uiSettings : UiSettings } @@ -40,6 +41,7 @@ init _ = , searchOffset = 0 , moreAvailable = True , moreInProgress = False + , uiSettings = Data.UiSettings.defaults } @@ -49,9 +51,11 @@ type Msg | ResetSearch | ItemCardListMsg Comp.ItemCardList.Msg | ItemSearchResp (Result Http.Error ItemLightList) + | ItemSearchAddResp (Result Http.Error ItemLightList) | DoSearch | ToggleSearchMenu | LoadMore + | GetUiSettings UiSettings type ViewMode @@ -73,24 +77,23 @@ itemNav id model = } -searchLimit : Int -searchLimit = - 90 - - -doSearchCmd : Flags -> Int -> Comp.SearchMenu.Model -> Cmd Msg +doSearchCmd : Flags -> Int -> Model -> Cmd Msg doSearchCmd flags offset model = let smask = - Comp.SearchMenu.getItemSearch model + Comp.SearchMenu.getItemSearch model.searchMenuModel mask = { smask - | limit = searchLimit + | limit = model.uiSettings.itemSearchPageSize , offset = offset } in - Api.itemSearch flags mask ItemSearchResp + if offset == 0 then + Api.itemSearch flags mask ItemSearchResp + + else + Api.itemSearch flags mask ItemSearchAddResp resultsBelowLimit : Model -> Bool @@ -99,4 +102,4 @@ resultsBelowLimit model = len = Data.Items.length model.itemListModel.results in - len < searchLimit + len < model.uiSettings.itemSearchPageSize diff --git a/modules/webapp/src/main/elm/Page/Home/Update.elm b/modules/webapp/src/main/elm/Page/Home/Update.elm index effd80cf..33d9a7d3 100644 --- a/modules/webapp/src/main/elm/Page/Home/Update.elm +++ b/modules/webapp/src/main/elm/Page/Home/Update.elm @@ -15,7 +15,6 @@ update key flags msg model = Init -> Util.Update.andThen1 [ update key flags (SearchMenuMsg Comp.SearchMenu.Init) - , doSearch flags ] model @@ -63,7 +62,22 @@ update key flags msg model = ItemSearchResp (Ok list) -> let noff = - model.searchOffset + searchLimit + model.uiSettings.itemSearchPageSize + + m = + { model + | searchInProgress = False + , searchOffset = noff + , viewMode = Listing + , moreAvailable = list.groups /= [] + } + in + update key flags (ItemCardListMsg (Comp.ItemCardList.SetResults list)) m + + ItemSearchAddResp (Ok list) -> + let + noff = + model.searchOffset + model.uiSettings.itemSearchPageSize m = { model @@ -74,11 +88,14 @@ update key flags msg model = , moreAvailable = list.groups /= [] } in - if model.searchOffset == 0 then - update key flags (ItemCardListMsg (Comp.ItemCardList.SetResults list)) m + update key flags (ItemCardListMsg (Comp.ItemCardList.AddResults list)) m - else - update key flags (ItemCardListMsg (Comp.ItemCardList.AddResults list)) m + ItemSearchAddResp (Err _) -> + ( { model + | moreInProgress = False + } + , Cmd.none + ) ItemSearchResp (Err _) -> ( { model @@ -106,12 +123,19 @@ update key flags msg model = else ( model, Cmd.none ) + GetUiSettings settings -> + let + m_ = + { model | uiSettings = settings } + in + doSearch flags m_ + doSearch : Flags -> Model -> ( Model, Cmd Msg ) doSearch flags model = let cmd = - doSearchCmd flags 0 model.searchMenuModel + doSearchCmd flags 0 model in ( { model | searchInProgress = True @@ -126,7 +150,7 @@ doSearchMore : Flags -> Model -> ( Model, Cmd Msg ) doSearchMore flags model = let cmd = - doSearchCmd flags model.searchOffset model.searchMenuModel + doSearchCmd flags model.searchOffset model in ( { model | moreInProgress = True, viewMode = Listing } , cmd diff --git a/modules/webapp/src/main/elm/Page/UserSettings/Data.elm b/modules/webapp/src/main/elm/Page/UserSettings/Data.elm index 96cbeadf..9b66d955 100644 --- a/modules/webapp/src/main/elm/Page/UserSettings/Data.elm +++ b/modules/webapp/src/main/elm/Page/UserSettings/Data.elm @@ -10,7 +10,9 @@ import Comp.EmailSettingsManage import Comp.ImapSettingsManage import Comp.NotificationForm import Comp.ScanMailboxManage +import Comp.UiSettingsManage import Data.Flags exposing (Flags) +import Data.UiSettings exposing (UiSettings) type alias Model = @@ -20,6 +22,7 @@ type alias Model = , imapSettingsModel : Comp.ImapSettingsManage.Model , notificationModel : Comp.NotificationForm.Model , scanMailboxModel : Comp.ScanMailboxManage.Model + , uiSettingsModel : Comp.UiSettingsManage.Model } @@ -31,6 +34,7 @@ emptyModel flags = , imapSettingsModel = Comp.ImapSettingsManage.emptyModel , notificationModel = Tuple.first (Comp.NotificationForm.init flags) , scanMailboxModel = Tuple.first (Comp.ScanMailboxManage.init flags) + , uiSettingsModel = Comp.UiSettingsManage.init Data.UiSettings.defaults } @@ -40,6 +44,7 @@ type Tab | ImapSettingsTab | NotificationTab | ScanMailboxTab + | UiSettingsTab type Msg @@ -49,3 +54,5 @@ type Msg | NotificationMsg Comp.NotificationForm.Msg | ImapSettingsMsg Comp.ImapSettingsManage.Msg | ScanMailboxMsg Comp.ScanMailboxManage.Msg + | GetUiSettings UiSettings + | UiSettingsMsg Comp.UiSettingsManage.Msg diff --git a/modules/webapp/src/main/elm/Page/UserSettings/Update.elm b/modules/webapp/src/main/elm/Page/UserSettings/Update.elm index 41295f05..23441716 100644 --- a/modules/webapp/src/main/elm/Page/UserSettings/Update.elm +++ b/modules/webapp/src/main/elm/Page/UserSettings/Update.elm @@ -5,75 +5,76 @@ import Comp.EmailSettingsManage import Comp.ImapSettingsManage import Comp.NotificationForm import Comp.ScanMailboxManage +import Comp.UiSettingsManage import Data.Flags exposing (Flags) import Page.UserSettings.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 -> let m = { model | currentTab = Just t } - - ( m2, cmd ) = - case t of - EmailSettingsTab -> - let - ( em, c ) = - Comp.EmailSettingsManage.init flags - in - ( { m | emailSettingsModel = em }, Cmd.map EmailSettingsMsg c ) - - ImapSettingsTab -> - let - ( em, c ) = - Comp.ImapSettingsManage.init flags - in - ( { m | imapSettingsModel = em }, Cmd.map ImapSettingsMsg c ) - - ChangePassTab -> - ( m, Cmd.none ) - - NotificationTab -> - let - initCmd = - Cmd.map NotificationMsg - (Tuple.second (Comp.NotificationForm.init flags)) - in - ( m, initCmd ) - - ScanMailboxTab -> - let - initCmd = - Cmd.map ScanMailboxMsg - (Tuple.second (Comp.ScanMailboxManage.init flags)) - in - ( m, initCmd ) in - ( m2, cmd ) + case t of + EmailSettingsTab -> + let + ( em, c ) = + Comp.EmailSettingsManage.init flags + in + ( { m | emailSettingsModel = em }, Cmd.map EmailSettingsMsg c, Sub.none ) + + ImapSettingsTab -> + let + ( em, c ) = + Comp.ImapSettingsManage.init flags + in + ( { m | imapSettingsModel = em }, Cmd.map ImapSettingsMsg c, Sub.none ) + + ChangePassTab -> + ( m, Cmd.none, Sub.none ) + + NotificationTab -> + let + initCmd = + Cmd.map NotificationMsg + (Tuple.second (Comp.NotificationForm.init flags)) + in + ( m, initCmd, Sub.none ) + + ScanMailboxTab -> + let + initCmd = + Cmd.map ScanMailboxMsg + (Tuple.second (Comp.ScanMailboxManage.init flags)) + in + ( m, initCmd, Sub.none ) + + UiSettingsTab -> + ( m, Cmd.none, Sub.none ) ChangePassMsg m -> let ( m2, c2 ) = Comp.ChangePasswordForm.update flags m model.changePassModel in - ( { model | changePassModel = m2 }, Cmd.map ChangePassMsg c2 ) + ( { model | changePassModel = m2 }, Cmd.map ChangePassMsg c2, Sub.none ) EmailSettingsMsg m -> let ( m2, c2 ) = Comp.EmailSettingsManage.update flags m model.emailSettingsModel in - ( { model | emailSettingsModel = m2 }, Cmd.map EmailSettingsMsg c2 ) + ( { model | emailSettingsModel = m2 }, Cmd.map EmailSettingsMsg c2, Sub.none ) ImapSettingsMsg m -> let ( m2, c2 ) = Comp.ImapSettingsManage.update flags m model.imapSettingsModel in - ( { model | imapSettingsModel = m2 }, Cmd.map ImapSettingsMsg c2 ) + ( { model | imapSettingsModel = m2 }, Cmd.map ImapSettingsMsg c2, Sub.none ) NotificationMsg lm -> let @@ -82,6 +83,7 @@ update flags msg model = in ( { model | notificationModel = m2 } , Cmd.map NotificationMsg c2 + , Sub.none ) ScanMailboxMsg lm -> @@ -91,4 +93,21 @@ update flags msg model = in ( { model | scanMailboxModel = m2 } , Cmd.map ScanMailboxMsg c2 + , Sub.none + ) + + GetUiSettings settings -> + ( { model | uiSettingsModel = Comp.UiSettingsManage.init settings } + , Cmd.none + , Sub.none + ) + + UiSettingsMsg lm -> + let + ( m2, c2, s2 ) = + Comp.UiSettingsManage.update flags lm model.uiSettingsModel + in + ( { model | uiSettingsModel = m2 } + , Cmd.map UiSettingsMsg c2 + , Sub.map UiSettingsMsg s2 ) diff --git a/modules/webapp/src/main/elm/Page/UserSettings/View.elm b/modules/webapp/src/main/elm/Page/UserSettings/View.elm index 12bdc5de..6b1dba06 100644 --- a/modules/webapp/src/main/elm/Page/UserSettings/View.elm +++ b/modules/webapp/src/main/elm/Page/UserSettings/View.elm @@ -5,6 +5,7 @@ import Comp.EmailSettingsManage import Comp.ImapSettingsManage import Comp.NotificationForm import Comp.ScanMailboxManage +import Comp.UiSettingsManage import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (onClick) @@ -26,6 +27,7 @@ view model = , makeTab model ImapSettingsTab "E-Mail Settings (IMAP)" "mail icon" , makeTab model NotificationTab "Notification Task" "bullhorn icon" , makeTab model ScanMailboxTab "Scan Mailbox Task" "envelope open outline icon" + , makeTab model UiSettingsTab "UI Settings" "cog icon" ] ] ] @@ -47,6 +49,9 @@ view model = Just ScanMailboxTab -> viewScanMailboxManage model + Just UiSettingsTab -> + viewUiSettings model + Nothing -> [] ) @@ -66,6 +71,20 @@ makeTab model tab header icon = ] +viewUiSettings : Model -> List (Html Msg) +viewUiSettings model = + [ h2 [ class "ui header" ] + [ i [ class "cog icon" ] [] + , text "UI Settings" + ] + , p [] + [ text "These settings only affect the web ui. They are stored in the browser, " + , text "so they are separated between browsers and devices." + ] + , Html.map UiSettingsMsg (Comp.UiSettingsManage.view "ui segment" model.uiSettingsModel) + ] + + viewEmailSettings : Model -> List (Html Msg) viewEmailSettings model = [ h2 [ class "ui header" ] diff --git a/modules/webapp/src/main/elm/Ports.elm b/modules/webapp/src/main/elm/Ports.elm index 100852c3..2c711b8e 100644 --- a/modules/webapp/src/main/elm/Ports.elm +++ b/modules/webapp/src/main/elm/Ports.elm @@ -1,14 +1,22 @@ port module Ports exposing - ( removeAccount + ( getUiSettings + , loadUiSettings + , onUiSettingsSaved + , removeAccount , scrollToElem , setAccount , setAllProgress , setProgress + , storeUiSettings ) import Api.Model.AuthResult exposing (AuthResult) +import Data.Flags exposing (Flags) +import Data.UiSettings exposing (StoredUiSettings, UiSettings) +{-| Save the result of authentication to local storage. +-} port setAccount : AuthResult -> Cmd msg @@ -22,3 +30,45 @@ port setAllProgress : ( String, Int ) -> Cmd msg port scrollToElem : String -> Cmd msg + + +port saveUiSettings : ( AuthResult, UiSettings ) -> Cmd msg + + +port receiveUiSettings : (StoredUiSettings -> msg) -> Sub msg + + +port requestUiSettings : ( AuthResult, UiSettings ) -> Cmd msg + + +port uiSettingsSaved : (() -> msg) -> Sub msg + + +onUiSettingsSaved : msg -> Sub msg +onUiSettingsSaved m = + uiSettingsSaved (\_ -> m) + + +storeUiSettings : Flags -> UiSettings -> Cmd msg +storeUiSettings flags settings = + case flags.account of + Just ar -> + saveUiSettings ( ar, settings ) + + Nothing -> + Cmd.none + + +loadUiSettings : (UiSettings -> msg) -> Sub msg +loadUiSettings tagger = + receiveUiSettings (Data.UiSettings.mergeDefaults >> tagger) + + +getUiSettings : Flags -> Cmd msg +getUiSettings flags = + case flags.account of + Just ar -> + requestUiSettings ( ar, Data.UiSettings.defaults ) + + Nothing -> + Cmd.none diff --git a/modules/webapp/src/main/webjar/docspell.js b/modules/webapp/src/main/webjar/docspell.js index 162c5b36..229eecbb 100644 --- a/modules/webapp/src/main/webjar/docspell.js +++ b/modules/webapp/src/main/webjar/docspell.js @@ -5,6 +5,7 @@ var elmApp = Elm.Main.init({ flags: elmFlags }); + elmApp.ports.setAccount.subscribe(function(authResult) { console.log("Add account from local storage"); localStorage.setItem("account", JSON.stringify(authResult)); @@ -45,3 +46,40 @@ elmApp.ports.scrollToElem.subscribe(function(id) { }, 20); } }); + +elmApp.ports.saveUiSettings.subscribe(function(args) { + if (Array.isArray(args) && args.length == 2) { + var authResult = args[0]; + var settings = args[1]; + if (authResult && settings) { + var key = authResult.collective + "/" + authResult.user + "/uiSettings"; + console.log("Save ui settings to local storage"); + localStorage.setItem(key, JSON.stringify(settings)); + elmApp.ports.receiveUiSettings.send(settings); + elmApp.ports.uiSettingsSaved.send(null); + } + } +}); + +elmApp.ports.requestUiSettings.subscribe(function(args) { + console.log("Requesting ui settings"); + if (Array.isArray(args) && args.length == 2) { + var account = args[0]; + var defaults = args[1]; + var collective = account ? account.collective : null; + var user = account ? account.user : null; + if (collective && user) { + var key = collective + "/" + user + "/uiSettings"; + var settings = localStorage.getItem(key); + var data = settings ? JSON.parse(settings) : null; + if (data && defaults) { + $.extend(defaults, data); + elmApp.ports.receiveUiSettings.send(defaults); + } else if (defaults) { + elmApp.ports.receiveUiSettings.send(defaults); + } + } else if (defaults) { + elmApp.ports.receiveUiSettings.send(defaults); + } + } +});