From 9f763578795d1e54312f400ca094dba8df9239ed Mon Sep 17 00:00:00 2001 From: Eike Kettner Date: Tue, 25 May 2021 19:04:07 +0200 Subject: [PATCH] Add api functions for getting/setting client settings --- modules/webapp/src/main/elm/Api.elm | 42 +++++++++++ .../src/main/elm/Comp/UiSettingsManage.elm | 11 ++- .../webapp/src/main/elm/Data/UiSettings.elm | 69 +++++++++++++++++++ modules/webapp/src/main/elm/Ports.elm | 1 - 4 files changed, 121 insertions(+), 2 deletions(-) diff --git a/modules/webapp/src/main/elm/Api.elm b/modules/webapp/src/main/elm/Api.elm index 84683a60..c883d71c 100644 --- a/modules/webapp/src/main/elm/Api.elm +++ b/modules/webapp/src/main/elm/Api.elm @@ -37,6 +37,7 @@ module Api exposing , deleteUser , fileURL , getAttachmentMeta + , getClientSettings , getCollective , getCollectiveSettings , getContacts @@ -91,6 +92,7 @@ module Api exposing , removeTagsMultiple , reprocessItem , reprocessMultiple + , saveClientSettings , sendMail , setAttachmentName , setCollectiveSettings @@ -204,8 +206,10 @@ import Api.Model.VersionInfo exposing (VersionInfo) import Data.ContactType exposing (ContactType) import Data.Flags exposing (Flags) import Data.Priority exposing (Priority) +import Data.UiSettings exposing (UiSettings) import File exposing (File) import Http +import Json.Decode as JsonDecode import Json.Encode as JsonEncode import Set exposing (Set) import Task @@ -1981,6 +1985,44 @@ getItemProposals flags item receive = +--- Client Settings + + +getClientSettings : Flags -> (Result Http.Error UiSettings -> msg) -> Cmd msg +getClientSettings flags receive = + let + defaults = + Data.UiSettings.defaults + + decoder = + JsonDecode.map (\s -> Data.UiSettings.merge s defaults) + Data.UiSettings.storedUiSettingsDecoder + in + Http2.authGet + { url = flags.config.baseUrl ++ "/api/v1/sec/clientSettings/webClient" + , account = getAccount flags + , expect = Http.expectJson receive decoder + } + + +saveClientSettings : Flags -> UiSettings -> (Result Http.Error BasicResult -> msg) -> Cmd msg +saveClientSettings flags settings receive = + let + storedSettings = + Data.UiSettings.toStoredUiSettings settings + + encode = + Data.UiSettings.storedUiSettingsEncode storedSettings + in + Http2.authPut + { url = flags.config.baseUrl ++ "/api/v1/sec/clientSettings/webClient" + , account = getAccount flags + , body = Http.jsonBody encode + , expect = Http.expectJson receive Api.Model.BasicResult.decoder + } + + + --- Helper diff --git a/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm b/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm index c1e60230..c49d6da1 100644 --- a/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm +++ b/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm @@ -6,6 +6,7 @@ module Comp.UiSettingsManage exposing , view2 ) +import Api import Api.Model.BasicResult exposing (BasicResult) import Comp.MenuBar as MB import Comp.UiSettingsForm @@ -14,6 +15,7 @@ import Data.UiSettings exposing (UiSettings) import Html exposing (..) import Html.Attributes exposing (..) import Html.Events exposing (onClick) +import Http import Messages.Comp.UiSettingsManage exposing (Texts) import Ports import Styles as S @@ -31,6 +33,7 @@ type Msg | Submit | SettingsSaved | UpdateSettings + | SaveSettingsResp (Result Http.Error BasicResult) init : Flags -> UiSettings -> ( Model, Cmd Msg ) @@ -85,7 +88,7 @@ update flags settings msg model = case model.settings of Just s -> ( { model | message = Nothing } - , Ports.storeUiSettings flags s + , Api.saveClientSettings flags s SaveSettingsResp , Ports.onUiSettingsSaved SettingsSaved ) @@ -101,6 +104,12 @@ update flags settings msg model = , Sub.none ) + SaveSettingsResp (Ok res) -> + ( { model | message = Just res }, Cmd.none, Sub.none ) + + SaveSettingsResp (Err err) -> + ( model, Cmd.none, Sub.none ) + UpdateSettings -> let ( fm, fc ) = diff --git a/modules/webapp/src/main/elm/Data/UiSettings.elm b/modules/webapp/src/main/elm/Data/UiSettings.elm index 8e1e3cd0..71f1fc8b 100644 --- a/modules/webapp/src/main/elm/Data/UiSettings.elm +++ b/modules/webapp/src/main/elm/Data/UiSettings.elm @@ -15,6 +15,8 @@ module Data.UiSettings exposing , mergeDefaults , posFromString , posToString + , storedUiSettingsDecoder + , storedUiSettingsEncode , tagColor , tagColorFg2 , tagColorString2 @@ -30,6 +32,9 @@ import Data.UiTheme exposing (UiTheme) import Dict exposing (Dict) import Html exposing (Attribute) import Html.Attributes as HA +import Json.Decode as Decode +import Json.Decode.Pipeline as P +import Json.Encode as Encode import Messages import Messages.UiLanguage exposing (UiLanguage) @@ -67,6 +72,70 @@ type alias StoredUiSettings = } +storedUiSettingsDecoder : Decode.Decoder StoredUiSettings +storedUiSettingsDecoder = + let + maybeInt = + Decode.maybe Decode.int + + maybeString = + Decode.maybe Decode.string + in + Decode.succeed StoredUiSettings + |> P.optional "itemSearchPageSize" maybeInt Nothing + |> P.optional "tagCategoryColors" (Decode.keyValuePairs Decode.string) [] + |> P.optional "nativePdfPreview" Decode.bool False + |> P.optional "itemSearchNoteLength" maybeInt Nothing + |> P.optional "itemDetailNotesPosition" maybeString Nothing + |> P.optional "searchMenuFolderCount" maybeInt Nothing + |> P.optional "searchMenuTagCount" maybeInt Nothing + |> P.optional "searchMenuTagCatCount" maybeInt Nothing + |> P.optional "formFields" (Decode.maybe <| Decode.list Decode.string) Nothing + |> P.optional "itemDetailShortcuts" Decode.bool False + |> P.optional "searchMenuVisible" Decode.bool False + |> P.optional "editMenuVisible" Decode.bool False + |> P.optional "cardPreviewSize" maybeString Nothing + |> P.optional "cardTitleTemplate" maybeString Nothing + |> P.optional "cardSubtitleTemplate" maybeString Nothing + |> P.optional "searchStatsVisible" Decode.bool False + |> P.optional "cardPreviewFullWidth" Decode.bool False + |> P.optional "uiTheme" maybeString Nothing + |> P.optional "sideMenuVisible" Decode.bool False + |> P.optional "powerSearchEnabled" Decode.bool False + |> P.optional "uiLang" maybeString Nothing + + +storedUiSettingsEncode : StoredUiSettings -> Encode.Value +storedUiSettingsEncode value = + let + maybeEnc enca ma = + Maybe.map enca ma |> Maybe.withDefault Encode.null + in + Encode.object + [ ( "itemSearchPageSize", maybeEnc Encode.int value.itemSearchPageSize ) + , ( "tagCategoryColors", Encode.dict identity Encode.string (Dict.fromList value.tagCategoryColors) ) + , ( "nativePdfPreview", Encode.bool value.nativePdfPreview ) + , ( "itemSearchNoteLength", maybeEnc Encode.int value.itemSearchNoteLength ) + , ( "itemDetailNotesPosition", maybeEnc Encode.string value.itemDetailNotesPosition ) + , ( "searchMenuFolderCount", maybeEnc Encode.int value.searchMenuFolderCount ) + , ( "searchMenuTagCount", maybeEnc Encode.int value.searchMenuTagCount ) + , ( "searchMenuTagCatCount", maybeEnc Encode.int value.searchMenuTagCatCount ) + , ( "formFields", maybeEnc (Encode.list Encode.string) value.formFields ) + , ( "itemDetailShortcuts", Encode.bool value.itemDetailShortcuts ) + , ( "searchMenuVisible", Encode.bool value.searchMenuVisible ) + , ( "editMenuVisible", Encode.bool value.editMenuVisible ) + , ( "cardPreviewSize", maybeEnc Encode.string value.cardPreviewSize ) + , ( "cardTitleTemplate", maybeEnc Encode.string value.cardTitleTemplate ) + , ( "cardSubtitleTemplate", maybeEnc Encode.string value.cardSubtitleTemplate ) + , ( "searchStatsVisible", Encode.bool value.searchStatsVisible ) + , ( "cardPreviewFullWidth", Encode.bool value.cardPreviewFullWidth ) + , ( "uiTheme", maybeEnc Encode.string value.uiTheme ) + , ( "sideMenuVisible", Encode.bool value.sideMenuVisible ) + , ( "powerSearchEnabled", Encode.bool value.powerSearchEnabled ) + , ( "uiLang", maybeEnc Encode.string value.uiLang ) + ] + + {-| Settings for the web ui. These fields are all mandatory, since there is always a default value. diff --git a/modules/webapp/src/main/elm/Ports.elm b/modules/webapp/src/main/elm/Ports.elm index 9f630a81..4dd24fae 100644 --- a/modules/webapp/src/main/elm/Ports.elm +++ b/modules/webapp/src/main/elm/Ports.elm @@ -12,7 +12,6 @@ port module Ports exposing ) import Api.Model.AuthResult exposing (AuthResult) -import Api.Model.BasicResult exposing (BasicResult) import Data.Flags exposing (Flags) import Data.QueryParseResult exposing (QueryParseResult) import Data.UiSettings exposing (StoredUiSettings, UiSettings)