mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-22 10:28:27 +00:00
Bookmark queries scoped to user or collective
This commit is contained in:
@ -6,7 +6,8 @@
|
||||
|
||||
|
||||
module Api exposing
|
||||
( addConcEquip
|
||||
( addBookmark
|
||||
, addConcEquip
|
||||
, addConcPerson
|
||||
, addCorrOrg
|
||||
, addCorrPerson
|
||||
@ -52,6 +53,7 @@ module Api exposing
|
||||
, disableOtp
|
||||
, fileURL
|
||||
, getAttachmentMeta
|
||||
, getBookmarks
|
||||
, getClientSettings
|
||||
, getCollective
|
||||
, getCollectiveSettings
|
||||
@ -120,6 +122,7 @@ module Api exposing
|
||||
, restoreAllItems
|
||||
, restoreItem
|
||||
, sampleEvent
|
||||
, saveBookmarks
|
||||
, saveClientSettings
|
||||
, searchShare
|
||||
, searchShareStats
|
||||
@ -260,6 +263,7 @@ import Api.Model.User exposing (User)
|
||||
import Api.Model.UserList exposing (UserList)
|
||||
import Api.Model.UserPass exposing (UserPass)
|
||||
import Api.Model.VersionInfo exposing (VersionInfo)
|
||||
import Data.BookmarkedQuery exposing (AllBookmarks, BookmarkedQuery, BookmarkedQueryDef, Bookmarks)
|
||||
import Data.ContactType exposing (ContactType)
|
||||
import Data.CustomFieldOrder exposing (CustomFieldOrder)
|
||||
import Data.EquipmentOrder exposing (EquipmentOrder)
|
||||
@ -2285,6 +2289,89 @@ saveClientSettings flags settings receive =
|
||||
|
||||
|
||||
|
||||
--- Query Bookmarks
|
||||
|
||||
|
||||
type alias BookmarkLocation =
|
||||
Data.BookmarkedQuery.Location
|
||||
|
||||
|
||||
bookmarkLocationUri : Flags -> BookmarkLocation -> String
|
||||
bookmarkLocationUri flags loc =
|
||||
case loc of
|
||||
Data.BookmarkedQuery.User ->
|
||||
flags.config.baseUrl ++ "/api/v1/sec/clientSettings/user/webClientBookmarks"
|
||||
|
||||
Data.BookmarkedQuery.Collective ->
|
||||
flags.config.baseUrl ++ "/api/v1/sec/clientSettings/collective/webClientBookmarks"
|
||||
|
||||
|
||||
getBookmarksTask : Flags -> BookmarkLocation -> Task.Task Http.Error Bookmarks
|
||||
getBookmarksTask flags loc =
|
||||
Http2.authTask
|
||||
{ method = "GET"
|
||||
, url = bookmarkLocationUri flags loc
|
||||
, account = getAccount flags
|
||||
, body = Http.emptyBody
|
||||
, resolver = Http2.jsonResolver Data.BookmarkedQuery.bookmarksDecoder
|
||||
, headers = []
|
||||
, timeout = Nothing
|
||||
}
|
||||
|
||||
|
||||
getBookmarksFor : Flags -> BookmarkLocation -> (Result Http.Error Bookmarks -> msg) -> Cmd msg
|
||||
getBookmarksFor flags loc receive =
|
||||
Task.attempt receive (getBookmarksTask flags loc)
|
||||
|
||||
|
||||
getBookmarks : Flags -> (Result Http.Error AllBookmarks -> msg) -> Cmd msg
|
||||
getBookmarks flags receive =
|
||||
let
|
||||
coll =
|
||||
getBookmarksTask flags Data.BookmarkedQuery.Collective
|
||||
|
||||
user =
|
||||
getBookmarksTask flags Data.BookmarkedQuery.User
|
||||
|
||||
combine bc bu =
|
||||
AllBookmarks bc bu
|
||||
in
|
||||
Task.map2 combine coll user
|
||||
|> Task.attempt receive
|
||||
|
||||
|
||||
saveBookmarksTask : Flags -> BookmarkLocation -> Bookmarks -> Task.Task Http.Error BasicResult
|
||||
saveBookmarksTask flags loc bookmarks =
|
||||
Http2.authTask
|
||||
{ method = "PUT"
|
||||
, url = bookmarkLocationUri flags loc
|
||||
, account = getAccount flags
|
||||
, body = Http.jsonBody (Data.BookmarkedQuery.bookmarksEncode bookmarks)
|
||||
, resolver = Http2.jsonResolver Api.Model.BasicResult.decoder
|
||||
, headers = []
|
||||
, timeout = Nothing
|
||||
}
|
||||
|
||||
|
||||
saveBookmarks : Flags -> Bookmarks -> BookmarkLocation -> (Result Http.Error BasicResult -> msg) -> Cmd msg
|
||||
saveBookmarks flags bookmarks loc receive =
|
||||
Task.attempt receive (saveBookmarksTask flags loc bookmarks)
|
||||
|
||||
|
||||
addBookmark : Flags -> BookmarkedQueryDef -> (Result Http.Error BasicResult -> msg) -> Cmd msg
|
||||
addBookmark flags model receive =
|
||||
let
|
||||
load =
|
||||
getBookmarksTask flags model.location
|
||||
|
||||
add current =
|
||||
Data.BookmarkedQuery.add model.query current
|
||||
|> saveBookmarksTask flags model.location
|
||||
in
|
||||
Task.andThen add load |> Task.attempt receive
|
||||
|
||||
|
||||
|
||||
--- OTP
|
||||
|
||||
|
||||
|
179
modules/webapp/src/main/elm/Comp/BookmarkQueryForm.elm
Normal file
179
modules/webapp/src/main/elm/Comp/BookmarkQueryForm.elm
Normal file
@ -0,0 +1,179 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Comp.BookmarkQueryForm exposing (Model, Msg, get, init, initQuery, update, view)
|
||||
|
||||
import Comp.Basic as B
|
||||
import Comp.PowerSearchInput
|
||||
import Data.BookmarkedQuery exposing (BookmarkedQueryDef, Location(..))
|
||||
import Data.Flags exposing (Flags)
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onCheck, onInput)
|
||||
import Messages.Comp.BookmarkQueryForm exposing (Texts)
|
||||
import Styles as S
|
||||
import Util.Maybe
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ name : Maybe String
|
||||
, queryModel : Comp.PowerSearchInput.Model
|
||||
, location : Location
|
||||
}
|
||||
|
||||
|
||||
initQuery : String -> ( Model, Cmd Msg )
|
||||
initQuery q =
|
||||
let
|
||||
res =
|
||||
Comp.PowerSearchInput.update
|
||||
(Comp.PowerSearchInput.setSearchString q)
|
||||
Comp.PowerSearchInput.init
|
||||
in
|
||||
( { name = Nothing
|
||||
, queryModel = res.model
|
||||
, location = User
|
||||
}
|
||||
, Cmd.batch
|
||||
[ Cmd.map QueryMsg res.cmd
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
init : ( Model, Cmd Msg )
|
||||
init =
|
||||
initQuery ""
|
||||
|
||||
|
||||
isValid : Model -> Bool
|
||||
isValid model =
|
||||
Comp.PowerSearchInput.isValid model.queryModel
|
||||
&& model.name
|
||||
/= Nothing
|
||||
|
||||
|
||||
get : Model -> Maybe BookmarkedQueryDef
|
||||
get model =
|
||||
let
|
||||
qStr =
|
||||
Maybe.withDefault "" model.queryModel.input
|
||||
in
|
||||
if isValid model then
|
||||
Just
|
||||
{ query =
|
||||
{ query = qStr
|
||||
, name = Maybe.withDefault "" model.name
|
||||
}
|
||||
, location = model.location
|
||||
}
|
||||
|
||||
else
|
||||
Nothing
|
||||
|
||||
|
||||
type Msg
|
||||
= SetName String
|
||||
| QueryMsg Comp.PowerSearchInput.Msg
|
||||
| SetLocation Location
|
||||
|
||||
|
||||
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Sub Msg )
|
||||
update _ msg model =
|
||||
case msg of
|
||||
SetName n ->
|
||||
( { model | name = Util.Maybe.fromString n }, Cmd.none, Sub.none )
|
||||
|
||||
SetLocation loc ->
|
||||
( { model | location = loc }, Cmd.none, Sub.none )
|
||||
|
||||
QueryMsg lm ->
|
||||
let
|
||||
res =
|
||||
Comp.PowerSearchInput.update lm model.queryModel
|
||||
in
|
||||
( { model | queryModel = res.model }
|
||||
, Cmd.map QueryMsg res.cmd
|
||||
, Sub.map QueryMsg res.subs
|
||||
)
|
||||
|
||||
|
||||
|
||||
--- View
|
||||
|
||||
|
||||
view : Texts -> Model -> Html Msg
|
||||
view texts model =
|
||||
let
|
||||
queryInput =
|
||||
div
|
||||
[ class "relative flex flex-grow flex-row" ]
|
||||
[ Html.map QueryMsg
|
||||
(Comp.PowerSearchInput.viewInput
|
||||
{ placeholder = texts.queryLabel
|
||||
, extraAttrs = []
|
||||
}
|
||||
model.queryModel
|
||||
)
|
||||
, Html.map QueryMsg
|
||||
(Comp.PowerSearchInput.viewResult [] model.queryModel)
|
||||
]
|
||||
in
|
||||
div
|
||||
[ class "flex flex-col" ]
|
||||
[ div [ class "mb-4" ]
|
||||
[ label
|
||||
[ for "sharename"
|
||||
, class S.inputLabel
|
||||
]
|
||||
[ text texts.basics.name
|
||||
, B.inputRequired
|
||||
]
|
||||
, input
|
||||
[ type_ "text"
|
||||
, onInput SetName
|
||||
, placeholder texts.basics.name
|
||||
, value <| Maybe.withDefault "" model.name
|
||||
, id "sharename"
|
||||
, class S.textInput
|
||||
]
|
||||
[]
|
||||
]
|
||||
, div [ class "flex flex-col mb-4 " ]
|
||||
[ label [ class "inline-flex items-center" ]
|
||||
[ input
|
||||
[ type_ "radio"
|
||||
, checked (model.location == User)
|
||||
, onCheck (\_ -> SetLocation User)
|
||||
, class S.radioInput
|
||||
]
|
||||
[]
|
||||
, span [ class "ml-2" ] [ text texts.userLocation ]
|
||||
, span [ class "ml-3 opacity-75 text-sm" ] [ text texts.userLocationText ]
|
||||
]
|
||||
, label [ class "inline-flex items-center" ]
|
||||
[ input
|
||||
[ type_ "radio"
|
||||
, checked (model.location == Collective)
|
||||
, class S.radioInput
|
||||
, onCheck (\_ -> SetLocation Collective)
|
||||
]
|
||||
[]
|
||||
, span [ class "ml-2" ] [ text texts.collectiveLocation ]
|
||||
, span [ class "ml-3 opacity-75 text-sm" ] [ text texts.collectiveLocationText ]
|
||||
]
|
||||
]
|
||||
, div [ class "mb-4" ]
|
||||
[ label
|
||||
[ for "sharequery"
|
||||
, class S.inputLabel
|
||||
]
|
||||
[ text texts.queryLabel
|
||||
, B.inputRequired
|
||||
]
|
||||
, queryInput
|
||||
]
|
||||
]
|
173
modules/webapp/src/main/elm/Comp/BookmarkQueryManage.elm
Normal file
173
modules/webapp/src/main/elm/Comp/BookmarkQueryManage.elm
Normal file
@ -0,0 +1,173 @@
|
||||
module Comp.BookmarkQueryManage exposing (..)
|
||||
|
||||
import Api
|
||||
import Api.Model.BasicResult exposing (BasicResult)
|
||||
import Comp.Basic as B
|
||||
import Comp.BookmarkQueryForm
|
||||
import Data.BookmarkedQuery exposing (BookmarkedQueryDef)
|
||||
import Data.Flags exposing (Flags)
|
||||
import Html exposing (Html, div, text)
|
||||
import Html.Attributes exposing (class, classList, href)
|
||||
import Html.Events exposing (onClick)
|
||||
import Http
|
||||
import Messages.Comp.BookmarkQueryManage exposing (Texts)
|
||||
import Styles as S
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ formModel : Comp.BookmarkQueryForm.Model
|
||||
, loading : Bool
|
||||
, formState : FormState
|
||||
}
|
||||
|
||||
|
||||
type FormState
|
||||
= FormStateNone
|
||||
| FormStateError Http.Error
|
||||
| FormStateSaveError String
|
||||
| FormStateInvalid
|
||||
| FormStateSaved
|
||||
|
||||
|
||||
init : String -> ( Model, Cmd Msg )
|
||||
init query =
|
||||
let
|
||||
( fm, fc ) =
|
||||
Comp.BookmarkQueryForm.initQuery query
|
||||
in
|
||||
( { formModel = fm
|
||||
, loading = False
|
||||
, formState = FormStateNone
|
||||
}
|
||||
, Cmd.map FormMsg fc
|
||||
)
|
||||
|
||||
|
||||
type Msg
|
||||
= Submit
|
||||
| Cancel
|
||||
| FormMsg Comp.BookmarkQueryForm.Msg
|
||||
| SaveResp (Result Http.Error BasicResult)
|
||||
|
||||
|
||||
|
||||
--- Update
|
||||
|
||||
|
||||
type FormResult
|
||||
= Submitted BookmarkedQueryDef
|
||||
| Cancelled
|
||||
| Done
|
||||
| None
|
||||
|
||||
|
||||
type alias UpdateResult =
|
||||
{ model : Model
|
||||
, cmd : Cmd Msg
|
||||
, sub : Sub Msg
|
||||
, outcome : FormResult
|
||||
}
|
||||
|
||||
|
||||
update : Flags -> Msg -> Model -> UpdateResult
|
||||
update flags msg model =
|
||||
let
|
||||
empty =
|
||||
{ model = model
|
||||
, cmd = Cmd.none
|
||||
, sub = Sub.none
|
||||
, outcome = None
|
||||
}
|
||||
in
|
||||
case msg of
|
||||
FormMsg lm ->
|
||||
let
|
||||
( fm, fc, fs ) =
|
||||
Comp.BookmarkQueryForm.update flags lm model.formModel
|
||||
in
|
||||
{ model = { model | formModel = fm }
|
||||
, cmd = Cmd.map FormMsg fc
|
||||
, sub = Sub.map FormMsg fs
|
||||
, outcome = None
|
||||
}
|
||||
|
||||
Submit ->
|
||||
case Comp.BookmarkQueryForm.get model.formModel of
|
||||
Just data ->
|
||||
{ empty | cmd = save flags data, outcome = Submitted data, model = { model | loading = True } }
|
||||
|
||||
Nothing ->
|
||||
{ empty | model = { model | formState = FormStateInvalid } }
|
||||
|
||||
Cancel ->
|
||||
{ model = model
|
||||
, cmd = Cmd.none
|
||||
, sub = Sub.none
|
||||
, outcome = Cancelled
|
||||
}
|
||||
|
||||
SaveResp (Ok res) ->
|
||||
if res.success then
|
||||
{ empty | model = { model | loading = False, formState = FormStateSaved }, outcome = Done }
|
||||
|
||||
else
|
||||
{ empty | model = { model | loading = False, formState = FormStateSaveError res.message } }
|
||||
|
||||
SaveResp (Err err) ->
|
||||
{ empty | model = { model | loading = False, formState = FormStateError err } }
|
||||
|
||||
|
||||
save : Flags -> BookmarkedQueryDef -> Cmd Msg
|
||||
save flags model =
|
||||
Api.addBookmark flags model SaveResp
|
||||
|
||||
|
||||
|
||||
--- View
|
||||
|
||||
|
||||
view : Texts -> Model -> Html Msg
|
||||
view texts model =
|
||||
div [ class "relative" ]
|
||||
[ B.loadingDimmer { label = "", active = model.loading }
|
||||
, Html.map FormMsg (Comp.BookmarkQueryForm.view texts.form model.formModel)
|
||||
, case model.formState of
|
||||
FormStateNone ->
|
||||
div [ class "hidden" ] []
|
||||
|
||||
FormStateError err ->
|
||||
div [ class S.errorMessage ]
|
||||
[ text <| texts.httpError err
|
||||
]
|
||||
|
||||
FormStateInvalid ->
|
||||
div [ class S.errorMessage ]
|
||||
[ text texts.formInvalid
|
||||
]
|
||||
|
||||
FormStateSaveError m ->
|
||||
div [ class S.errorMessage ]
|
||||
[ text m
|
||||
]
|
||||
|
||||
FormStateSaved ->
|
||||
div [ class S.successMessage ]
|
||||
[ text texts.saved
|
||||
]
|
||||
, div [ class "flex flex-row space-x-2 py-2" ]
|
||||
[ B.primaryButton
|
||||
{ label = texts.basics.submit
|
||||
, icon = "fa fa-save"
|
||||
, disabled = False
|
||||
, handler = onClick Submit
|
||||
, attrs = [ href "#" ]
|
||||
}
|
||||
, B.secondaryButton
|
||||
{ label = texts.basics.cancel
|
||||
, icon = "fa fa-times"
|
||||
, disabled = False
|
||||
, handler = onClick Cancel
|
||||
, attrs = [ href "#" ]
|
||||
}
|
||||
]
|
||||
]
|
114
modules/webapp/src/main/elm/Data/BookmarkedQuery.elm
Normal file
114
modules/webapp/src/main/elm/Data/BookmarkedQuery.elm
Normal file
@ -0,0 +1,114 @@
|
||||
module Data.BookmarkedQuery exposing
|
||||
( AllBookmarks
|
||||
, BookmarkedQuery
|
||||
, BookmarkedQueryDef
|
||||
, Bookmarks
|
||||
, Location(..)
|
||||
, add
|
||||
, bookmarksDecoder
|
||||
, bookmarksEncode
|
||||
, emptyBookmarks
|
||||
, exists
|
||||
, remove
|
||||
)
|
||||
|
||||
import Json.Decode as D
|
||||
import Json.Encode as E
|
||||
|
||||
|
||||
type Location
|
||||
= User
|
||||
| Collective
|
||||
|
||||
|
||||
type alias BookmarkedQuery =
|
||||
{ name : String
|
||||
, query : String
|
||||
}
|
||||
|
||||
|
||||
bookmarkedQueryDecoder : D.Decoder BookmarkedQuery
|
||||
bookmarkedQueryDecoder =
|
||||
D.map2 BookmarkedQuery
|
||||
(D.field "name" D.string)
|
||||
(D.field "query" D.string)
|
||||
|
||||
|
||||
bookmarkedQueryEncode : BookmarkedQuery -> E.Value
|
||||
bookmarkedQueryEncode bq =
|
||||
E.object
|
||||
[ ( "name", E.string bq.name )
|
||||
, ( "query", E.string bq.query )
|
||||
]
|
||||
|
||||
|
||||
type alias BookmarkedQueryDef =
|
||||
{ query : BookmarkedQuery
|
||||
, location : Location
|
||||
}
|
||||
|
||||
|
||||
type Bookmarks
|
||||
= Bookmarks (List BookmarkedQuery)
|
||||
|
||||
|
||||
emptyBookmarks : Bookmarks
|
||||
emptyBookmarks =
|
||||
Bookmarks []
|
||||
|
||||
|
||||
type alias AllBookmarks =
|
||||
{ collective : Bookmarks
|
||||
, user : Bookmarks
|
||||
}
|
||||
|
||||
|
||||
{-| Checks wether a bookmark of this name already exists.
|
||||
-}
|
||||
exists : String -> Bookmarks -> Bool
|
||||
exists name bookmarks =
|
||||
case bookmarks of
|
||||
Bookmarks list ->
|
||||
List.any (\b -> b.name == name) list
|
||||
|
||||
|
||||
remove : String -> Bookmarks -> Bookmarks
|
||||
remove name bookmarks =
|
||||
case bookmarks of
|
||||
Bookmarks list ->
|
||||
Bookmarks <| List.filter (\b -> b.name /= name) list
|
||||
|
||||
|
||||
sortByName : Bookmarks -> Bookmarks
|
||||
sortByName bm =
|
||||
case bm of
|
||||
Bookmarks all ->
|
||||
Bookmarks <| List.sortBy .name all
|
||||
|
||||
|
||||
add : BookmarkedQuery -> Bookmarks -> Bookmarks
|
||||
add query bookmarks =
|
||||
case remove query.name bookmarks of
|
||||
Bookmarks all ->
|
||||
sortByName (Bookmarks (query :: all))
|
||||
|
||||
|
||||
bookmarksDecoder : D.Decoder Bookmarks
|
||||
bookmarksDecoder =
|
||||
D.maybe
|
||||
(D.field "bookmarks"
|
||||
(D.list bookmarkedQueryDecoder
|
||||
|> D.map Bookmarks
|
||||
|> D.map sortByName
|
||||
)
|
||||
)
|
||||
|> D.map (Maybe.withDefault emptyBookmarks)
|
||||
|
||||
|
||||
bookmarksEncode : Bookmarks -> E.Value
|
||||
bookmarksEncode bookmarks =
|
||||
case bookmarks of
|
||||
Bookmarks all ->
|
||||
E.object
|
||||
[ ( "bookmarks", E.list bookmarkedQueryEncode all )
|
||||
]
|
@ -0,0 +1,46 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Messages.Comp.BookmarkQueryForm exposing
|
||||
( Texts
|
||||
, de
|
||||
, gb
|
||||
)
|
||||
|
||||
import Messages.Basics
|
||||
|
||||
|
||||
type alias Texts =
|
||||
{ basics : Messages.Basics.Texts
|
||||
, queryLabel : String
|
||||
, userLocation : String
|
||||
, userLocationText : String
|
||||
, collectiveLocation : String
|
||||
, collectiveLocationText : String
|
||||
}
|
||||
|
||||
|
||||
gb : Texts
|
||||
gb =
|
||||
{ basics = Messages.Basics.gb
|
||||
, queryLabel = "Query"
|
||||
, userLocation = "User scope"
|
||||
, userLocationText = "The bookmarked query is just for you"
|
||||
, collectiveLocation = "Collective scope"
|
||||
, collectiveLocationText = "The bookmarked query can be used and edited by all users"
|
||||
}
|
||||
|
||||
|
||||
de : Texts
|
||||
de =
|
||||
{ basics = Messages.Basics.de
|
||||
, queryLabel = "Abfrage"
|
||||
, userLocation = "Persönliches Bookmark"
|
||||
, userLocationText = "Der Bookmark ist nur für dich"
|
||||
, collectiveLocation = "Kollektiv-Bookmark"
|
||||
, collectiveLocationText = "Der Bookmark kann von allen Benutzer verwendet werden"
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Messages.Comp.BookmarkQueryManage exposing
|
||||
( Texts
|
||||
, de
|
||||
, gb
|
||||
)
|
||||
|
||||
import Http
|
||||
import Messages.Basics
|
||||
import Messages.Comp.BookmarkQueryForm
|
||||
import Messages.Comp.HttpError
|
||||
|
||||
|
||||
type alias Texts =
|
||||
{ basics : Messages.Basics.Texts
|
||||
, form : Messages.Comp.BookmarkQueryForm.Texts
|
||||
, httpError : Http.Error -> String
|
||||
, formInvalid : String
|
||||
, saved : String
|
||||
}
|
||||
|
||||
|
||||
gb : Texts
|
||||
gb =
|
||||
{ basics = Messages.Basics.gb
|
||||
, form = Messages.Comp.BookmarkQueryForm.gb
|
||||
, httpError = Messages.Comp.HttpError.gb
|
||||
, formInvalid = "Please correct errors in the form"
|
||||
, saved = "Bookmark saved"
|
||||
}
|
||||
|
||||
|
||||
de : Texts
|
||||
de =
|
||||
{ basics = Messages.Basics.de
|
||||
, form = Messages.Comp.BookmarkQueryForm.de
|
||||
, httpError = Messages.Comp.HttpError.de
|
||||
, formInvalid = "Bitte korrigiere das Formular"
|
||||
, saved = "Bookmark gespeichert"
|
||||
}
|
@ -12,6 +12,7 @@ module Messages.Page.Home exposing
|
||||
)
|
||||
|
||||
import Messages.Basics
|
||||
import Messages.Comp.BookmarkQueryManage
|
||||
import Messages.Comp.ItemCardList
|
||||
import Messages.Comp.ItemMerge
|
||||
import Messages.Comp.PublishItems
|
||||
@ -26,6 +27,7 @@ type alias Texts =
|
||||
, sideMenu : Messages.Page.HomeSideMenu.Texts
|
||||
, itemMerge : Messages.Comp.ItemMerge.Texts
|
||||
, publishItems : Messages.Comp.PublishItems.Texts
|
||||
, bookmarkManage : Messages.Comp.BookmarkQueryManage.Texts
|
||||
, contentSearch : String
|
||||
, searchInNames : String
|
||||
, selectModeTitle : String
|
||||
@ -46,6 +48,7 @@ type alias Texts =
|
||||
, mergeItemsTitle : Int -> String
|
||||
, publishItemsTitle : Int -> String
|
||||
, publishCurrentQueryTitle : String
|
||||
, shareResults : String
|
||||
, nothingSelectedToShare : String
|
||||
, loadMore : String
|
||||
, thatsAll : String
|
||||
@ -53,6 +56,8 @@ type alias Texts =
|
||||
, listView : String
|
||||
, tileView : String
|
||||
, expandCollapseRows : String
|
||||
, bookmarkQuery : String
|
||||
, nothingToBookmark : String
|
||||
}
|
||||
|
||||
|
||||
@ -64,6 +69,7 @@ gb =
|
||||
, sideMenu = Messages.Page.HomeSideMenu.gb
|
||||
, itemMerge = Messages.Comp.ItemMerge.gb
|
||||
, publishItems = Messages.Comp.PublishItems.gb
|
||||
, bookmarkManage = Messages.Comp.BookmarkQueryManage.gb
|
||||
, contentSearch = "Content search…"
|
||||
, searchInNames = "Search in names…"
|
||||
, selectModeTitle = "Select Mode"
|
||||
@ -84,6 +90,7 @@ gb =
|
||||
, mergeItemsTitle = \n -> "Merge " ++ String.fromInt n ++ " selected items"
|
||||
, publishItemsTitle = \n -> "Publish " ++ String.fromInt n ++ " selected items"
|
||||
, publishCurrentQueryTitle = "Publish current results"
|
||||
, shareResults = "Share Results"
|
||||
, nothingSelectedToShare = "Sharing everything doesn't work. You need to apply some criteria."
|
||||
, loadMore = "Load more…"
|
||||
, thatsAll = "That's all"
|
||||
@ -91,6 +98,8 @@ gb =
|
||||
, listView = "List view"
|
||||
, tileView = "Tile view"
|
||||
, expandCollapseRows = "Expand/Collapse all"
|
||||
, bookmarkQuery = "Bookmark query"
|
||||
, nothingToBookmark = "Nothing selected to bookmark"
|
||||
}
|
||||
|
||||
|
||||
@ -102,6 +111,7 @@ de =
|
||||
, sideMenu = Messages.Page.HomeSideMenu.de
|
||||
, itemMerge = Messages.Comp.ItemMerge.de
|
||||
, publishItems = Messages.Comp.PublishItems.de
|
||||
, bookmarkManage = Messages.Comp.BookmarkQueryManage.de
|
||||
, contentSearch = "Volltextsuche…"
|
||||
, searchInNames = "Suche in Namen…"
|
||||
, selectModeTitle = "Auswahlmodus"
|
||||
@ -122,6 +132,7 @@ de =
|
||||
, mergeItemsTitle = \n -> String.fromInt n ++ " gewählte Dokumente zusammenführen"
|
||||
, publishItemsTitle = \n -> String.fromInt n ++ " gewählte Dokumente publizieren"
|
||||
, publishCurrentQueryTitle = "Aktuelle Ansicht publizieren"
|
||||
, shareResults = "Ergebnisse teilen"
|
||||
, nothingSelectedToShare = "Alles kann nicht geteilt werden; es muss etwas gesucht werden."
|
||||
, loadMore = "Mehr laden…"
|
||||
, thatsAll = "Mehr gibt es nicht"
|
||||
@ -129,4 +140,6 @@ de =
|
||||
, listView = "Listenansicht"
|
||||
, tileView = "Kachelansicht"
|
||||
, expandCollapseRows = "Alle ein-/ausklappen"
|
||||
, bookmarkQuery = "Abfrage merken"
|
||||
, nothingToBookmark = "Keine Abfrage vorhanden"
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ module Page.Home.Data exposing
|
||||
, SearchType(..)
|
||||
, SelectActionMode(..)
|
||||
, SelectViewModel
|
||||
, TopWidgetModel(..)
|
||||
, ViewMode(..)
|
||||
, createQuery
|
||||
, doSearchCmd
|
||||
@ -30,6 +31,7 @@ import Api.Model.BasicResult exposing (BasicResult)
|
||||
import Api.Model.ItemLightList exposing (ItemLightList)
|
||||
import Api.Model.SearchStats exposing (SearchStats)
|
||||
import Browser.Dom as Dom
|
||||
import Comp.BookmarkQueryManage
|
||||
import Comp.ItemCardList
|
||||
import Comp.ItemDetail.FormChange exposing (FormChange)
|
||||
import Comp.ItemDetail.MultiEditMenu exposing (SaveNameState(..))
|
||||
@ -68,9 +70,15 @@ type alias Model =
|
||||
, powerSearchInput : Comp.PowerSearchInput.Model
|
||||
, viewMenuOpen : Bool
|
||||
, itemRowsOpen : Set String
|
||||
, topWidgetModel : TopWidgetModel
|
||||
}
|
||||
|
||||
|
||||
type TopWidgetModel
|
||||
= TopWidgetHidden
|
||||
| BookmarkQuery Comp.BookmarkQueryManage.Model
|
||||
|
||||
|
||||
type ConfirmModalValue
|
||||
= ConfirmReprocessItems
|
||||
| ConfirmDelete
|
||||
@ -137,6 +145,7 @@ init flags viewMode =
|
||||
, powerSearchInput = Comp.PowerSearchInput.init
|
||||
, viewMenuOpen = False
|
||||
, itemRowsOpen = Set.empty
|
||||
, topWidgetModel = TopWidgetHidden
|
||||
}
|
||||
|
||||
|
||||
@ -238,6 +247,8 @@ type Msg
|
||||
| ToggleShowGroups
|
||||
| ToggleArrange ItemArrange
|
||||
| ToggleExpandCollapseRows
|
||||
| ToggleBookmarkCurrentQueryView
|
||||
| BookmarkQueryMsg Comp.BookmarkQueryManage.Msg
|
||||
|
||||
|
||||
type SearchType
|
||||
|
@ -13,6 +13,7 @@ module Page.Home.Update exposing
|
||||
import Api
|
||||
import Api.Model.ItemLightList exposing (ItemLightList)
|
||||
import Browser.Navigation as Nav
|
||||
import Comp.BookmarkQueryManage
|
||||
import Comp.ItemCardList
|
||||
import Comp.ItemDetail.FormChange exposing (FormChange(..))
|
||||
import Comp.ItemDetail.MultiEditMenu exposing (SaveNameState(..))
|
||||
@ -927,6 +928,54 @@ update mId key flags texts settings msg model =
|
||||
Nothing ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
ToggleBookmarkCurrentQueryView ->
|
||||
case createQuery model of
|
||||
Just q ->
|
||||
case model.topWidgetModel of
|
||||
BookmarkQuery _ ->
|
||||
noSub ( { model | topWidgetModel = TopWidgetHidden, viewMenuOpen = False }, Cmd.none )
|
||||
|
||||
TopWidgetHidden ->
|
||||
let
|
||||
( qm, qc ) =
|
||||
Comp.BookmarkQueryManage.init (Q.render q)
|
||||
in
|
||||
noSub
|
||||
( { model | topWidgetModel = BookmarkQuery qm, viewMenuOpen = False }
|
||||
, Cmd.map BookmarkQueryMsg qc
|
||||
)
|
||||
|
||||
Nothing ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
BookmarkQueryMsg lm ->
|
||||
case model.topWidgetModel of
|
||||
BookmarkQuery bm ->
|
||||
let
|
||||
res =
|
||||
Comp.BookmarkQueryManage.update flags lm bm
|
||||
|
||||
nextModel =
|
||||
if
|
||||
res.outcome
|
||||
== Comp.BookmarkQueryManage.Cancelled
|
||||
|| res.outcome
|
||||
== Comp.BookmarkQueryManage.Done
|
||||
then
|
||||
TopWidgetHidden
|
||||
|
||||
else
|
||||
BookmarkQuery res.model
|
||||
in
|
||||
makeResult
|
||||
( { model | topWidgetModel = nextModel }
|
||||
, Cmd.map BookmarkQueryMsg res.cmd
|
||||
, Sub.map BookmarkQueryMsg res.sub
|
||||
)
|
||||
|
||||
TopWidgetHidden ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
PublishViewMsg lmsg ->
|
||||
case model.viewMode of
|
||||
PublishView inPM ->
|
||||
|
@ -9,6 +9,7 @@ module Page.Home.View2 exposing (viewContent, viewSidebar)
|
||||
|
||||
import Api
|
||||
import Comp.Basic as B
|
||||
import Comp.BookmarkQueryManage
|
||||
import Comp.ConfirmModal
|
||||
import Comp.ItemCardList
|
||||
import Comp.ItemMerge
|
||||
@ -103,7 +104,21 @@ mainView texts flags settings model =
|
||||
body
|
||||
|
||||
Nothing ->
|
||||
itemCardList texts flags settings model
|
||||
bookmarkQueryWidget texts settings flags model
|
||||
++ itemCardList texts flags settings model
|
||||
|
||||
|
||||
bookmarkQueryWidget : Texts -> UiSettings -> Flags -> Model -> List (Html Msg)
|
||||
bookmarkQueryWidget texts settings flags model =
|
||||
case model.topWidgetModel of
|
||||
BookmarkQuery m ->
|
||||
[ div [ class "px-2 mb-4 border-l border-r border-b dark:border-slate-600" ]
|
||||
[ Html.map BookmarkQueryMsg (Comp.BookmarkQueryManage.view texts.bookmarkManage m)
|
||||
]
|
||||
]
|
||||
|
||||
TopWidgetHidden ->
|
||||
[]
|
||||
|
||||
|
||||
itemPublishView : Texts -> UiSettings -> Flags -> SelectViewModel -> List (Html Msg)
|
||||
@ -354,7 +369,7 @@ defaultMenuBar texts flags settings model =
|
||||
]
|
||||
}
|
||||
, menuSep
|
||||
, { label = "Share Results"
|
||||
, { label = texts.shareResults
|
||||
, icon = Icons.shareIcon ""
|
||||
, disabled = createQuery model == Nothing
|
||||
, attrs =
|
||||
@ -372,6 +387,24 @@ defaultMenuBar texts flags settings model =
|
||||
onClick TogglePublishCurrentQueryView
|
||||
]
|
||||
}
|
||||
, { label = texts.bookmarkQuery
|
||||
, icon = i [ class "fa fa-bookmark" ] []
|
||||
, disabled = createQuery model == Nothing
|
||||
, attrs =
|
||||
[ title <|
|
||||
if createQuery model == Nothing then
|
||||
texts.nothingToBookmark
|
||||
|
||||
else
|
||||
texts.bookmarkQuery
|
||||
, href "#"
|
||||
, if createQuery model == Nothing then
|
||||
class ""
|
||||
|
||||
else
|
||||
onClick ToggleBookmarkCurrentQueryView
|
||||
]
|
||||
}
|
||||
, { label =
|
||||
if settings.cardPreviewFullWidth then
|
||||
texts.fullHeightPreviewTitle
|
||||
|
Reference in New Issue
Block a user