mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-04-05 19:09:32 +00:00
Merge pull request #1327 from eikek/collective-settings
Collective settings
This commit is contained in:
commit
4902fb36df
@ -6,6 +6,7 @@
|
||||
|
||||
package docspell.backend.ops
|
||||
|
||||
import cats.Semigroup
|
||||
import cats.data.OptionT
|
||||
import cats.effect.{Async, Resource}
|
||||
import cats.implicits._
|
||||
@ -32,6 +33,7 @@ trait OClientSettings[F[_]] {
|
||||
account: AccountId
|
||||
): F[Option[RClientSettingsCollective]]
|
||||
|
||||
def loadMerged(clientId: Ident, account: AccountId): F[Option[Json]]
|
||||
}
|
||||
|
||||
object OClientSettings {
|
||||
@ -108,5 +110,14 @@ object OClientSettings {
|
||||
data <- OptionT(store.transact(RClientSettingsUser.find(clientId, userId)))
|
||||
} yield data).value
|
||||
|
||||
def loadMerged(clientId: Ident, account: AccountId) =
|
||||
for {
|
||||
collData <- loadCollective(clientId, account)
|
||||
userData <- loadUser(clientId, account)
|
||||
mergedData = collData.map(_.settingsData) |+| userData.map(_.settingsData)
|
||||
} yield mergedData
|
||||
|
||||
implicit def jsonSemigroup: Semigroup[Json] =
|
||||
Semigroup.instance((a1, a2) => a1.deepMerge(a2))
|
||||
})
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ trait OShare[F[_]] {
|
||||
|
||||
// ---
|
||||
|
||||
def findActiveById(id: Ident): OptionT[F, ShareData]
|
||||
|
||||
/** Verifies the given id and password and returns a authorization token on success. */
|
||||
def verify(key: ByteVector)(id: Ident, password: Option[Password]): F[VerifyResult]
|
||||
|
||||
@ -277,6 +279,9 @@ object OShare {
|
||||
VerifyResult.invalidToken.pure[F]
|
||||
}
|
||||
|
||||
def findActiveById(id: Ident): OptionT[F, ShareData] =
|
||||
RShare.findCurrentActive(id).mapK(store.transform).map(ShareData.tupled)
|
||||
|
||||
def findShareQuery(id: Ident): OptionT[F, ShareQuery] =
|
||||
RShare
|
||||
.findCurrentActive(id)
|
||||
|
@ -2304,7 +2304,7 @@ paths:
|
||||
/share/attachment/{id}/preview:
|
||||
head:
|
||||
operationId: "share-attach-check-preview"
|
||||
tags: [ Attachment ]
|
||||
tags: [ Share ]
|
||||
summary: Get the headers to a preview image of an attachment file.
|
||||
description: |
|
||||
Checks if an image file showing a preview of the attachment is
|
||||
@ -2320,7 +2320,7 @@ paths:
|
||||
description: NotFound
|
||||
get:
|
||||
operationId: "share-attach-get-preview"
|
||||
tags: [ Attachment ]
|
||||
tags: [ Share ]
|
||||
summary: Get a preview image of an attachment file.
|
||||
description: |
|
||||
Gets a image file showing a preview of the attachment. Usually
|
||||
@ -2347,6 +2347,31 @@ paths:
|
||||
schema:
|
||||
type: string
|
||||
format: binary
|
||||
/share/clientSettings/{clientId}:
|
||||
parameters:
|
||||
- $ref: "#/components/parameters/clientId"
|
||||
get:
|
||||
operationId: "share-clientsettings-get"
|
||||
tags: [ Share ]
|
||||
summary: Return the client settings of current user
|
||||
description: |
|
||||
Returns the settings for the share. This is the settings of
|
||||
the collective that belongs to the share.
|
||||
|
||||
The `clientId` is an identifier to a client application. It
|
||||
returns a JSON structure. The server doesn't care about the
|
||||
actual data, since it is meant to be interpreted by clients.
|
||||
security:
|
||||
- shareTokenHeader: []
|
||||
responses:
|
||||
422:
|
||||
description: BadRequest
|
||||
200:
|
||||
description: Ok
|
||||
content:
|
||||
application/json:
|
||||
schema: {}
|
||||
|
||||
|
||||
/admin/user/resetPassword:
|
||||
post:
|
||||
|
@ -213,7 +213,8 @@ object RestServer {
|
||||
Router(
|
||||
"search" -> ShareSearchRoutes(restApp.backend, cfg, token),
|
||||
"attachment" -> ShareAttachmentRoutes(restApp.backend, token),
|
||||
"item" -> ShareItemRoutes(restApp.backend, token)
|
||||
"item" -> ShareItemRoutes(restApp.backend, token),
|
||||
"clientSettings" -> ClientSettingsRoutes.share(restApp.backend, token)
|
||||
)
|
||||
|
||||
def redirectTo[F[_]: Async](path: String): HttpRoutes[F] = {
|
||||
|
@ -6,12 +6,12 @@
|
||||
|
||||
package docspell.restserver.routes
|
||||
|
||||
import cats.data.OptionT
|
||||
import cats.effect._
|
||||
import cats.implicits._
|
||||
import cats.kernel.Semigroup
|
||||
|
||||
import docspell.backend.BackendApp
|
||||
import docspell.backend.auth.AuthToken
|
||||
import docspell.backend.auth.{AuthToken, ShareToken}
|
||||
import docspell.common._
|
||||
import docspell.restapi.model._
|
||||
|
||||
@ -23,6 +23,28 @@ import org.http4s.dsl.Http4sDsl
|
||||
|
||||
object ClientSettingsRoutes {
|
||||
|
||||
def share[F[_]: Async](
|
||||
backend: BackendApp[F],
|
||||
token: ShareToken
|
||||
): HttpRoutes[F] = {
|
||||
val logger = Logger.log4s[F](org.log4s.getLogger)
|
||||
|
||||
val dsl = new Http4sDsl[F] {}
|
||||
import dsl._
|
||||
|
||||
HttpRoutes.of { case GET -> Root / Ident(clientId) =>
|
||||
(for {
|
||||
_ <- OptionT.liftF(logger.debug(s"Get client settings for share ${token.id}"))
|
||||
share <- backend.share.findActiveById(token.id)
|
||||
sett <- OptionT(
|
||||
backend.clientSettings.loadCollective(clientId, share.user.accountId)
|
||||
)
|
||||
res <- OptionT.liftF(Ok(sett.settingsData))
|
||||
} yield res)
|
||||
.getOrElseF(Ok(Map.empty[String, String]))
|
||||
}
|
||||
}
|
||||
|
||||
def apply[F[_]: Async](backend: BackendApp[F], user: AuthToken): HttpRoutes[F] = {
|
||||
val dsl = new Http4sDsl[F] {}
|
||||
import dsl._
|
||||
@ -30,14 +52,10 @@ object ClientSettingsRoutes {
|
||||
HttpRoutes.of {
|
||||
case GET -> Root / Ident(clientId) =>
|
||||
for {
|
||||
collData <- backend.clientSettings.loadCollective(clientId, user.account)
|
||||
userData <- backend.clientSettings.loadUser(clientId, user.account)
|
||||
|
||||
mergedData = collData.map(_.settingsData) |+| userData.map(_.settingsData)
|
||||
|
||||
mergedData <- backend.clientSettings.loadMerged(clientId, user.account)
|
||||
res <- mergedData match {
|
||||
case Some(j) => Ok(j)
|
||||
case None => NotFound()
|
||||
case None => Ok(Map.empty[String, String])
|
||||
}
|
||||
} yield res
|
||||
|
||||
@ -96,7 +114,4 @@ object ClientSettingsRoutes {
|
||||
} yield res
|
||||
}
|
||||
}
|
||||
|
||||
implicit def jsonSemigroup: Semigroup[Json] =
|
||||
Semigroup.instance((a1, a2) => a1.deepMerge(a2))
|
||||
}
|
||||
|
@ -22,6 +22,7 @@ module Api exposing
|
||||
, changeFolderName
|
||||
, changePassword
|
||||
, checkCalEvent
|
||||
, clientSettingsShare
|
||||
, confirmMultiple
|
||||
, confirmOtp
|
||||
, createChannel
|
||||
@ -64,6 +65,7 @@ module Api exposing
|
||||
, getChannels
|
||||
, getChannelsIgnoreError
|
||||
, getClientSettings
|
||||
, getClientSettingsRaw
|
||||
, getCollective
|
||||
, getCollectiveSettings
|
||||
, getContacts
|
||||
@ -136,6 +138,7 @@ module Api exposing
|
||||
, restoreItem
|
||||
, sampleEvent
|
||||
, saveClientSettings
|
||||
, saveUserClientSettingsBy
|
||||
, searchShare
|
||||
, searchShareStats
|
||||
, sendMail
|
||||
@ -296,7 +299,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 +2338,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 +2356,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
|
||||
|
||||
@ -2749,6 +2821,23 @@ itemDetailShare flags token itemId receive =
|
||||
}
|
||||
|
||||
|
||||
clientSettingsShare : Flags -> String -> (Result Http.Error UiSettings -> msg) -> Cmd msg
|
||||
clientSettingsShare flags token receive =
|
||||
let
|
||||
defaults =
|
||||
Data.UiSettings.defaults
|
||||
|
||||
decoder =
|
||||
JsonDecode.map (\s -> Data.UiSettings.merge s defaults)
|
||||
Data.UiSettings.storedUiSettingsDecoder
|
||||
in
|
||||
Http2.shareGet
|
||||
{ url = flags.config.baseUrl ++ "/api/v1/share/clientSettings/webClient"
|
||||
, token = token
|
||||
, expect = Http.expectJson receive decoder
|
||||
}
|
||||
|
||||
|
||||
shareSendMail :
|
||||
Flags
|
||||
-> { conn : String, mail : SimpleShareMail }
|
||||
|
@ -18,18 +18,15 @@ import Api.Model.BasicResult exposing (BasicResult)
|
||||
import Api.Model.VersionInfo exposing (VersionInfo)
|
||||
import Browser exposing (UrlRequest)
|
||||
import Browser.Navigation exposing (Key)
|
||||
import Data.Dashboard exposing (Dashboard)
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.ServerEvent exposing (ServerEvent)
|
||||
import Data.UiSettings exposing (StoredUiSettings, UiSettings)
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Data.UiTheme exposing (UiTheme)
|
||||
import Http
|
||||
import Messages
|
||||
import Messages.UiLanguage exposing (UiLanguage)
|
||||
import Page exposing (Page(..))
|
||||
import Page.CollectiveSettings.Data
|
||||
import Page.Dashboard.Data
|
||||
import Page.Dashboard.DefaultDashboard
|
||||
import Page.ItemDetail.Data
|
||||
import Page.Login.Data
|
||||
import Page.ManageData.Data
|
||||
@ -107,11 +104,7 @@ init key url flags_ settings =
|
||||
Page.Dashboard.Data.init flags
|
||||
|
||||
searchViewMode =
|
||||
if settings.searchMenuVisible then
|
||||
Page.Search.Data.SearchView
|
||||
|
||||
else
|
||||
Page.Search.Data.SimpleView
|
||||
Page.Search.Data.SearchView
|
||||
in
|
||||
( { flags = flags
|
||||
, key = key
|
||||
@ -204,8 +197,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
|
||||
|
||||
|
@ -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
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -144,7 +144,12 @@ viewItemRow texts settings meta item =
|
||||
getColumns meta
|
||||
|
||||
render col =
|
||||
Comp.ItemColumnView.renderDiv texts.templateCtx settings col [ class "flex flex-row flex-wrap space-x-1" ] item
|
||||
Comp.ItemColumnView.renderDiv
|
||||
texts.templateCtx
|
||||
settings
|
||||
col
|
||||
[ class "flex flex-row flex-wrap space-x-1 space-y-1" ]
|
||||
item
|
||||
|
||||
td1 =
|
||||
td [ class "py-2 px-1" ]
|
||||
@ -158,7 +163,7 @@ viewItemRow texts settings meta item =
|
||||
|
||||
tdRem index col =
|
||||
td
|
||||
[ class "py-2 px-1"
|
||||
[ class "py-1 px-1"
|
||||
, classList [ ( "hidden md:table-cell", index > 1 ) ]
|
||||
]
|
||||
[ render col
|
||||
|
@ -1411,7 +1411,7 @@ update key flags inav settings msg model =
|
||||
let
|
||||
model_ =
|
||||
{ model
|
||||
| menuOpen = settings.editMenuVisible
|
||||
| menuOpen = settings.sideMenuVisible
|
||||
}
|
||||
in
|
||||
resultModel model_
|
||||
|
@ -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)
|
||||
]
|
||||
)
|
||||
[]
|
||||
|
@ -9,6 +9,8 @@ module Comp.UiSettingsForm exposing
|
||||
( Model
|
||||
, Msg
|
||||
, init
|
||||
, initData
|
||||
, toggleAllTabs
|
||||
, update
|
||||
, view2
|
||||
)
|
||||
@ -30,7 +32,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, StoredUiSettings, UiSettings)
|
||||
import Dict exposing (Dict)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
@ -73,6 +75,7 @@ type alias Model =
|
||||
, uiLangModel : Comp.FixedDropdown.Model UiLanguage
|
||||
, uiLang : UiLanguage
|
||||
, openTabs : Set String
|
||||
, defaults : UiSettings
|
||||
}
|
||||
|
||||
|
||||
@ -111,61 +114,78 @@ 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 )
|
||||
|
||||
|
||||
initData : Flags -> StoredUiSettings -> UiSettings -> Model -> ( Model, Cmd Msg )
|
||||
initData flags storedSettings defaults model =
|
||||
let
|
||||
( m, c ) =
|
||||
init flags storedSettings defaults
|
||||
in
|
||||
( { m | openTabs = model.openTabs }, c )
|
||||
|
||||
|
||||
type Msg
|
||||
@ -188,14 +208,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 +270,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 +286,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 +302,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 +318,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 +334,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 +349,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 +388,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 +408,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 +419,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 +443,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 +460,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 +477,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 +511,7 @@ update sett msg model =
|
||||
not model.sideMenuVisible
|
||||
in
|
||||
( { model | sideMenuVisible = next }
|
||||
, Just { sett | sideMenuVisible = next }
|
||||
, Just { sett | sideMenuVisible = Just next }
|
||||
)
|
||||
|
||||
TogglePowerSearch ->
|
||||
@ -438,7 +520,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 +536,7 @@ update sett msg model =
|
||||
Nothing
|
||||
|
||||
else
|
||||
Just { sett | uiLang = newLang }
|
||||
Just { sett | uiLang = Just (Messages.toIso2 newLang) }
|
||||
)
|
||||
|
||||
PdfModeMsg lm ->
|
||||
@ -470,9 +552,52 @@ 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 }
|
||||
|
||||
FieldsTab ->
|
||||
{ sett | formFields = Nothing }
|
||||
|
||||
nm =
|
||||
initModel flags newSettings model.defaults
|
||||
in
|
||||
( { nm | openTabs = model.openTabs }, Just newSettings )
|
||||
|
||||
|
||||
|
||||
--- View2
|
||||
@ -495,7 +620,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 +642,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 +658,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 texts.resetLabel
|
||||
]
|
||||
in
|
||||
[ { name = "general"
|
||||
[ { name = akkordionTabName GeneralTab
|
||||
, title = texts.general
|
||||
, titleRight = []
|
||||
, titleRight = [ resetLink GeneralTab ]
|
||||
, info = Nothing
|
||||
, body =
|
||||
[ div [ class "mb-4 " ]
|
||||
@ -560,9 +696,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 +730,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 +802,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 +836,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 +862,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 +875,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" ]
|
||||
|
@ -16,26 +16,44 @@ 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 Process
|
||||
import Styles as S
|
||||
import Task
|
||||
|
||||
|
||||
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 +63,40 @@ 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
|
||||
| ResetFormState
|
||||
|
||||
|
||||
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 +105,177 @@ 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_
|
||||
}
|
||||
}
|
||||
|
||||
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_
|
||||
}
|
||||
}
|
||||
|
||||
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 | formResult = FormSaved }
|
||||
|
||||
cmd =
|
||||
Process.sleep 2000
|
||||
|> Task.perform (\_ -> ResetFormState)
|
||||
in
|
||||
{ result | appEvent = AppReloadUiSettings, cmd = Cmd.batch [ cmd, result.cmd ] }
|
||||
|
||||
_ ->
|
||||
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 ), ( cm, cc ) ) =
|
||||
case model.formData of
|
||||
Just data ->
|
||||
( Comp.UiSettingsForm.initData flags user userDefaults data.userModel
|
||||
, Comp.UiSettingsForm.initData flags coll collDefaults data.collModel
|
||||
)
|
||||
|
||||
Nothing ->
|
||||
( Comp.UiSettingsForm.init flags user userDefaults
|
||||
, Comp.UiSettingsForm.init flags coll collDefaults
|
||||
)
|
||||
|
||||
model_ =
|
||||
{ model
|
||||
| formData =
|
||||
Just
|
||||
{ userSettings = user
|
||||
, userModel = um
|
||||
, collSettings = coll
|
||||
, collModel = cm
|
||||
}
|
||||
, formModel =
|
||||
case model.formModel of
|
||||
ViewLoading ->
|
||||
ViewUser
|
||||
|
||||
_ ->
|
||||
model.formModel
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
Data.AccountScope.fold forUser forColl scope
|
||||
|
||||
ResetFormState ->
|
||||
case model.formResult of
|
||||
FormSaved ->
|
||||
unit { model | formResult = FormInit }
|
||||
|
||||
|
||||
--- View2
|
||||
_ ->
|
||||
unit model
|
||||
|
||||
|
||||
isError : Model -> Bool
|
||||
@ -211,7 +303,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 +317,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 +363,55 @@ 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
|
||||
]
|
||||
, div [ class "py-1 opacity-80" ]
|
||||
[ text texts.collectiveInfo
|
||||
]
|
||||
, 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" ] []
|
||||
]
|
||||
|
@ -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 }
|
||||
|
||||
|
@ -23,6 +23,11 @@ fold user coll scope =
|
||||
coll
|
||||
|
||||
|
||||
all : List AccountScope
|
||||
all =
|
||||
[ Collective, User ]
|
||||
|
||||
|
||||
isUser : AccountScope -> Bool
|
||||
isUser scope =
|
||||
fold True False scope
|
||||
|
13
modules/webapp/src/main/elm/Data/AppEvent.elm
Normal file
13
modules/webapp/src/main/elm/Data/AppEvent.elm
Normal file
@ -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
|
@ -7,7 +7,6 @@
|
||||
|
||||
module Data.UiSettings exposing
|
||||
( ItemPattern
|
||||
, Pos(..)
|
||||
, StoredUiSettings
|
||||
, UiSettings
|
||||
, cardPreviewSize
|
||||
@ -15,22 +14,21 @@ module Data.UiSettings exposing
|
||||
, catColor
|
||||
, catColorFg2
|
||||
, catColorString2
|
||||
, convert
|
||||
, defaults
|
||||
, documentationSite
|
||||
, emptyStoredSettings
|
||||
, fieldHidden
|
||||
, fieldVisible
|
||||
, getUiLanguage
|
||||
, merge
|
||||
, mergeDefaults
|
||||
, pdfUrl
|
||||
, posFromString
|
||||
, posToString
|
||||
, storedUiSettingsDecoder
|
||||
, storedUiSettingsEncode
|
||||
, tagColor
|
||||
, tagColorFg2
|
||||
, tagColorString2
|
||||
, toStoredUiSettings
|
||||
)
|
||||
|
||||
import Api.Model.Tag exposing (Tag)
|
||||
@ -62,31 +60,53 @@ 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
|
||||
, searchMenuFolderCount : Maybe Int
|
||||
, searchMenuTagCount : Maybe Int
|
||||
, searchMenuTagCatCount : Maybe Int
|
||||
, formFields : Maybe (List String)
|
||||
, itemDetailShortcuts : Bool
|
||||
, searchMenuVisible : Bool
|
||||
, editMenuVisible : Bool
|
||||
, itemDetailShortcuts : 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
|
||||
, searchMenuFolderCount = Nothing
|
||||
, searchMenuTagCount = Nothing
|
||||
, searchMenuTagCatCount = Nothing
|
||||
, formFields = Nothing
|
||||
, itemDetailShortcuts = 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,66 +116,63 @@ 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
|
||||
|> 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 def.itemDetailShortcuts
|
||||
|> P.optional "searchMenuVisible" Decode.bool def.searchMenuVisible
|
||||
|> P.optional "editMenuVisible" Decode.bool def.editMenuVisible
|
||||
|> P.optional "itemDetailShortcuts" 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 "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 "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
|
||||
@ -171,14 +188,11 @@ type alias UiSettings =
|
||||
, tagCategoryColors : Dict String Color
|
||||
, pdfMode : PdfMode
|
||||
, itemSearchNoteLength : Int
|
||||
, itemDetailNotesPosition : Pos
|
||||
, searchMenuFolderCount : Int
|
||||
, searchMenuTagCount : Int
|
||||
, searchMenuTagCatCount : Int
|
||||
, formFields : List Field
|
||||
, itemDetailShortcuts : Bool
|
||||
, searchMenuVisible : Bool
|
||||
, editMenuVisible : Bool
|
||||
, cardPreviewSize : BasicSize
|
||||
, cardTitleTemplate : ItemPattern
|
||||
, cardSubtitleTemplate : ItemPattern
|
||||
@ -205,48 +219,17 @@ readPattern str =
|
||||
|> Maybe.map (ItemPattern str)
|
||||
|
||||
|
||||
type Pos
|
||||
= Top
|
||||
| Bottom
|
||||
|
||||
|
||||
posToString : Pos -> String
|
||||
posToString pos =
|
||||
case pos of
|
||||
Top ->
|
||||
"top"
|
||||
|
||||
Bottom ->
|
||||
"bottom"
|
||||
|
||||
|
||||
posFromString : String -> Maybe Pos
|
||||
posFromString str =
|
||||
case str of
|
||||
"top" ->
|
||||
Just Top
|
||||
|
||||
"bottom" ->
|
||||
Just Bottom
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
|
||||
|
||||
defaults : UiSettings
|
||||
defaults =
|
||||
{ itemSearchPageSize = 60
|
||||
, tagCategoryColors = Dict.empty
|
||||
, pdfMode = Data.Pdf.Detect
|
||||
, itemSearchNoteLength = 0
|
||||
, itemDetailNotesPosition = Bottom
|
||||
, searchMenuFolderCount = 3
|
||||
, searchMenuTagCount = 6
|
||||
, searchMenuTagCatCount = 3
|
||||
, formFields = Data.Fields.all
|
||||
, itemDetailShortcuts = False
|
||||
, searchMenuVisible = False
|
||||
, editMenuVisible = False
|
||||
, cardPreviewSize = Data.BasicSize.Medium
|
||||
, cardTitleTemplate =
|
||||
{ template = Data.ItemTemplate.name
|
||||
@ -273,7 +256,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)
|
||||
@ -285,9 +269,6 @@ merge given fallback =
|
||||
|> Maybe.withDefault fallback.pdfMode
|
||||
, itemSearchNoteLength =
|
||||
choose given.itemSearchNoteLength fallback.itemSearchNoteLength
|
||||
, itemDetailNotesPosition =
|
||||
choose (Maybe.andThen posFromString given.itemDetailNotesPosition)
|
||||
fallback.itemDetailNotesPosition
|
||||
, searchMenuFolderCount =
|
||||
choose given.searchMenuFolderCount
|
||||
fallback.searchMenuFolderCount
|
||||
@ -299,9 +280,7 @@ 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
|
||||
, cardPreviewSize =
|
||||
given.cardPreviewSize
|
||||
|> Maybe.andThen Data.BasicSize.fromString
|
||||
@ -312,17 +291,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,37 +313,35 @@ 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)
|
||||
, searchMenuFolderCount = Just settings.searchMenuFolderCount
|
||||
, searchMenuTagCount = Just settings.searchMenuTagCount
|
||||
, searchMenuTagCatCount = Just settings.searchMenuTagCatCount
|
||||
, formFields =
|
||||
List.map Data.Fields.toString settings.formFields
|
||||
|> Just
|
||||
, itemDetailShortcuts = settings.itemDetailShortcuts
|
||||
, searchMenuVisible = settings.searchMenuVisible
|
||||
, editMenuVisible = settings.editMenuVisible
|
||||
, itemDetailShortcuts = Just settings.itemDetailShortcuts
|
||||
, 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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
]
|
||||
|
@ -56,6 +56,7 @@ type alias Texts =
|
||||
, fieldLabel : Field -> String
|
||||
, templateHelpMessage : String
|
||||
, pdfMode : PdfMode -> String
|
||||
, resetLabel : String
|
||||
}
|
||||
|
||||
|
||||
@ -131,6 +132,7 @@ and if that is not present the person. If both are absent a dash `-`
|
||||
is rendered.
|
||||
"""
|
||||
, pdfMode = Messages.Data.PdfMode.gb
|
||||
, resetLabel = "Reset"
|
||||
}
|
||||
|
||||
|
||||
@ -208,4 +210,5 @@ oder, wenn diese leer ist, die Person. Sind beide leer wird ein `-`
|
||||
dargestellt.
|
||||
"""
|
||||
, pdfMode = Messages.Data.PdfMode.de
|
||||
, resetLabel = "Zurücksetzen"
|
||||
}
|
||||
|
@ -15,16 +15,23 @@ 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
|
||||
, collectiveInfo : String
|
||||
, expandCollapse : String
|
||||
}
|
||||
|
||||
|
||||
@ -32,11 +39,17 @@ 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 taken from the collective settings."
|
||||
, collectiveHeader = "Collective settings"
|
||||
, collectiveInfo = "These settings apply to all users, unless overriden by personal ones. A reset loads the provided default values of the application."
|
||||
, expandCollapse = "Expand/collapse all"
|
||||
}
|
||||
|
||||
|
||||
@ -44,9 +57,15 @@ 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, gelten automatisch die Werte des Kollektivs."
|
||||
, collectiveHeader = "Kollektiv Einstellungen"
|
||||
, collectiveInfo = "Diese Einstellungen sind für alle Benutzer, können aber in den persönlichen Einstellungen überschrieben werden. Durch ein Zurücksetzen erhält man die bereitgestellten Standardwerte der Anwendung."
|
||||
, expandCollapse = "Alle ein-/ausklappen"
|
||||
}
|
||||
|
@ -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."""
|
||||
|
@ -109,8 +109,7 @@ initSelectViewModel flags =
|
||||
|
||||
|
||||
type ViewMode
|
||||
= SimpleView
|
||||
| SearchView
|
||||
= SearchView
|
||||
| SelectView SelectViewModel
|
||||
| PublishView Comp.PublishItems.Model
|
||||
|
||||
@ -149,9 +148,6 @@ init flags viewMode =
|
||||
menuCollapsed : Model -> Bool
|
||||
menuCollapsed model =
|
||||
case model.viewMode of
|
||||
SimpleView ->
|
||||
True
|
||||
|
||||
SearchView ->
|
||||
False
|
||||
|
||||
@ -165,9 +161,6 @@ menuCollapsed model =
|
||||
selectActive : Model -> Bool
|
||||
selectActive model =
|
||||
case model.viewMode of
|
||||
SimpleView ->
|
||||
False
|
||||
|
||||
SearchView ->
|
||||
False
|
||||
|
||||
@ -181,9 +174,6 @@ selectActive model =
|
||||
editActive : Model -> Bool
|
||||
editActive model =
|
||||
case model.viewMode of
|
||||
SimpleView ->
|
||||
False
|
||||
|
||||
SearchView ->
|
||||
False
|
||||
|
||||
@ -203,7 +193,6 @@ type Msg
|
||||
| ItemSearchResp Bool (Result Http.Error ItemLightList)
|
||||
| ItemSearchAddResp (Result Http.Error ItemLightList)
|
||||
| DoSearch SearchType
|
||||
| ToggleSearchMenu
|
||||
| ToggleSelectView
|
||||
| LoadMore
|
||||
| SetBasicSearch String
|
||||
@ -231,7 +220,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
|
||||
|
@ -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
|
||||
@ -274,34 +276,10 @@ update bookmarkId mId key flags texts settings msg model =
|
||||
else
|
||||
doSearch param model
|
||||
|
||||
ToggleSearchMenu ->
|
||||
let
|
||||
nextView =
|
||||
case model.viewMode of
|
||||
SimpleView ->
|
||||
SearchView
|
||||
|
||||
SearchView ->
|
||||
SimpleView
|
||||
|
||||
SelectView _ ->
|
||||
SimpleView
|
||||
|
||||
PublishView q ->
|
||||
PublishView q
|
||||
in
|
||||
withSub
|
||||
( { model | viewMode = nextView }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
ToggleSelectView ->
|
||||
let
|
||||
( nextView, cmd ) =
|
||||
case model.viewMode of
|
||||
SimpleView ->
|
||||
( SelectView <| initSelectViewModel flags, loadEditModel flags )
|
||||
|
||||
SearchView ->
|
||||
( SelectView <| initSelectViewModel flags, loadEditModel flags )
|
||||
|
||||
@ -642,11 +620,7 @@ update bookmarkId mId key flags texts settings msg model =
|
||||
SelectView { svm | mergeModel = result.model }
|
||||
|
||||
Comp.ItemMerge.OutcomeMerged ->
|
||||
if settings.searchMenuVisible then
|
||||
SearchView
|
||||
|
||||
else
|
||||
SimpleView
|
||||
SearchView
|
||||
|
||||
model_ =
|
||||
{ model | viewMode = nextView }
|
||||
@ -834,17 +808,10 @@ update bookmarkId mId key flags texts settings msg model =
|
||||
UiSettingsUpdated ->
|
||||
let
|
||||
defaultViewMode =
|
||||
if settings.searchMenuVisible then
|
||||
SearchView
|
||||
|
||||
else
|
||||
SimpleView
|
||||
SearchView
|
||||
|
||||
viewMode =
|
||||
case model.viewMode of
|
||||
SimpleView ->
|
||||
defaultViewMode
|
||||
|
||||
SearchView ->
|
||||
defaultViewMode
|
||||
|
||||
@ -868,26 +835,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 +982,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 +1168,5 @@ makeResult ( m, c, s ) =
|
||||
{ model = m
|
||||
, cmd = c
|
||||
, sub = s
|
||||
, newSettings = Nothing
|
||||
, appEvent = AppNothing
|
||||
}
|
||||
|
@ -93,9 +93,6 @@ mainView texts flags settings model =
|
||||
(publishResults texts settings flags model pm)
|
||||
]
|
||||
|
||||
SimpleView ->
|
||||
Nothing
|
||||
|
||||
SearchView ->
|
||||
Nothing
|
||||
in
|
||||
@ -109,7 +106,7 @@ mainView texts flags settings model =
|
||||
|
||||
|
||||
bookmarkQueryWidget : Texts -> UiSettings -> Flags -> Model -> List (Html Msg)
|
||||
bookmarkQueryWidget texts settings flags model =
|
||||
bookmarkQueryWidget texts _ _ model =
|
||||
case model.topWidgetModel of
|
||||
BookmarkQuery m ->
|
||||
[ div [ class "px-2 mb-4 border-l border-r border-b dark:border-slate-600" ]
|
||||
@ -136,7 +133,7 @@ itemMergeView texts settings svm =
|
||||
|
||||
|
||||
publishResults : Texts -> UiSettings -> Flags -> Model -> Comp.PublishItems.Model -> List (Html Msg)
|
||||
publishResults texts settings flags model pm =
|
||||
publishResults texts settings flags _ pm =
|
||||
[ Html.map PublishViewMsg
|
||||
(Comp.PublishItems.view texts.publishItems settings flags pm)
|
||||
]
|
||||
@ -188,9 +185,6 @@ confirmModal texts model =
|
||||
itemsBar : Texts -> Flags -> UiSettings -> Model -> List (Html Msg)
|
||||
itemsBar texts flags settings model =
|
||||
case model.viewMode of
|
||||
SimpleView ->
|
||||
[ defaultMenuBar texts flags settings model ]
|
||||
|
||||
SearchView ->
|
||||
[ defaultMenuBar texts flags settings model ]
|
||||
|
||||
|
@ -18,6 +18,7 @@ import Comp.SearchMenu
|
||||
import Comp.SharePasswordForm
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.ItemArrange exposing (ItemArrange)
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Http
|
||||
import Page.Search.Data exposing (Msg(..))
|
||||
import Set exposing (Set)
|
||||
@ -53,6 +54,7 @@ type alias Model =
|
||||
, initialized : Bool
|
||||
, contentSearch : Maybe String
|
||||
, searchMode : SearchBarMode
|
||||
, uiSettings : UiSettings
|
||||
, viewMode :
|
||||
{ menuOpen : Bool
|
||||
, showGroups : Bool
|
||||
@ -75,6 +77,7 @@ emptyModel flags =
|
||||
, initialized = False
|
||||
, contentSearch = Nothing
|
||||
, searchMode = SearchBarContent
|
||||
, uiSettings = Data.UiSettings.defaults
|
||||
, viewMode =
|
||||
{ menuOpen = False
|
||||
, showGroups = True
|
||||
@ -107,6 +110,7 @@ type Msg
|
||||
= VerifyResp (Result Http.Error ShareVerifyResult)
|
||||
| SearchResp (Result Http.Error ItemLightList)
|
||||
| StatsResp Bool (Result Http.Error SearchStats)
|
||||
| UiSettingsResp (Result Http.Error UiSettings)
|
||||
| PasswordMsg Comp.SharePasswordForm.Msg
|
||||
| SearchMenuMsg Comp.SearchMenu.Msg
|
||||
| PowerSearchMsg Comp.PowerSearchInput.Msg
|
||||
|
@ -10,7 +10,6 @@ module Page.Share.Sidebar exposing (..)
|
||||
import Comp.SearchMenu
|
||||
import Comp.Tabs
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Messages.Page.Share exposing (Texts)
|
||||
@ -18,8 +17,8 @@ import Page.Share.Data exposing (Model, Msg(..))
|
||||
import Util.ItemDragDrop
|
||||
|
||||
|
||||
view : Texts -> Flags -> UiSettings -> Model -> Html Msg
|
||||
view texts flags settings model =
|
||||
view : Texts -> Flags -> Model -> Html Msg
|
||||
view texts flags model =
|
||||
let
|
||||
hideTrashTab tab default =
|
||||
case tab of
|
||||
@ -41,7 +40,7 @@ view texts flags settings model =
|
||||
ddDummy
|
||||
flags
|
||||
searchMenuCfg
|
||||
settings
|
||||
model.uiSettings
|
||||
model.searchMenuModel
|
||||
)
|
||||
]
|
||||
|
@ -43,7 +43,10 @@ update flags settings shareId msg model =
|
||||
, verifyResult = res
|
||||
, searchInProgress = True
|
||||
}
|
||||
, makeSearchCmd flags True model
|
||||
, Cmd.batch
|
||||
[ makeSearchCmd flags True model
|
||||
, Api.clientSettingsShare flags res.token UiSettingsResp
|
||||
]
|
||||
)
|
||||
|
||||
else if res.passwordRequired then
|
||||
@ -242,6 +245,12 @@ update flags settings shareId msg model =
|
||||
in
|
||||
noSub ( { model | viewMode = next }, Cmd.none )
|
||||
|
||||
UiSettingsResp (Ok s) ->
|
||||
noSub ( { model | uiSettings = s }, Cmd.none )
|
||||
|
||||
UiSettingsResp (Err _) ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
|
||||
noSub : ( Model, Cmd Msg ) -> UpdateResult
|
||||
noSub ( m, c ) =
|
||||
|
@ -11,11 +11,9 @@ import Api.Model.VersionInfo exposing (VersionInfo)
|
||||
import Comp.Basic as B
|
||||
import Comp.SharePasswordForm
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Items
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onInput, onSubmit)
|
||||
import Messages.Page.Share exposing (Texts)
|
||||
import Page.Share.Data exposing (..)
|
||||
import Page.Share.Menubar as Menubar
|
||||
@ -25,19 +23,19 @@ import Styles as S
|
||||
|
||||
|
||||
viewSidebar : Texts -> Bool -> Flags -> UiSettings -> Model -> Html Msg
|
||||
viewSidebar texts visible flags settings model =
|
||||
viewSidebar texts visible flags _ model =
|
||||
div
|
||||
[ id "sidebar"
|
||||
, class S.sidebar
|
||||
, class S.sidebarBg
|
||||
, classList [ ( "hidden", not visible || model.mode /= ModeShare ) ]
|
||||
]
|
||||
[ Sidebar.view texts flags settings model
|
||||
[ Sidebar.view texts flags model
|
||||
]
|
||||
|
||||
|
||||
viewContent : Texts -> Flags -> VersionInfo -> UiSettings -> String -> Model -> Html Msg
|
||||
viewContent texts flags versionInfo uiSettings shareId model =
|
||||
viewContent texts flags versionInfo _ shareId model =
|
||||
case model.mode of
|
||||
ModeInitial ->
|
||||
div
|
||||
@ -60,15 +58,15 @@ viewContent texts flags versionInfo uiSettings shareId model =
|
||||
passwordContent texts flags versionInfo model
|
||||
|
||||
ModeShare ->
|
||||
mainContent texts flags uiSettings shareId model
|
||||
mainContent texts flags shareId model
|
||||
|
||||
|
||||
|
||||
--- Helpers
|
||||
|
||||
|
||||
mainContent : Texts -> Flags -> UiSettings -> String -> Model -> Html Msg
|
||||
mainContent texts flags settings shareId model =
|
||||
mainContent : Texts -> Flags -> String -> Model -> Html Msg
|
||||
mainContent texts flags shareId model =
|
||||
div
|
||||
[ id "content"
|
||||
, class "h-full flex flex-col"
|
||||
@ -82,7 +80,7 @@ mainContent texts flags settings shareId model =
|
||||
]
|
||||
, Menubar.view texts flags model
|
||||
, errorMessage texts model
|
||||
, Results.view texts settings flags shareId model
|
||||
, Results.view texts model.uiSettings flags shareId model
|
||||
]
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@ import Api.Model.ShareVerifyResult exposing (ShareVerifyResult)
|
||||
import Comp.SharePasswordForm
|
||||
import Comp.UrlCopy
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Http
|
||||
|
||||
|
||||
@ -37,12 +38,14 @@ type alias Model =
|
||||
, pageError : PageError
|
||||
, attachMenuOpen : Bool
|
||||
, visibleAttach : Int
|
||||
, uiSettings : UiSettings
|
||||
}
|
||||
|
||||
|
||||
type Msg
|
||||
= VerifyResp (Result Http.Error ShareVerifyResult)
|
||||
| GetItemResp (Result Http.Error ItemDetail)
|
||||
| UiSettingsResp (Result Http.Error UiSettings)
|
||||
| PasswordMsg Comp.SharePasswordForm.Msg
|
||||
| SelectActiveAttachment Int
|
||||
| ToggleSelectAttach
|
||||
@ -58,6 +61,7 @@ emptyModel vm =
|
||||
, pageError = PageErrorNone
|
||||
, attachMenuOpen = False
|
||||
, visibleAttach = 0
|
||||
, uiSettings = Data.UiSettings.defaults
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,7 +25,10 @@ update shareId itemId flags msg model =
|
||||
, viewMode = ViewLoading
|
||||
, verifyResult = res
|
||||
}
|
||||
, Api.itemDetailShare flags res.token itemId GetItemResp
|
||||
, Cmd.batch
|
||||
[ Api.itemDetailShare flags res.token itemId GetItemResp
|
||||
, Api.clientSettingsShare flags res.token UiSettingsResp
|
||||
]
|
||||
)
|
||||
|
||||
else if res.passwordRequired then
|
||||
@ -93,3 +96,9 @@ update shareId itemId flags msg model =
|
||||
Comp.UrlCopy.update lm
|
||||
in
|
||||
( model, cmd )
|
||||
|
||||
UiSettingsResp (Ok s) ->
|
||||
( { model | uiSettings = s }, Cmd.none )
|
||||
|
||||
UiSettingsResp (Err _) ->
|
||||
( model, Cmd.none )
|
||||
|
@ -16,7 +16,7 @@ import Comp.UrlCopy
|
||||
import Data.Fields
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Icons as Icons
|
||||
import Data.ItemTemplate as IT exposing (ItemTemplate)
|
||||
import Data.ItemTemplate as IT
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
@ -33,7 +33,7 @@ import Util.String
|
||||
|
||||
|
||||
viewSidebar : Texts -> Bool -> Flags -> UiSettings -> String -> String -> Model -> Html Msg
|
||||
viewSidebar texts visible flags settings shareId itemId model =
|
||||
viewSidebar texts visible flags _ shareId itemId model =
|
||||
div
|
||||
[ id "sidebar"
|
||||
, classList [ ( "hidden", not visible || model.viewMode /= ViewNormal ) ]
|
||||
@ -103,6 +103,7 @@ itemData texts flags model shareId itemId =
|
||||
div
|
||||
[ class "flex ml-2 mt-1 font-semibold hover:opacity-75"
|
||||
, class S.basicLabel
|
||||
, class (Data.UiSettings.tagColorString2 tag model.uiSettings)
|
||||
]
|
||||
[ i [ class "fa fa-tag mr-2" ] []
|
||||
, text tag.name
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
-}
|
||||
|
@ -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 = {};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user