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
This commit is contained in:
eikek
2022-01-29 10:11:25 +01:00
parent ee927096a4
commit c29ce73dd0
19 changed files with 812 additions and 438 deletions

View File

@ -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)
]
)
[]

View File

@ -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" ]

View File

@ -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" ] []
]

View File

@ -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 }