From c29ce73dd070bae144944950f76b7568474423b5 Mon Sep 17 00:00:00 2001 From: eikek Date: Sat, 29 Jan 2022 10:11:25 +0100 Subject: [PATCH] Client settings per collective and user Client settings can be stored at the user and and the collective. The settings used in the application are merged from these two settings, where any user setting takes precedence. The form can now manage both variants. Refs: #838 --- modules/webapp/src/main/elm/Api.elm | 97 ++++- modules/webapp/src/main/elm/App/Data.elm | 3 +- modules/webapp/src/main/elm/App/Update.elm | 55 ++- modules/webapp/src/main/elm/Comp/MenuBar.elm | 23 +- .../src/main/elm/Comp/UiSettingsForm.elm | 335 +++++++++++----- .../src/main/elm/Comp/UiSettingsManage.elm | 377 ++++++++++++------ .../src/main/elm/Comp/UiSettingsMigrate.elm | 6 +- .../webapp/src/main/elm/Data/AccountScope.elm | 5 + modules/webapp/src/main/elm/Data/AppEvent.elm | 13 + .../webapp/src/main/elm/Data/UiSettings.elm | 170 ++++---- modules/webapp/src/main/elm/Main.elm | 2 - .../elm/Messages/Comp/UiSettingsManage.elm | 16 + .../main/elm/Messages/Page/UserSettings.elm | 5 +- .../webapp/src/main/elm/Page/Search/Data.elm | 2 +- .../src/main/elm/Page/Search/Update.elm | 32 +- .../src/main/elm/Page/UserSettings/Data.elm | 6 +- .../src/main/elm/Page/UserSettings/Update.elm | 75 ++-- modules/webapp/src/main/elm/Ports.elm | 9 - modules/webapp/src/main/webjar/docspell.js | 19 - 19 files changed, 812 insertions(+), 438 deletions(-) create mode 100644 modules/webapp/src/main/elm/Data/AppEvent.elm diff --git a/modules/webapp/src/main/elm/Api.elm b/modules/webapp/src/main/elm/Api.elm index 5a5cff99..bb989e83 100644 --- a/modules/webapp/src/main/elm/Api.elm +++ b/modules/webapp/src/main/elm/Api.elm @@ -64,6 +64,7 @@ module Api exposing , getChannels , getChannelsIgnoreError , getClientSettings + , getClientSettingsRaw , getCollective , getCollectiveSettings , getContacts @@ -136,6 +137,7 @@ module Api exposing , restoreItem , sampleEvent , saveClientSettings + , saveUserClientSettingsBy , searchShare , searchShareStats , sendMail @@ -296,7 +298,7 @@ import Data.OrganizationOrder exposing (OrganizationOrder) import Data.PersonOrder exposing (PersonOrder) import Data.Priority exposing (Priority) import Data.TagOrder exposing (TagOrder) -import Data.UiSettings exposing (UiSettings) +import Data.UiSettings exposing (StoredUiSettings, UiSettings) import File exposing (File) import Http import Json.Decode as JsonDecode @@ -2335,6 +2337,13 @@ getItemProposals flags item receive = --- Client Settings +uiSettingsPath : AccountScope -> String +uiSettingsPath scope = + Data.AccountScope.fold "/api/v1/sec/clientSettings/user/webClient" + "/api/v1/sec/clientSettings/collective/webClient" + scope + + getClientSettings : Flags -> (Result Http.Error UiSettings -> msg) -> Cmd msg getClientSettings flags receive = let @@ -2346,29 +2355,91 @@ getClientSettings flags receive = Data.UiSettings.storedUiSettingsDecoder in Http2.authGet - { url = flags.config.baseUrl ++ "/api/v1/sec/clientSettings/user/webClient" + { 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 = +getClientSettingsTaskFor : Flags -> AccountScope -> Task.Task Http.Error StoredUiSettings +getClientSettingsTaskFor flags scope = let - storedSettings = - Data.UiSettings.toStoredUiSettings settings - - encode = - Data.UiSettings.storedUiSettingsEncode storedSettings + path = + uiSettingsPath scope in - Http2.authPut - { url = flags.config.baseUrl ++ "/api/v1/sec/clientSettings/user/webClient" + Http2.authTask + { method = "GET" + , url = flags.config.baseUrl ++ path , account = getAccount flags - , body = Http.jsonBody encode - , expect = Http.expectJson receive Api.Model.BasicResult.decoder + , body = Http.emptyBody + , resolver = Http2.jsonResolver Data.UiSettings.storedUiSettingsDecoder + , headers = [] + , timeout = Nothing } +getClientSettingsRaw : Flags -> (Result Http.Error ( StoredUiSettings, StoredUiSettings ) -> msg) -> Cmd msg +getClientSettingsRaw flags receive = + let + coll = + getClientSettingsTaskFor flags Data.AccountScope.Collective + + user = + getClientSettingsTaskFor flags Data.AccountScope.User + in + Task.map2 Tuple.pair coll user |> Task.attempt receive + + +saveClientSettingsTask : + Flags + -> StoredUiSettings + -> AccountScope + -> Task.Task Http.Error BasicResult +saveClientSettingsTask flags settings scope = + let + encoded = + Data.UiSettings.storedUiSettingsEncode settings + + path = + uiSettingsPath scope + in + Http2.authTask + { method = "PUT" + , url = flags.config.baseUrl ++ path + , account = getAccount flags + , body = Http.jsonBody encoded + , resolver = Http2.jsonResolver Api.Model.BasicResult.decoder + , headers = [] + , timeout = Nothing + } + + +saveClientSettings : + Flags + -> StoredUiSettings + -> AccountScope + -> (Result Http.Error BasicResult -> msg) + -> Cmd msg +saveClientSettings flags settings scope receive = + saveClientSettingsTask flags settings scope |> Task.attempt receive + + +saveUserClientSettingsBy : + Flags + -> (StoredUiSettings -> StoredUiSettings) + -> (Result Http.Error BasicResult -> msg) + -> Cmd msg +saveUserClientSettingsBy flags modify receive = + let + readTask = + getClientSettingsTaskFor flags Data.AccountScope.User + + save s = + saveClientSettingsTask flags s Data.AccountScope.User + in + Task.andThen (modify >> save) readTask |> Task.attempt receive + + --- Dashboards diff --git a/modules/webapp/src/main/elm/App/Data.elm b/modules/webapp/src/main/elm/App/Data.elm index 0facd89b..aef87620 100644 --- a/modules/webapp/src/main/elm/App/Data.elm +++ b/modules/webapp/src/main/elm/App/Data.elm @@ -204,8 +204,7 @@ type Msg | ToggleDarkMode | ToggleLangMenu | SetLanguage UiLanguage - | ClientSettingsSaveResp UiSettings (Result Http.Error BasicResult) - | ReceiveBrowserSettings StoredUiSettings + | ClientSettingsSaveResp (Result Http.Error BasicResult) | ReceiveWsMessage (Result String ServerEvent) | ToggleShowNewItemsArrived diff --git a/modules/webapp/src/main/elm/App/Update.elm b/modules/webapp/src/main/elm/App/Update.elm index 268e05cf..48e2621d 100644 --- a/modules/webapp/src/main/elm/App/Update.elm +++ b/modules/webapp/src/main/elm/App/Update.elm @@ -14,6 +14,7 @@ import Api import App.Data exposing (..) import Browser exposing (UrlRequest(..)) import Browser.Navigation as Nav +import Data.AppEvent exposing (AppEvent(..)) import Data.Flags import Data.ServerEvent exposing (ServerEvent(..)) import Data.UiSettings exposing (UiSettings) @@ -81,15 +82,15 @@ updateWithSub msg model = next = Data.UiTheme.cycle settings.uiTheme - newSettings = - { settings | uiTheme = next } + newSettings s = + { s | uiTheme = Just (Data.UiTheme.toString next) } in -- when authenticated, store it in settings only -- once new settings are successfully saved (the -- response is arrived), the ui is updated. so it -- is also updated on page refresh ( { model | userMenuOpen = False } - , Api.saveClientSettings model.flags newSettings (ClientSettingsSaveResp newSettings) + , Api.saveUserClientSettingsBy model.flags newSettings ClientSettingsSaveResp , Sub.none ) @@ -104,14 +105,14 @@ updateWithSub msg model = , Sub.none ) - ClientSettingsSaveResp settings (Ok res) -> + ClientSettingsSaveResp (Ok res) -> if res.success then - applyClientSettings texts model settings + ( model, Api.getClientSettings model.flags GetUiSettings, Sub.none ) else ( model, Cmd.none, Sub.none ) - ClientSettingsSaveResp _ (Err _) -> + ClientSettingsSaveResp (Err _) -> ( model, Cmd.none, Sub.none ) ToggleLangMenu -> @@ -307,13 +308,6 @@ updateWithSub msg model = GetUiSettings (Err _) -> ( model, Cmd.none, Sub.none ) - ReceiveBrowserSettings sett -> - let - lm = - Page.UserSettings.Data.ReceiveBrowserSettings sett - in - updateUserSettings texts lm model - ReceiveWsMessage data -> case data of Ok (JobDone task) -> @@ -342,7 +336,7 @@ updateWithSub msg model = Ok (JobsWaiting n) -> ( { model | jobsWaiting = max 0 n }, Cmd.none, Sub.none ) - Err err -> + Err _ -> ( model, Cmd.none, Sub.none ) ToggleShowNewItemsArrived -> @@ -368,7 +362,6 @@ applyClientSettings texts model settings = , Sub.none ) , updateDashboard texts Page.Dashboard.Data.reloadUiSettings - , updateUserSettings texts Page.UserSettings.Data.UpdateSettings , updateSearch texts Page.Search.Data.UiSettingsUpdated , updateItemDetail texts Page.ItemDetail.Data.UiSettingsUpdated ] @@ -524,22 +517,21 @@ updateUserSettings texts lmsg model = model_ = { model | userSettingsModel = result.model } - ( lm2, lc2, s2 ) = - case result.newSettings of - Just sett -> - applyClientSettings texts model_ sett + lc = + case result.appEvent of + AppReloadUiSettings -> + Api.getClientSettings model.flags GetUiSettings - Nothing -> - ( model_, Cmd.none, Sub.none ) + AppNothing -> + Cmd.none in - ( lm2 + ( model_ , Cmd.batch [ Cmd.map UserSettingsMsg result.cmd - , lc2 + , lc ] , Sub.batch [ Sub.map UserSettingsMsg result.sub - , s2 ] ) @@ -595,22 +587,21 @@ updateSearch texts lmsg model = model_ = { model | searchModel = result.model } - ( lm, lc, ls ) = - case result.newSettings of - Just sett -> - applyClientSettings texts model_ sett + lc = + case result.appEvent of + AppReloadUiSettings -> + Api.getClientSettings model.flags GetUiSettings - Nothing -> - ( model_, Cmd.none, Sub.none ) + AppNothing -> + Cmd.none in - ( lm + ( model_ , Cmd.batch [ Cmd.map SearchMsg result.cmd , lc ] , Sub.batch [ Sub.map SearchMsg result.sub - , ls ] ) diff --git a/modules/webapp/src/main/elm/Comp/MenuBar.elm b/modules/webapp/src/main/elm/Comp/MenuBar.elm index b5819ae2..825b9bcd 100644 --- a/modules/webapp/src/main/elm/Comp/MenuBar.elm +++ b/modules/webapp/src/main/elm/Comp/MenuBar.elm @@ -26,6 +26,7 @@ import Styles as S type Item msg = TextInput (TextInputData msg) | Checkbox (CheckboxData msg) + | RadioButton (CheckboxData msg) | PrimaryButton (ButtonData msg) | SecondaryButton (ButtonData msg) | DeleteButton (ButtonData msg) @@ -119,7 +120,7 @@ view1 classes mb = (List.map viewItem mb.start) right = - div [ class "flex-grow flex-row flex justify-end space-x-2 w-full" ] + div [ class "flex-grow flex-row items-center flex justify-end space-x-2 w-full" ] (List.map viewItem mb.end) in div @@ -139,7 +140,10 @@ viewItem item = makeInput model Checkbox model -> - makeCheckbox model + makeCheckbox False model + + RadioButton model -> + makeCheckbox True model PrimaryButton model -> makeButton [ ( S.primaryButton, True ) ] model @@ -306,8 +310,8 @@ makeButton btnType model = (icon ++ label) -makeCheckbox : CheckboxData msg -> Html msg -makeCheckbox model = +makeCheckbox : Bool -> CheckboxData msg -> Html msg +makeCheckbox radio model = let withId list = if model.id == "" then @@ -315,6 +319,13 @@ makeCheckbox model = else id model.id :: list + + fold rd ck = + if radio then + rd + + else + ck in div [ class "" ] [ label @@ -323,10 +334,10 @@ makeCheckbox model = ] [ input (withId - [ type_ "checkbox" + [ type_ (fold "radio" "checkbox") , onCheck model.tagger , checked model.value - , class S.checkboxInput + , class (fold S.radioInput S.checkboxInput) ] ) [] diff --git a/modules/webapp/src/main/elm/Comp/UiSettingsForm.elm b/modules/webapp/src/main/elm/Comp/UiSettingsForm.elm index ecfb6781..16eb1851 100644 --- a/modules/webapp/src/main/elm/Comp/UiSettingsForm.elm +++ b/modules/webapp/src/main/elm/Comp/UiSettingsForm.elm @@ -9,6 +9,7 @@ module Comp.UiSettingsForm exposing ( Model , Msg , init + , toggleAllTabs , update , view2 ) @@ -30,7 +31,7 @@ import Data.Flags exposing (Flags) import Data.ItemTemplate as IT exposing (ItemTemplate) import Data.Pdf exposing (PdfMode) import Data.TagOrder -import Data.UiSettings exposing (ItemPattern, Pos(..), UiSettings) +import Data.UiSettings exposing (ItemPattern, Pos(..), StoredUiSettings, UiSettings) import Dict exposing (Dict) import Html exposing (..) import Html.Attributes exposing (..) @@ -73,6 +74,7 @@ type alias Model = , uiLangModel : Comp.FixedDropdown.Model UiLanguage , uiLang : UiLanguage , openTabs : Set String + , defaults : UiSettings } @@ -111,61 +113,69 @@ updatePatternModel pm str = } -init : Flags -> UiSettings -> ( Model, Cmd Msg ) -init flags settings = - ( { itemSearchPageSize = Just settings.itemSearchPageSize - , searchPageSizeModel = - Comp.IntField.init - (Just 10) - (Just flags.config.maxPageSize) - False - , tagColors = settings.tagCategoryColors - , tagColorModel = - Comp.ColorTagger.init - [] - Data.Color.all - , pdfMode = settings.pdfMode - , pdfModeModel = Comp.FixedDropdown.init Data.Pdf.allModes - , itemSearchNoteLength = Just settings.itemSearchNoteLength - , searchNoteLengthModel = - Comp.IntField.init - (Just 0) - (Just flags.config.maxNoteLength) - False - , searchMenuFolderCount = Just settings.searchMenuFolderCount - , searchMenuFolderCountModel = - Comp.IntField.init - (Just 0) - (Just 2000) - False - , searchMenuTagCount = Just settings.searchMenuTagCount - , searchMenuTagCountModel = - Comp.IntField.init - (Just 0) - (Just 2000) - False - , searchMenuTagCatCount = Just settings.searchMenuTagCatCount - , searchMenuTagCatCountModel = - Comp.IntField.init - (Just 0) - (Just 2000) - False - , formFields = settings.formFields - , itemDetailShortcuts = settings.itemDetailShortcuts - , cardPreviewSize = settings.cardPreviewSize - , cardTitlePattern = initPatternModel settings.cardTitleTemplate - , cardSubtitlePattern = initPatternModel settings.cardSubtitleTemplate - , showPatternHelp = False - , searchStatsVisible = settings.searchStatsVisible - , sideMenuVisible = settings.sideMenuVisible - , powerSearchEnabled = settings.powerSearchEnabled - , uiLang = settings.uiLang - , uiLangModel = - Comp.FixedDropdown.init Messages.UiLanguage.all - , openTabs = Set.empty - } - , Api.getTags flags "" Data.TagOrder.NameAsc GetTagsResp - ) +initModel : Flags -> StoredUiSettings -> UiSettings -> Model +initModel flags storedSettings defaults = + let + settings = + Data.UiSettings.merge storedSettings defaults + in + { itemSearchPageSize = Just settings.itemSearchPageSize + , searchPageSizeModel = + Comp.IntField.init + (Just 10) + (Just flags.config.maxPageSize) + False + , tagColors = settings.tagCategoryColors + , tagColorModel = + Comp.ColorTagger.init + [] + Data.Color.all + , pdfMode = settings.pdfMode + , pdfModeModel = Comp.FixedDropdown.init Data.Pdf.allModes + , itemSearchNoteLength = Just settings.itemSearchNoteLength + , searchNoteLengthModel = + Comp.IntField.init + (Just 0) + (Just flags.config.maxNoteLength) + False + , searchMenuFolderCount = Just settings.searchMenuFolderCount + , searchMenuFolderCountModel = + Comp.IntField.init + (Just 0) + (Just 2000) + False + , searchMenuTagCount = Just settings.searchMenuTagCount + , searchMenuTagCountModel = + Comp.IntField.init + (Just 0) + (Just 2000) + False + , searchMenuTagCatCount = Just settings.searchMenuTagCatCount + , searchMenuTagCatCountModel = + Comp.IntField.init + (Just 0) + (Just 2000) + False + , formFields = settings.formFields + , itemDetailShortcuts = settings.itemDetailShortcuts + , cardPreviewSize = settings.cardPreviewSize + , cardTitlePattern = initPatternModel settings.cardTitleTemplate + , cardSubtitlePattern = initPatternModel settings.cardSubtitleTemplate + , showPatternHelp = False + , searchStatsVisible = settings.searchStatsVisible + , sideMenuVisible = settings.sideMenuVisible + , powerSearchEnabled = settings.powerSearchEnabled + , uiLang = settings.uiLang + , uiLangModel = + Comp.FixedDropdown.init Messages.UiLanguage.all + , openTabs = Set.empty + , defaults = defaults + } + + +init : Flags -> StoredUiSettings -> UiSettings -> ( Model, Cmd Msg ) +init flags storedSettings defaults = + ( initModel flags storedSettings defaults, Api.getTags flags "" Data.TagOrder.NameAsc GetTagsResp ) type Msg @@ -188,14 +198,61 @@ type Msg | TogglePowerSearch | UiLangMsg (Comp.FixedDropdown.Msg UiLanguage) | PdfModeMsg (Comp.FixedDropdown.Msg PdfMode) + | ToggleAllTabs + | ResetTab AkkordionTab + + +toggleAllTabs : Msg +toggleAllTabs = + ToggleAllTabs + + +type AkkordionTab + = GeneralTab + | SearchTab + | CardsTab + | SearchMenuTab + | DetailTab + | TagsTab + | FieldsTab + + +allTabs : List AkkordionTab +allTabs = + [ GeneralTab, SearchTab, CardsTab, SearchMenuTab, DetailTab, TagsTab, FieldsTab ] + + +akkordionTabName : AkkordionTab -> String +akkordionTabName tab = + case tab of + GeneralTab -> + "general" + + SearchTab -> + "search" + + CardsTab -> + "item-cards" + + SearchMenuTab -> + "search-menu" + + DetailTab -> + "item-detail" + + TagsTab -> + "tags" + + FieldsTab -> + "fields" --- Update -update : UiSettings -> Msg -> Model -> ( Model, Maybe UiSettings ) -update sett msg model = +update : Flags -> StoredUiSettings -> Msg -> Model -> ( Model, Maybe StoredUiSettings ) +update flags sett msg model = case msg of SearchPageSizeMsg lm -> let @@ -203,7 +260,7 @@ update sett msg model = Comp.IntField.update lm model.searchPageSizeModel nextSettings = - Maybe.map (\sz -> { sett | itemSearchPageSize = sz }) n + Maybe.map (\sz -> { sett | itemSearchPageSize = Just sz }) n model_ = { model @@ -219,7 +276,7 @@ update sett msg model = Comp.IntField.update lm model.searchNoteLengthModel nextSettings = - Maybe.map (\len -> { sett | itemSearchNoteLength = len }) n + Maybe.map (\len -> { sett | itemSearchNoteLength = Just len }) n model_ = { model @@ -235,7 +292,7 @@ update sett msg model = Comp.IntField.update lm model.searchMenuFolderCountModel nextSettings = - Maybe.map (\len -> { sett | searchMenuFolderCount = len }) n + Maybe.map (\len -> { sett | searchMenuFolderCount = Just len }) n model_ = { model @@ -251,7 +308,7 @@ update sett msg model = Comp.IntField.update lm model.searchMenuTagCountModel nextSettings = - Maybe.map (\len -> { sett | searchMenuTagCount = len }) n + Maybe.map (\len -> { sett | searchMenuTagCount = Just len }) n model_ = { model @@ -267,7 +324,7 @@ update sett msg model = Comp.IntField.update lm model.searchMenuTagCatCountModel nextSettings = - Maybe.map (\len -> { sett | searchMenuTagCatCount = len }) n + Maybe.map (\len -> { sett | searchMenuTagCatCount = Just len }) n model_ = { model @@ -282,8 +339,13 @@ update sett msg model = ( m_, d_ ) = Comp.ColorTagger.update lm model.tagColorModel + colors dict = + Dict.map (\_ -> Data.Color.toString) dict + |> Dict.toList + |> Just + nextSettings = - Maybe.map (\tc -> { sett | tagCategoryColors = tc }) d_ + Maybe.map (\tc -> { sett | tagCategoryColors = colors tc }) d_ model_ = { model @@ -316,7 +378,11 @@ update sett msg model = Comp.FieldListSelect.update lm model.formFields newSettings = - { sett | formFields = selected } + { sett + | formFields = + List.map Data.Fields.toString selected + |> Just + } in ( { model | formFields = selected } , if selected /= model.formFields then @@ -332,7 +398,7 @@ update sett msg model = not model.itemDetailShortcuts in ( { model | itemDetailShortcuts = flag } - , Just { sett | itemDetailShortcuts = flag } + , Just { sett | itemDetailShortcuts = Just flag } ) CardPreviewSizeMsg lm -> @@ -343,7 +409,13 @@ update sett msg model = newSettings = if next /= model.cardPreviewSize then - Just { sett | cardPreviewSize = next } + Just + { sett + | cardPreviewSize = + next + |> Data.BasicSize.asString + |> Just + } else Nothing @@ -361,14 +433,8 @@ update sett msg model = updatePatternModel pm str newSettings = - if pm_.pattern /= Just sett.cardTitleTemplate.pattern then - Just - { sett - | cardTitleTemplate = - ItemPattern - (Maybe.withDefault "" pm_.pattern) - pm_.current - } + if pm_.pattern /= sett.cardTitleTemplate then + Just { sett | cardTitleTemplate = pm_.pattern } else Nothing @@ -384,14 +450,8 @@ update sett msg model = updatePatternModel pm str newSettings = - if pm_.pattern /= Just sett.cardSubtitleTemplate.pattern then - Just - { sett - | cardSubtitleTemplate = - ItemPattern - (Maybe.withDefault "" pm_.pattern) - pm_.current - } + if pm_.pattern /= sett.cardSubtitleTemplate then + Just { sett | cardSubtitleTemplate = pm_.pattern } else Nothing @@ -407,9 +467,21 @@ update sett msg model = not model.searchStatsVisible in ( { model | searchStatsVisible = flag } - , Just { sett | searchStatsVisible = flag } + , Just { sett | searchStatsVisible = Just flag } ) + ToggleAllTabs -> + let + tabs = + if Set.isEmpty model.openTabs then + List.map akkordionTabName allTabs + |> Set.fromList + + else + Set.empty + in + ( { model | openTabs = tabs }, Nothing ) + ToggleAkkordionTab name -> let tabs = @@ -429,7 +501,7 @@ update sett msg model = not model.sideMenuVisible in ( { model | sideMenuVisible = next } - , Just { sett | sideMenuVisible = next } + , Just { sett | sideMenuVisible = Just next } ) TogglePowerSearch -> @@ -438,7 +510,7 @@ update sett msg model = not model.powerSearchEnabled in ( { model | powerSearchEnabled = next } - , Just { sett | powerSearchEnabled = next } + , Just { sett | powerSearchEnabled = Just next } ) UiLangMsg lm -> @@ -454,7 +526,7 @@ update sett msg model = Nothing else - Just { sett | uiLang = newLang } + Just { sett | uiLang = Just (Messages.toIso2 newLang) } ) PdfModeMsg lm -> @@ -470,9 +542,53 @@ update sett msg model = Nothing else - Just { sett | pdfMode = newMode } + Just { sett | pdfMode = Just (Data.Pdf.asString newMode) } ) + ResetTab tab -> + let + newSettings = + case tab of + GeneralTab -> + { sett | uiLang = Nothing, sideMenuVisible = Nothing } + + SearchTab -> + { sett + | itemSearchPageSize = Nothing + , searchStatsVisible = Nothing + , powerSearchEnabled = Nothing + } + + CardsTab -> + { sett + | itemSearchNoteLength = Nothing + , cardPreviewSize = Nothing + , cardTitleTemplate = Nothing + , cardSubtitleTemplate = Nothing + } + + SearchMenuTab -> + { sett + | searchMenuTagCount = Nothing + , searchMenuTagCatCount = Nothing + , searchMenuFolderCount = Nothing + } + + DetailTab -> + { sett | pdfMode = Nothing, itemDetailShortcuts = Nothing } + + TagsTab -> + { sett | tagCategoryColors = Nothing } + + -- no reset here + FieldsTab -> + { sett | formFields = Nothing } + + nm = + initModel flags newSettings model.defaults + in + ( { nm | openTabs = model.openTabs }, Just newSettings ) + --- View2 @@ -495,7 +611,7 @@ tagColorViewOpts2 texts = } -view2 : Texts -> Flags -> UiSettings -> Model -> Html Msg +view2 : Texts -> Flags -> StoredUiSettings -> Model -> Html Msg view2 texts flags settings model = let state tab = @@ -517,7 +633,7 @@ view2 texts flags settings model = ] -settingFormTabs : Texts -> Flags -> UiSettings -> Model -> List (Comp.Tabs.Tab Msg) +settingFormTabs : Texts -> Flags -> StoredUiSettings -> Model -> List (Comp.Tabs.Tab Msg) settingFormTabs texts flags _ model = let langCfg = @@ -533,10 +649,21 @@ settingFormTabs texts flags _ model = , style = DS.mainStyle , selectPlaceholder = texts.basics.selectPlaceholder } + + resetLink tab = + a + [ href "#" + , class S.link + , class "text-sm" + , onClick (ResetTab tab) + ] + [ i [ class "fa fa-eraser mr-1" ] [] + , text "Reset" + ] in - [ { name = "general" + [ { name = akkordionTabName GeneralTab , title = texts.general - , titleRight = [] + , titleRight = [ resetLink GeneralTab ] , info = Nothing , body = [ div [ class "mb-4 " ] @@ -560,9 +687,9 @@ settingFormTabs texts flags _ model = ] ] } - , { name = "item-search" + , { name = akkordionTabName SearchTab , title = texts.itemSearch - , titleRight = [] + , titleRight = [ resetLink SearchTab ] , info = Nothing , body = [ Html.map SearchPageSizeMsg @@ -594,9 +721,9 @@ settingFormTabs texts flags _ model = ] ] } - , { name = "item-cards" + , { name = akkordionTabName CardsTab , title = texts.itemCards - , titleRight = [] + , titleRight = [ resetLink CardsTab ] , info = Nothing , body = [ Html.map NoteLengthMsg @@ -666,9 +793,9 @@ settingFormTabs texts flags _ model = texts.templateHelpMessage ] } - , { name = "search-menu" + , { name = akkordionTabName SearchMenuTab , title = texts.searchMenu - , titleRight = [] + , titleRight = [ resetLink SearchMenuTab ] , info = Nothing , body = [ Html.map SearchMenuTagMsg @@ -700,9 +827,9 @@ settingFormTabs texts flags _ model = ) ] } - , { name = "item-detail" + , { name = akkordionTabName DetailTab , title = texts.itemDetail - , titleRight = [] + , titleRight = [ resetLink DetailTab ] , info = Nothing , body = [ div [ class "mb-4" ] @@ -726,9 +853,9 @@ settingFormTabs texts flags _ model = ] ] } - , { name = "tag-category-colors" + , { name = akkordionTabName TagsTab , title = texts.tagCategoryColors - , titleRight = [] + , titleRight = [ resetLink TagsTab ] , info = Nothing , body = [ Html.map TagColorMsg @@ -739,9 +866,9 @@ settingFormTabs texts flags _ model = ) ] } - , { name = "fields" + , { name = akkordionTabName FieldsTab , title = texts.fields - , titleRight = [] + , titleRight = [ resetLink FieldsTab ] , info = Nothing , body = [ span [ class "opacity-50 text-sm" ] diff --git a/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm b/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm index c1a96ecc..9bd02222 100644 --- a/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm +++ b/modules/webapp/src/main/elm/Comp/UiSettingsManage.elm @@ -16,26 +16,42 @@ module Comp.UiSettingsManage exposing import Api import Api.Model.BasicResult exposing (BasicResult) +import Comp.Basic import Comp.MenuBar as MB import Comp.UiSettingsForm -import Comp.UiSettingsMigrate +import Data.AccountScope exposing (AccountScope) +import Data.AppEvent exposing (AppEvent(..)) import Data.Flags exposing (Flags) import Data.UiSettings exposing (StoredUiSettings, UiSettings) import Html exposing (..) import Html.Attributes exposing (..) import Http import Messages.Comp.UiSettingsManage exposing (Texts) +import Page.Search.Data exposing (Msg(..)) import Styles as S type alias Model = - { formModel : Comp.UiSettingsForm.Model - , settings : Maybe UiSettings + { formModel : FormView , formResult : FormResult - , settingsMigrate : Comp.UiSettingsMigrate.Model + , formData : Maybe FormData } +type alias FormData = + { userSettings : StoredUiSettings + , userModel : Comp.UiSettingsForm.Model + , collSettings : StoredUiSettings + , collModel : Comp.UiSettingsForm.Model + } + + +type FormView + = ViewLoading + | ViewUser + | ViewCollective + + type FormResult = FormInit | FormUnchanged @@ -45,35 +61,39 @@ type FormResult type Msg - = UiSettingsFormMsg Comp.UiSettingsForm.Msg - | UiSettingsMigrateMsg Comp.UiSettingsMigrate.Msg + = UiFormMsg AccountScope Comp.UiSettingsForm.Msg | Submit - | UpdateSettings - | SaveSettingsResp UiSettings (Result Http.Error BasicResult) - | ReceiveBrowserSettings StoredUiSettings + | SaveSettingsResp (Result Http.Error BasicResult) + | ReceiveServerSettings (Result Http.Error ( StoredUiSettings, StoredUiSettings )) + | ToggleExpandCollapse + | SwitchForm AccountScope -init : Flags -> UiSettings -> ( Model, Cmd Msg ) -init flags settings = - let - ( fm, fc ) = - Comp.UiSettingsForm.init flags settings - - ( mm, mc ) = - Comp.UiSettingsMigrate.init flags - in - ( { formModel = fm - , settings = Nothing +init : Flags -> ( Model, Cmd Msg ) +init flags = + ( { formModel = ViewLoading + , formData = Nothing , formResult = FormInit - , settingsMigrate = mm } , Cmd.batch - [ Cmd.map UiSettingsFormMsg fc - , Cmd.map UiSettingsMigrateMsg mc + [ Api.getClientSettingsRaw flags ReceiveServerSettings ] ) +getViewScope : Model -> AccountScope +getViewScope model = + case model.formModel of + ViewCollective -> + Data.AccountScope.Collective + + ViewUser -> + Data.AccountScope.User + + _ -> + Data.AccountScope.User + + --- update @@ -82,108 +102,165 @@ type alias UpdateResult = { model : Model , cmd : Cmd Msg , sub : Sub Msg - , newSettings : Maybe UiSettings + , appEvent : AppEvent } +unit : Model -> UpdateResult +unit model = + UpdateResult model Cmd.none Sub.none AppNothing + + update : Flags -> UiSettings -> Msg -> Model -> UpdateResult update flags settings msg model = case msg of - UiSettingsFormMsg lm -> + UiFormMsg scope lm -> + case model.formData of + Nothing -> + unit model + + Just data -> + case scope of + Data.AccountScope.Collective -> + let + ( m_, sett ) = + Comp.UiSettingsForm.update flags data.collSettings lm data.collModel + in + unit + { model + | formData = + Just + { data + | collSettings = Maybe.withDefault data.collSettings sett + , collModel = m_ + } + , formResult = + if sett /= Nothing then + FormInit + + else + model.formResult + } + + Data.AccountScope.User -> + let + ( m_, sett ) = + Comp.UiSettingsForm.update flags data.userSettings lm data.userModel + in + unit + { model + | formData = + Just + { data + | userSettings = Maybe.withDefault data.userSettings sett + , userModel = m_ + } + , formResult = + if sett /= Nothing then + FormInit + + else + model.formResult + } + + Submit -> + case ( model.formModel, model.formData ) of + ( ViewCollective, Just data ) -> + { model = { model | formResult = FormInit } + , cmd = + Api.saveClientSettings flags + data.collSettings + Data.AccountScope.Collective + SaveSettingsResp + , sub = Sub.none + , appEvent = AppNothing + } + + ( ViewUser, Just data ) -> + { model = { model | formResult = FormInit } + , cmd = + Api.saveClientSettings flags + data.userSettings + Data.AccountScope.User + SaveSettingsResp + , sub = Sub.none + , appEvent = AppNothing + } + + _ -> + unit model + + SaveSettingsResp (Ok res) -> + case ( res.success, model.formData ) of + ( True, Just data ) -> + let + result = + update flags + settings + (ReceiveServerSettings (Ok ( data.collSettings, data.userSettings ))) + model + in + { result | appEvent = AppReloadUiSettings } + + _ -> + unit { model | formResult = FormUnknownError } + + SaveSettingsResp (Err err) -> + UpdateResult { model | formResult = FormHttpError err } Cmd.none Sub.none AppNothing + + ReceiveServerSettings (Ok ( coll, user )) -> let - inSettings = - Maybe.withDefault settings model.settings + collDefaults = + Data.UiSettings.defaults - ( m_, sett ) = - Comp.UiSettingsForm.update inSettings lm model.formModel + userDefaults = + Data.UiSettings.merge coll collDefaults + + ( um, uc ) = + Comp.UiSettingsForm.init flags user userDefaults + + ( cm, cc ) = + Comp.UiSettingsForm.init flags coll collDefaults + + model_ = + { model + | formData = + Just + { userSettings = user + , userModel = um + , collSettings = coll + , collModel = cm + } + , formModel = ViewUser + } + + cmds = + Cmd.batch + [ Cmd.map (UiFormMsg Data.AccountScope.User) uc + , Cmd.map (UiFormMsg Data.AccountScope.Collective) cc + ] in - { model = - { model - | formModel = m_ - , settings = - if sett == Nothing then - model.settings + UpdateResult model_ cmds Sub.none AppNothing - else - sett - , formResult = - if sett /= Nothing then - FormInit + ReceiveServerSettings (Err err) -> + unit { model | formResult = FormHttpError err } - else - model.formResult - } - , cmd = Cmd.none - , sub = Sub.none - , newSettings = Nothing - } - - UiSettingsMigrateMsg lm -> - let - result = - Comp.UiSettingsMigrate.update flags lm model.settingsMigrate - in - { model = { model | settingsMigrate = result.model } - , cmd = Cmd.map UiSettingsMigrateMsg result.cmd - , sub = Sub.map UiSettingsMigrateMsg result.sub - , newSettings = result.newSettings - } - - ReceiveBrowserSettings sett -> + ToggleExpandCollapse -> let lm = - UiSettingsMigrateMsg (Comp.UiSettingsMigrate.receiveBrowserSettings sett) + UiFormMsg (getViewScope model) Comp.UiSettingsForm.toggleAllTabs in update flags settings lm model - Submit -> - case model.settings of - Just s -> - { model = { model | formResult = FormInit } - , cmd = Api.saveClientSettings flags s (SaveSettingsResp s) - , sub = Sub.none - , newSettings = Nothing - } - - Nothing -> - { model = { model | formResult = FormUnchanged } - , cmd = Cmd.none - , sub = Sub.none - , newSettings = Nothing - } - - SaveSettingsResp newSettings (Ok res) -> - if res.success then - { model = { model | formResult = FormSaved } - , cmd = Cmd.none - , sub = Sub.none - , newSettings = Just newSettings - } - - else - { model = { model | formResult = FormUnknownError } - , cmd = Cmd.none - , sub = Sub.none - , newSettings = Nothing - } - - SaveSettingsResp _ (Err err) -> - UpdateResult { model | formResult = FormHttpError err } Cmd.none Sub.none Nothing - - UpdateSettings -> + SwitchForm scope -> let - ( fm, fc ) = - Comp.UiSettingsForm.init flags settings + forUser = + unit { model | formModel = ViewUser } + + forColl = + unit { model | formModel = ViewCollective } in - { model = { model | formModel = fm } - , cmd = Cmd.map UiSettingsFormMsg fc - , sub = Sub.none - , newSettings = Nothing - } - - - ---- View2 + Data.AccountScope.fold forUser forColl scope isError : Model -> Bool @@ -211,7 +288,11 @@ isSuccess model = view2 : Texts -> Flags -> UiSettings -> String -> Model -> Html Msg -view2 texts flags settings classes model = +view2 texts flags _ classes model = + let + scope = + getViewScope model + in div [ class classes ] [ MB.view { start = @@ -221,14 +302,29 @@ view2 texts flags settings classes model = , title = texts.saveSettings , icon = Just "fa fa-save" } + , MB.SecondaryButton + { tagger = ToggleExpandCollapse + , label = "" + , title = texts.expandCollapse + , icon = Just "fa fa-compress" + } + ] + , end = + [ MB.RadioButton + { tagger = \_ -> SwitchForm Data.AccountScope.User + , label = texts.accountScope Data.AccountScope.User + , value = Data.AccountScope.fold True False scope + , id = "ui-settings-chooser-user" + } + , MB.RadioButton + { tagger = \_ -> SwitchForm Data.AccountScope.Collective + , label = texts.accountScope Data.AccountScope.Collective + , value = Data.AccountScope.fold False True scope + , id = "ui-settings-chooser-collective" + } ] - , end = [] , rootClasses = "mb-4" } - , div [] - [ Html.map UiSettingsMigrateMsg - (Comp.UiSettingsMigrate.view model.settingsMigrate) - ] , div [ classList [ ( S.successMessage, isSuccess model ) @@ -252,11 +348,52 @@ view2 texts flags settings classes model = FormUnknownError -> text texts.unknownSaveError ] - , Html.map UiSettingsFormMsg - (Comp.UiSettingsForm.view2 - texts.uiSettingsForm - flags - settings - model.formModel - ) + , case model.formModel of + ViewLoading -> + div [ class "h-24 md:relative" ] + [ Comp.Basic.loadingDimmer + { label = "" + , active = True + } + ] + + ViewCollective -> + case model.formData of + Just data -> + div [] + [ h2 [ class S.header2 ] + [ text texts.collectiveHeader + ] + , Html.map (UiFormMsg scope) + (Comp.UiSettingsForm.view2 + texts.uiSettingsForm + flags + data.collSettings + data.collModel + ) + ] + + Nothing -> + span [ class "hidden" ] [] + + ViewUser -> + case model.formData of + Just data -> + div [] + [ h2 [ class S.header2 ] + [ text texts.userHeader + ] + , div [ class "py-1 opacity-80" ] + [ text texts.userInfo + ] + , Html.map (UiFormMsg scope) + (Comp.UiSettingsForm.view2 texts.uiSettingsForm + flags + data.userSettings + data.userModel + ) + ] + + Nothing -> + span [ class "hidden" ] [] ] diff --git a/modules/webapp/src/main/elm/Comp/UiSettingsMigrate.elm b/modules/webapp/src/main/elm/Comp/UiSettingsMigrate.elm index a5b39ad3..d1aeed8e 100644 --- a/modules/webapp/src/main/elm/Comp/UiSettingsMigrate.elm +++ b/modules/webapp/src/main/elm/Comp/UiSettingsMigrate.elm @@ -17,6 +17,7 @@ module Comp.UiSettingsMigrate exposing import Api import Api.Model.BasicResult exposing (BasicResult) +import Data.AccountScope import Data.Flags exposing (Flags) import Data.UiSettings exposing (StoredUiSettings, UiSettings) import Html exposing (..) @@ -132,7 +133,10 @@ update flags msg model = Data.UiSettings.merge settings Data.UiSettings.defaults cmd = - Api.saveClientSettings flags uiSettings (SaveSettingsResp uiSettings) + Api.saveClientSettings flags + (Data.UiSettings.convert uiSettings) + Data.AccountScope.Collective + (SaveSettingsResp uiSettings) in { empty | model = MigrateRequestRunning, cmd = cmd } diff --git a/modules/webapp/src/main/elm/Data/AccountScope.elm b/modules/webapp/src/main/elm/Data/AccountScope.elm index 1fe287ec..07772f38 100644 --- a/modules/webapp/src/main/elm/Data/AccountScope.elm +++ b/modules/webapp/src/main/elm/Data/AccountScope.elm @@ -23,6 +23,11 @@ fold user coll scope = coll +all : List AccountScope +all = + [ Collective, User ] + + isUser : AccountScope -> Bool isUser scope = fold True False scope diff --git a/modules/webapp/src/main/elm/Data/AppEvent.elm b/modules/webapp/src/main/elm/Data/AppEvent.elm new file mode 100644 index 00000000..c15e912f --- /dev/null +++ b/modules/webapp/src/main/elm/Data/AppEvent.elm @@ -0,0 +1,13 @@ +{- + Copyright 2020 Eike K. & Contributors + + SPDX-License-Identifier: AGPL-3.0-or-later +-} + + +module Data.AppEvent exposing (AppEvent(..)) + + +type AppEvent + = AppNothing + | AppReloadUiSettings diff --git a/modules/webapp/src/main/elm/Data/UiSettings.elm b/modules/webapp/src/main/elm/Data/UiSettings.elm index 30a6c129..43f27216 100644 --- a/modules/webapp/src/main/elm/Data/UiSettings.elm +++ b/modules/webapp/src/main/elm/Data/UiSettings.elm @@ -15,8 +15,10 @@ module Data.UiSettings exposing , catColor , catColorFg2 , catColorString2 + , convert , defaults , documentationSite + , emptyStoredSettings , fieldHidden , fieldVisible , getUiLanguage @@ -30,7 +32,6 @@ module Data.UiSettings exposing , tagColor , tagColorFg2 , tagColorString2 - , toStoredUiSettings ) import Api.Model.Tag exposing (Tag) @@ -62,7 +63,7 @@ force default settings. -} type alias StoredUiSettings = { itemSearchPageSize : Maybe Int - , tagCategoryColors : List ( String, String ) + , tagCategoryColors : Maybe (List ( String, String )) , pdfMode : Maybe String , itemSearchNoteLength : Maybe Int , itemDetailNotesPosition : Maybe String @@ -70,23 +71,51 @@ type alias StoredUiSettings = , searchMenuTagCount : Maybe Int , searchMenuTagCatCount : Maybe Int , formFields : Maybe (List String) - , itemDetailShortcuts : Bool - , searchMenuVisible : Bool - , editMenuVisible : Bool + , itemDetailShortcuts : Maybe Bool + , searchMenuVisible : Maybe Bool + , editMenuVisible : Maybe Bool , cardPreviewSize : Maybe String , cardTitleTemplate : Maybe String , cardSubtitleTemplate : Maybe String - , searchStatsVisible : Bool - , cardPreviewFullWidth : Bool + , searchStatsVisible : Maybe Bool + , cardPreviewFullWidth : Maybe Bool , uiTheme : Maybe String - , sideMenuVisible : Bool - , powerSearchEnabled : Bool + , sideMenuVisible : Maybe Bool + , powerSearchEnabled : Maybe Bool , uiLang : Maybe String - , itemSearchShowGroups : Bool + , itemSearchShowGroups : Maybe Bool , itemSearchArrange : Maybe String } +emptyStoredSettings : StoredUiSettings +emptyStoredSettings = + { itemSearchPageSize = Nothing + , tagCategoryColors = Nothing + , pdfMode = Nothing + , itemSearchNoteLength = Nothing + , itemDetailNotesPosition = Nothing + , searchMenuFolderCount = Nothing + , searchMenuTagCount = Nothing + , searchMenuTagCatCount = Nothing + , formFields = Nothing + , itemDetailShortcuts = Nothing + , searchMenuVisible = Nothing + , editMenuVisible = Nothing + , cardPreviewSize = Nothing + , cardTitleTemplate = Nothing + , cardSubtitleTemplate = Nothing + , searchStatsVisible = Nothing + , cardPreviewFullWidth = Nothing + , uiTheme = Nothing + , sideMenuVisible = Nothing + , powerSearchEnabled = Nothing + , uiLang = Nothing + , itemSearchShowGroups = Nothing + , itemSearchArrange = Nothing + } + + storedUiSettingsDecoder : Decode.Decoder StoredUiSettings storedUiSettingsDecoder = let @@ -96,12 +125,12 @@ storedUiSettingsDecoder = maybeString = Decode.maybe Decode.string - def = - defaults + maybeBool = + Decode.maybe Decode.bool in Decode.succeed StoredUiSettings |> P.optional "itemSearchPageSize" maybeInt Nothing - |> P.optional "tagCategoryColors" (Decode.keyValuePairs Decode.string) [] + |> P.optional "tagCategoryColors" (Decode.maybe <| Decode.keyValuePairs Decode.string) Nothing |> P.optional "pdfMode" maybeString Nothing |> P.optional "itemSearchNoteLength" maybeInt Nothing |> P.optional "itemDetailNotesPosition" maybeString Nothing @@ -109,53 +138,56 @@ storedUiSettingsDecoder = |> 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 def.itemDetailShortcuts - |> P.optional "searchMenuVisible" Decode.bool def.searchMenuVisible - |> P.optional "editMenuVisible" Decode.bool def.editMenuVisible + |> P.optional "itemDetailShortcuts" maybeBool Nothing + |> P.optional "searchMenuVisible" maybeBool Nothing + |> P.optional "editMenuVisible" maybeBool Nothing |> P.optional "cardPreviewSize" maybeString Nothing |> P.optional "cardTitleTemplate" maybeString Nothing |> P.optional "cardSubtitleTemplate" maybeString Nothing - |> P.optional "searchStatsVisible" Decode.bool def.searchStatsVisible - |> P.optional "cardPreviewFullWidth" Decode.bool def.cardPreviewFullWidth + |> P.optional "searchStatsVisible" maybeBool Nothing + |> P.optional "cardPreviewFullWidth" maybeBool Nothing |> P.optional "uiTheme" maybeString Nothing - |> P.optional "sideMenuVisible" Decode.bool def.sideMenuVisible - |> P.optional "powerSearchEnabled" Decode.bool def.powerSearchEnabled + |> P.optional "sideMenuVisible" maybeBool Nothing + |> P.optional "powerSearchEnabled" maybeBool Nothing |> P.optional "uiLang" maybeString Nothing - |> P.optional "itemSearchShowGroups" Decode.bool def.itemSearchShowGroups + |> P.optional "itemSearchShowGroups" maybeBool Nothing |> P.optional "itemSearchArrange" maybeString Nothing storedUiSettingsEncode : StoredUiSettings -> Encode.Value storedUiSettingsEncode value = let - maybeEnc enca ma = - Maybe.map enca ma |> Maybe.withDefault Encode.null + maybeEnc field enca ma = + Maybe.map (\a -> ( field, enca a )) ma in - Encode.object - [ ( "itemSearchPageSize", maybeEnc Encode.int value.itemSearchPageSize ) - , ( "tagCategoryColors", Encode.dict identity Encode.string (Dict.fromList value.tagCategoryColors) ) - , ( "pdfMode", maybeEnc Encode.string value.pdfMode ) - , ( "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 ) - , ( "itemSearchShowGroups", Encode.bool value.itemSearchShowGroups ) - , ( "itemSearchArrange", maybeEnc Encode.string value.itemSearchArrange ) - ] + Encode.object <| + List.filterMap identity + [ maybeEnc "itemSearchPageSize" Encode.int value.itemSearchPageSize + , maybeEnc "tagCategoryColors" + (Encode.dict identity Encode.string) + (Maybe.map Dict.fromList value.tagCategoryColors) + , maybeEnc "pdfMode" Encode.string value.pdfMode + , maybeEnc "itemSearchNoteLength" Encode.int value.itemSearchNoteLength + , maybeEnc "itemDetailNotesPosition" Encode.string value.itemDetailNotesPosition + , maybeEnc "searchMenuFolderCount" Encode.int value.searchMenuFolderCount + , maybeEnc "searchMenuTagCount" Encode.int value.searchMenuTagCount + , maybeEnc "searchMenuTagCatCount" Encode.int value.searchMenuTagCatCount + , maybeEnc "formFields" (Encode.list Encode.string) value.formFields + , maybeEnc "itemDetailShortcuts" Encode.bool value.itemDetailShortcuts + , maybeEnc "searchMenuVisible" Encode.bool value.searchMenuVisible + , maybeEnc "editMenuVisible" Encode.bool value.editMenuVisible + , maybeEnc "cardPreviewSize" Encode.string value.cardPreviewSize + , maybeEnc "cardTitleTemplate" Encode.string value.cardTitleTemplate + , maybeEnc "cardSubtitleTemplate" Encode.string value.cardSubtitleTemplate + , maybeEnc "searchStatsVisible" Encode.bool value.searchStatsVisible + , maybeEnc "cardPreviewFullWidth" Encode.bool value.cardPreviewFullWidth + , maybeEnc "uiTheme" Encode.string value.uiTheme + , maybeEnc "sideMenuVisible" Encode.bool value.sideMenuVisible + , maybeEnc "powerSearchEnabled" Encode.bool value.powerSearchEnabled + , maybeEnc "uiLang" Encode.string value.uiLang + , maybeEnc "itemSearchShowGroups" Encode.bool value.itemSearchShowGroups + , maybeEnc "itemSearchArrange" Encode.string value.itemSearchArrange + ] {-| Settings for the web ui. These fields are all mandatory, since @@ -273,7 +305,8 @@ merge given fallback = choose given.itemSearchPageSize fallback.itemSearchPageSize , tagCategoryColors = Dict.union - (Dict.fromList given.tagCategoryColors + (Maybe.map Dict.fromList given.tagCategoryColors + |> Maybe.withDefault Dict.empty |> Dict.map (\_ -> Data.Color.fromString) |> Dict.filter (\_ -> \mc -> mc /= Nothing) |> Dict.map (\_ -> Maybe.withDefault Data.Color.Grey) @@ -299,9 +332,9 @@ merge given fallback = choose (Maybe.map Data.Fields.fromList given.formFields) fallback.formFields - , itemDetailShortcuts = given.itemDetailShortcuts - , searchMenuVisible = given.searchMenuVisible - , editMenuVisible = given.editMenuVisible + , itemDetailShortcuts = choose given.itemDetailShortcuts fallback.itemDetailShortcuts + , searchMenuVisible = choose given.searchMenuVisible fallback.searchMenuVisible + , editMenuVisible = choose given.editMenuVisible fallback.editMenuVisible , cardPreviewSize = given.cardPreviewSize |> Maybe.andThen Data.BasicSize.fromString @@ -312,17 +345,17 @@ merge given fallback = , cardSubtitleTemplate = Maybe.andThen readPattern given.cardSubtitleTemplate |> Maybe.withDefault fallback.cardSubtitleTemplate - , searchStatsVisible = given.searchStatsVisible - , cardPreviewFullWidth = given.cardPreviewFullWidth + , searchStatsVisible = choose given.searchStatsVisible fallback.searchStatsVisible + , cardPreviewFullWidth = choose given.cardPreviewFullWidth fallback.cardPreviewFullWidth , uiTheme = Maybe.andThen Data.UiTheme.fromString given.uiTheme |> Maybe.withDefault fallback.uiTheme - , sideMenuVisible = given.sideMenuVisible - , powerSearchEnabled = given.powerSearchEnabled + , sideMenuVisible = choose given.sideMenuVisible fallback.sideMenuVisible + , powerSearchEnabled = choose given.powerSearchEnabled fallback.powerSearchEnabled , uiLang = Maybe.map Messages.fromIso2 given.uiLang - |> Maybe.withDefault Messages.UiLanguage.English - , itemSearchShowGroups = given.itemSearchShowGroups + |> Maybe.withDefault fallback.uiLang + , itemSearchShowGroups = choose given.itemSearchShowGroups fallback.itemSearchShowGroups , itemSearchArrange = Maybe.andThen Data.ItemArrange.fromString given.itemSearchArrange |> Maybe.withDefault fallback.itemSearchArrange @@ -334,12 +367,13 @@ mergeDefaults given = merge given defaults -toStoredUiSettings : UiSettings -> StoredUiSettings -toStoredUiSettings settings = +convert : UiSettings -> StoredUiSettings +convert settings = { itemSearchPageSize = Just settings.itemSearchPageSize , tagCategoryColors = Dict.map (\_ -> Data.Color.toString) settings.tagCategoryColors |> Dict.toList + |> Just , pdfMode = Just (Data.Pdf.asString settings.pdfMode) , itemSearchNoteLength = Just settings.itemSearchNoteLength , itemDetailNotesPosition = Just (posToString settings.itemDetailNotesPosition) @@ -349,22 +383,22 @@ toStoredUiSettings settings = , formFields = List.map Data.Fields.toString settings.formFields |> Just - , itemDetailShortcuts = settings.itemDetailShortcuts - , searchMenuVisible = settings.searchMenuVisible - , editMenuVisible = settings.editMenuVisible + , itemDetailShortcuts = Just settings.itemDetailShortcuts + , searchMenuVisible = Just settings.searchMenuVisible + , editMenuVisible = Just settings.editMenuVisible , cardPreviewSize = settings.cardPreviewSize |> Data.BasicSize.asString |> Just , cardTitleTemplate = settings.cardTitleTemplate.pattern |> Just , cardSubtitleTemplate = settings.cardSubtitleTemplate.pattern |> Just - , searchStatsVisible = settings.searchStatsVisible - , cardPreviewFullWidth = settings.cardPreviewFullWidth + , searchStatsVisible = Just settings.searchStatsVisible + , cardPreviewFullWidth = Just settings.cardPreviewFullWidth , uiTheme = Just (Data.UiTheme.toString settings.uiTheme) - , sideMenuVisible = settings.sideMenuVisible - , powerSearchEnabled = settings.powerSearchEnabled + , sideMenuVisible = Just settings.sideMenuVisible + , powerSearchEnabled = Just settings.powerSearchEnabled , uiLang = Just <| Messages.toIso2 settings.uiLang - , itemSearchShowGroups = settings.itemSearchShowGroups + , itemSearchShowGroups = Just settings.itemSearchShowGroups , itemSearchArrange = Data.ItemArrange.asString settings.itemSearchArrange |> Just } diff --git a/modules/webapp/src/main/elm/Main.elm b/modules/webapp/src/main/elm/Main.elm index 3569ad5c..d972f35b 100644 --- a/modules/webapp/src/main/elm/Main.elm +++ b/modules/webapp/src/main/elm/Main.elm @@ -14,7 +14,6 @@ import App.View2 import Browser exposing (Document) import Browser.Navigation exposing (Key) import Data.Flags exposing (Flags) -import Data.NotificationChannel import Data.UiSettings import Html exposing (..) import Html.Attributes exposing (..) @@ -93,6 +92,5 @@ subscriptions : Model -> Sub Msg subscriptions model = Sub.batch [ model.subs - , Ports.receiveUiSettings ReceiveBrowserSettings , Ports.receiveServerEvent ReceiveWsMessage ] diff --git a/modules/webapp/src/main/elm/Messages/Comp/UiSettingsManage.elm b/modules/webapp/src/main/elm/Messages/Comp/UiSettingsManage.elm index 77eb7037..409b0c4b 100644 --- a/modules/webapp/src/main/elm/Messages/Comp/UiSettingsManage.elm +++ b/modules/webapp/src/main/elm/Messages/Comp/UiSettingsManage.elm @@ -15,16 +15,22 @@ import Http import Messages.Basics import Messages.Comp.HttpError import Messages.Comp.UiSettingsForm +import Messages.Data.AccountScope type alias Texts = { basics : Messages.Basics.Texts , uiSettingsForm : Messages.Comp.UiSettingsForm.Texts + , accountScope : Messages.Data.AccountScope.Texts , saveSettings : String , settingsUnchanged : String , settingsSaved : String , unknownSaveError : String , httpError : Http.Error -> String + , userHeader : String + , userInfo : String + , collectiveHeader : String + , expandCollapse : String } @@ -32,11 +38,16 @@ gb : Texts gb = { basics = Messages.Basics.gb , uiSettingsForm = Messages.Comp.UiSettingsForm.gb + , accountScope = Messages.Data.AccountScope.gb , saveSettings = "Save settings" , settingsUnchanged = "Settings unchanged or invalid." , settingsSaved = "Settings saved." , unknownSaveError = "Unknown error while trying to save settings." , httpError = Messages.Comp.HttpError.gb + , userHeader = "Personal settings" + , userInfo = "Your personal settings override those of the collective. On reset, settings are set back to those of the collective." + , collectiveHeader = "Collective settings" + , expandCollapse = "Expand/collapse all" } @@ -44,9 +55,14 @@ de : Texts de = { basics = Messages.Basics.de , uiSettingsForm = Messages.Comp.UiSettingsForm.de + , accountScope = Messages.Data.AccountScope.de , saveSettings = "Einstellungen speichern" , settingsUnchanged = "Einstellungen nicht verändert oder ungültig." , settingsSaved = "Einstellungen gespeichert" , unknownSaveError = "Unbekannter Fehler beim Speichern der Einstellungen." , httpError = Messages.Comp.HttpError.de + , userHeader = "Persönliche Einstellungen" + , userInfo = "Die persönlichen Einstellungen überschreiben die des Kollektivs. Wenn Einstellungen zurückgesetzt werden, werden sie auf die Werte des Kollektivs gesetzt." + , collectiveHeader = "Kollektiv Einstellungen" + , expandCollapse = "Alle ein-/ausklappen" } diff --git a/modules/webapp/src/main/elm/Messages/Page/UserSettings.elm b/modules/webapp/src/main/elm/Messages/Page/UserSettings.elm index 99879774..e030fdda 100644 --- a/modules/webapp/src/main/elm/Messages/Page/UserSettings.elm +++ b/modules/webapp/src/main/elm/Messages/Page/UserSettings.elm @@ -80,8 +80,7 @@ gb = , changePassword = "Change Password" , channelSettings = "Notification Channels" , uiSettingsInfo = - "These settings only affect the web ui. They are stored in the browser, " - ++ "so they are separated between browsers and devices." + "These settings only affect the web ui. Settings can be stored to the collective or to your personal user. Personal settings are prefered when both values exist." , scanMailboxInfo1 = "Docspell can scan folders of your mailbox to import your mails. " ++ "You need to provide a connection in " @@ -144,7 +143,7 @@ de = , channelSettings = "Benachrichtigungskanäle" , changePassword = "Passwort ändern" , uiSettingsInfo = - "Diese Einstellungen sind für die Web-Oberfläche." + "Diese Einstellungen sind für die Web-Oberfläche. Es kann entweder für das ganze Kollektiv Einstellungen gemacht werden oder persönliche. Die persönlichen Einstellungen werden bevorzugt, falls beide gesetzt sind." , scanMailboxInfo1 = """Docspell kann Postfächer durchsuchen und E-Mails importieren. Dafür sind E-Mail-Einstellungen (IMAP) notwendig.""" diff --git a/modules/webapp/src/main/elm/Page/Search/Data.elm b/modules/webapp/src/main/elm/Page/Search/Data.elm index 06d6bc05..e24b2e2a 100644 --- a/modules/webapp/src/main/elm/Page/Search/Data.elm +++ b/modules/webapp/src/main/elm/Page/Search/Data.elm @@ -231,7 +231,7 @@ type Msg | KeyUpPowerSearchbarMsg (Maybe KeyCode) | RequestReprocessSelected | ReprocessSelectedConfirmed - | ClientSettingsSaveResp UiSettings (Result Http.Error BasicResult) + | ClientSettingsSaveResp (Result Http.Error BasicResult) | RemoveItem String | MergeSelectedItems | MergeItemsMsg Comp.ItemMerge.Msg diff --git a/modules/webapp/src/main/elm/Page/Search/Update.elm b/modules/webapp/src/main/elm/Page/Search/Update.elm index 6db4874d..fa25cdb2 100644 --- a/modules/webapp/src/main/elm/Page/Search/Update.elm +++ b/modules/webapp/src/main/elm/Page/Search/Update.elm @@ -22,7 +22,9 @@ import Comp.LinkTarget exposing (LinkTarget) import Comp.PowerSearchInput import Comp.PublishItems import Comp.SearchMenu +import Data.AppEvent exposing (AppEvent(..)) import Data.Flags exposing (Flags) +import Data.ItemArrange import Data.ItemQuery as Q import Data.ItemSelection import Data.Items @@ -44,7 +46,7 @@ type alias UpdateResult = { model : Model , cmd : Cmd Msg , sub : Sub Msg - , newSettings : Maybe UiSettings + , appEvent : AppEvent } @@ -74,7 +76,7 @@ update bookmarkId mId key flags texts settings msg model = model DoNothing -> - UpdateResult model Cmd.none Sub.none Nothing + UpdateResult model Cmd.none Sub.none AppNothing ResetSearch -> let @@ -868,26 +870,26 @@ update bookmarkId mId key flags texts settings msg model = TogglePreviewFullWidth -> let - newSettings = - { settings | cardPreviewFullWidth = not settings.cardPreviewFullWidth } + newSettings s = + { s | cardPreviewFullWidth = Just (not settings.cardPreviewFullWidth) } cmd = - Api.saveClientSettings flags newSettings (ClientSettingsSaveResp newSettings) + Api.saveUserClientSettingsBy flags newSettings ClientSettingsSaveResp in noSub ( { model | viewMenuOpen = False }, cmd ) - ClientSettingsSaveResp newSettings (Ok res) -> + ClientSettingsSaveResp (Ok res) -> if res.success then { model = model , cmd = Cmd.none , sub = Sub.none - , newSettings = Just newSettings + , appEvent = AppReloadUiSettings } else noSub ( model, Cmd.none ) - ClientSettingsSaveResp _ (Err _) -> + ClientSettingsSaveResp (Err _) -> noSub ( model, Cmd.none ) PowerSearchMsg lm -> @@ -1015,21 +1017,21 @@ update bookmarkId mId key flags texts settings msg model = ToggleShowGroups -> let - newSettings = - { settings | itemSearchShowGroups = not settings.itemSearchShowGroups } + newSettings s = + { s | itemSearchShowGroups = Just (not settings.itemSearchShowGroups) } cmd = - Api.saveClientSettings flags newSettings (ClientSettingsSaveResp newSettings) + Api.saveUserClientSettingsBy flags newSettings ClientSettingsSaveResp in noSub ( { model | viewMenuOpen = False }, cmd ) ToggleArrange am -> let - newSettings = - { settings | itemSearchArrange = am } + newSettings s = + { s | itemSearchArrange = Data.ItemArrange.asString am |> Just } cmd = - Api.saveClientSettings flags newSettings (ClientSettingsSaveResp newSettings) + Api.saveUserClientSettingsBy flags newSettings ClientSettingsSaveResp in noSub ( { model | viewMenuOpen = False }, cmd ) @@ -1201,5 +1203,5 @@ makeResult ( m, c, s ) = { model = m , cmd = c , sub = s - , newSettings = Nothing + , appEvent = AppNothing } diff --git a/modules/webapp/src/main/elm/Page/UserSettings/Data.elm b/modules/webapp/src/main/elm/Page/UserSettings/Data.elm index 2c71dda6..141e86e6 100644 --- a/modules/webapp/src/main/elm/Page/UserSettings/Data.elm +++ b/modules/webapp/src/main/elm/Page/UserSettings/Data.elm @@ -42,10 +42,10 @@ type alias Model = init : Flags -> UiSettings -> ( Model, Cmd Msg ) -init flags settings = +init flags _ = let ( um, uc ) = - Comp.UiSettingsManage.init flags settings + Comp.UiSettingsManage.init flags ( otpm, otpc ) = Comp.OtpSetup.init flags @@ -107,5 +107,3 @@ type Msg | NotificationHookMsg Comp.NotificationHookManage.Msg | PeriodicQueryMsg Comp.PeriodicQueryTaskManage.Msg | ChannelMsg Comp.NotificationChannelManage.Msg - | UpdateSettings - | ReceiveBrowserSettings StoredUiSettings diff --git a/modules/webapp/src/main/elm/Page/UserSettings/Update.elm b/modules/webapp/src/main/elm/Page/UserSettings/Update.elm index 656674ad..eec01a4e 100644 --- a/modules/webapp/src/main/elm/Page/UserSettings/Update.elm +++ b/modules/webapp/src/main/elm/Page/UserSettings/Update.elm @@ -17,6 +17,7 @@ import Comp.OtpSetup import Comp.PeriodicQueryTaskManage import Comp.ScanMailboxManage import Comp.UiSettingsManage +import Data.AppEvent exposing (AppEvent(..)) import Data.Flags exposing (Flags) import Data.UiSettings exposing (UiSettings) import Page.UserSettings.Data exposing (..) @@ -26,10 +27,15 @@ type alias UpdateResult = { model : Model , cmd : Cmd Msg , sub : Sub Msg - , newSettings : Maybe UiSettings + , appEvent : AppEvent } +unit : Model -> UpdateResult +unit model = + UpdateResult model Cmd.none Sub.none AppNothing + + update : Flags -> UiSettings -> Msg -> Model -> UpdateResult update flags settings msg model = case msg of @@ -47,7 +53,7 @@ update flags settings msg model = { model = { m | emailSettingsModel = em } , cmd = Cmd.map EmailSettingsMsg c , sub = Sub.none - , newSettings = Nothing + , appEvent = AppNothing } ImapSettingsTab -> @@ -58,18 +64,14 @@ update flags settings msg model = { model = { m | imapSettingsModel = em } , cmd = Cmd.map ImapSettingsMsg c , sub = Sub.none - , newSettings = Nothing + , appEvent = AppNothing } ChangePassTab -> - UpdateResult m Cmd.none Sub.none Nothing + unit m NotificationTab -> - { model = m - , cmd = Cmd.none - , sub = Sub.none - , newSettings = Nothing - } + unit m NotificationWebhookTab -> let @@ -79,7 +81,7 @@ update flags settings msg model = { model = m , cmd = Cmd.map NotificationHookMsg nc , sub = Sub.none - , newSettings = Nothing + , appEvent = AppNothing } NotificationQueriesTab -> @@ -88,7 +90,7 @@ update flags settings msg model = Cmd.map NotificationMsg (Tuple.second (Comp.DueItemsTaskManage.init flags)) in - UpdateResult m initCmd Sub.none Nothing + UpdateResult m initCmd Sub.none AppNothing NotificationDueItemsTab -> let @@ -96,7 +98,7 @@ update flags settings msg model = Cmd.map NotificationMsg (Tuple.second (Comp.DueItemsTaskManage.init flags)) in - UpdateResult m initCmd Sub.none Nothing + UpdateResult m initCmd Sub.none AppNothing ScanMailboxTab -> let @@ -104,16 +106,24 @@ update flags settings msg model = Cmd.map ScanMailboxMsg (Tuple.second (Comp.ScanMailboxManage.init flags)) in - UpdateResult m initCmd Sub.none Nothing + UpdateResult m initCmd Sub.none AppNothing UiSettingsTab -> - UpdateResult m Cmd.none Sub.none Nothing + let + ( um, uc ) = + Comp.UiSettingsManage.init flags + in + { model = { m | uiSettingsModel = um } + , cmd = Cmd.map UiSettingsMsg uc + , sub = Sub.none + , appEvent = AppNothing + } OtpTab -> - UpdateResult m Cmd.none Sub.none Nothing + unit m ChannelTab -> - UpdateResult m Cmd.none Sub.none Nothing + unit m ChangePassMsg m -> let @@ -123,7 +133,7 @@ update flags settings msg model = { model = { model | changePassModel = m2 } , cmd = Cmd.map ChangePassMsg c2 , sub = Sub.none - , newSettings = Nothing + , appEvent = AppNothing } EmailSettingsMsg m -> @@ -134,7 +144,7 @@ update flags settings msg model = { model = { model | emailSettingsModel = m2 } , cmd = Cmd.map EmailSettingsMsg c2 , sub = Sub.none - , newSettings = Nothing + , appEvent = AppNothing } ImapSettingsMsg m -> @@ -145,7 +155,7 @@ update flags settings msg model = { model = { model | imapSettingsModel = m2 } , cmd = Cmd.map ImapSettingsMsg c2 , sub = Sub.none - , newSettings = Nothing + , appEvent = AppNothing } NotificationMsg lm -> @@ -156,7 +166,7 @@ update flags settings msg model = { model = { model | notificationModel = m2 } , cmd = Cmd.map NotificationMsg c2 , sub = Sub.none - , newSettings = Nothing + , appEvent = AppNothing } ScanMailboxMsg lm -> @@ -167,7 +177,7 @@ update flags settings msg model = { model = { model | scanMailboxModel = m2 } , cmd = Cmd.map ScanMailboxMsg c2 , sub = Sub.none - , newSettings = Nothing + , appEvent = AppNothing } UiSettingsMsg lm -> @@ -178,7 +188,7 @@ update flags settings msg model = { model = { model | uiSettingsModel = res.model } , cmd = Cmd.map UiSettingsMsg res.cmd , sub = Sub.map UiSettingsMsg res.sub - , newSettings = res.newSettings + , appEvent = res.appEvent } OtpSetupMsg lm -> @@ -189,7 +199,7 @@ update flags settings msg model = { model = { model | otpSetupModel = otpm } , cmd = Cmd.map OtpSetupMsg otpc , sub = Sub.none - , newSettings = Nothing + , appEvent = AppNothing } NotificationHookMsg lm -> @@ -200,7 +210,7 @@ update flags settings msg model = { model = { model | notificationHookModel = hm } , cmd = Cmd.map NotificationHookMsg hc , sub = Sub.none - , newSettings = Nothing + , appEvent = AppNothing } ChannelMsg lm -> @@ -211,22 +221,9 @@ update flags settings msg model = { model = { model | channelModel = cm } , cmd = Cmd.map ChannelMsg cc , sub = Sub.none - , newSettings = Nothing + , appEvent = AppNothing } - UpdateSettings -> - update flags - settings - (UiSettingsMsg Comp.UiSettingsManage.UpdateSettings) - model - - ReceiveBrowserSettings sett -> - let - lm = - Comp.UiSettingsManage.ReceiveBrowserSettings sett - in - update flags settings (UiSettingsMsg lm) model - PeriodicQueryMsg lm -> let ( pqm, pqc, pqs ) = @@ -235,5 +232,5 @@ update flags settings msg model = { model = { model | periodicQueryModel = pqm } , cmd = Cmd.map PeriodicQueryMsg pqc , sub = Sub.map PeriodicQueryMsg pqs - , newSettings = Nothing + , appEvent = AppNothing } diff --git a/modules/webapp/src/main/elm/Ports.elm b/modules/webapp/src/main/elm/Ports.elm index 8a348b85..09ff2b44 100644 --- a/modules/webapp/src/main/elm/Ports.elm +++ b/modules/webapp/src/main/elm/Ports.elm @@ -11,9 +11,7 @@ port module Ports exposing , printElement , receiveCheckQueryResult , receiveServerEvent - , receiveUiSettings , removeAccount - , requestUiSettings , setAccount , setUiTheme ) @@ -21,7 +19,6 @@ port module Ports exposing import Api.Model.AuthResult exposing (AuthResult) import Data.QueryParseResult exposing (QueryParseResult) import Data.ServerEvent exposing (ServerEvent) -import Data.UiSettings exposing (StoredUiSettings) import Data.UiTheme exposing (UiTheme) import Json.Decode as D @@ -46,12 +43,6 @@ port receiveCheckQueryResult : (QueryParseResult -> msg) -> Sub msg port initClipboard : ( String, String ) -> Cmd msg -port receiveUiSettings : (StoredUiSettings -> msg) -> Sub msg - - -port requestUiSettings : AuthResult -> Cmd msg - - {-| Creates a new window/tab, writes the contents of the given element and calls the print dialog. -} diff --git a/modules/webapp/src/main/webjar/docspell.js b/modules/webapp/src/main/webjar/docspell.js index 4b32212e..0b81ff02 100644 --- a/modules/webapp/src/main/webjar/docspell.js +++ b/modules/webapp/src/main/webjar/docspell.js @@ -55,25 +55,6 @@ elmApp.ports.removeAccount.subscribe(function() { closeWS(); }); -elmApp.ports.requestUiSettings.subscribe(function(args) { - console.log("Requesting ui settings"); - var account = args; - 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); - try { - var data = settings ? JSON.parse(settings) : null; - if (data) { - console.log("Sending browser ui settings"); - elmApp.ports.receiveUiSettings.send(data); - } - } catch (error) { - console.log(error); - } - } -}); var docspell_clipboards = {};