docspell/modules/webapp/src/main/elm/Comp/BookmarkChooser.elm
2022-01-26 21:27:31 +01:00

220 lines
5.1 KiB
Elm

{-
Copyright 2020 Eike K. & Contributors
SPDX-License-Identifier: AGPL-3.0-or-later
-}
module Comp.BookmarkChooser exposing
( Model
, Msg
, Selection
, emptySelection
, getQueries
, init
, isEmpty
, isEmptySelection
, update
, view
, viewWith
)
import Api.Model.BookmarkedQuery exposing (BookmarkedQuery)
import Api.Model.ShareDetail exposing (ShareDetail)
import Data.Bookmarks exposing (AllBookmarks)
import Data.Icons as Icons
import Html exposing (Html, a, div, i, label, span, text)
import Html.Attributes exposing (class, classList, href)
import Html.Events exposing (onClick)
import Messages.Comp.BookmarkChooser exposing (Texts)
import Set exposing (Set)
type alias Model =
{ all : AllBookmarks
}
init : AllBookmarks -> Model
init all =
{ all = all
}
isEmpty : Model -> Bool
isEmpty model =
model.all == Data.Bookmarks.empty
type alias Selection =
{ bookmarks : Set String
, shares : Set String
}
emptySelection : Selection
emptySelection =
{ bookmarks = Set.empty, shares = Set.empty }
isEmptySelection : Selection -> Bool
isEmptySelection sel =
sel == emptySelection
type Kind
= Bookmark
| Share
type Msg
= Toggle Kind String
getQueries : Model -> Selection -> List BookmarkedQuery
getQueries model sel =
let
member set bm =
Set.member bm.id set
filterBookmarks f bms =
List.filter f bms |> List.map identity
in
List.concat
[ filterBookmarks (member sel.bookmarks) model.all.bookmarks
, List.map shareToBookmark model.all.shares
|> List.filter (member sel.shares)
]
--- Update
update : Msg -> Model -> Selection -> ( Model, Selection )
update msg model current =
let
toggle name set =
if Set.member name set then
Set.remove name set
else
Set.insert name set
in
case msg of
Toggle kind id ->
case kind of
Bookmark ->
( model, { current | bookmarks = toggle id current.bookmarks } )
Share ->
( model, { current | shares = toggle id current.shares } )
--- View
type alias ViewSettings =
{ showUser : Bool
, showCollective : Bool
, showShares : Bool
}
viewWith : ViewSettings -> Texts -> Model -> Selection -> Html Msg
viewWith cfg texts model selection =
let
( user, coll ) =
List.partition .personal model.all.bookmarks
in
div [ class "flex flex-col" ]
[ userBookmarks cfg.showUser texts user selection
, collBookmarks cfg.showCollective texts coll selection
, shares cfg.showShares texts model selection
]
view : Texts -> Model -> Selection -> Html Msg
view =
viewWith { showUser = True, showCollective = True, showShares = True }
titleDiv : String -> Html msg
titleDiv label =
div [ class "text-sm opacity-75 py-0.5 italic" ]
[ text label
]
userBookmarks : Bool -> Texts -> List BookmarkedQuery -> Selection -> Html Msg
userBookmarks visible texts model sel =
div
[ class "mb-2"
, classList [ ( "hidden", model == [] || not visible ) ]
]
[ titleDiv texts.userLabel
, div [ class "flex flex-col space-y-2 md:space-y-1" ]
(List.map (mkItem "fa fa-bookmark" sel Bookmark) model)
]
collBookmarks : Bool -> Texts -> List BookmarkedQuery -> Selection -> Html Msg
collBookmarks visible texts model sel =
div
[ class "mb-2"
, classList [ ( "hidden", [] == model || not visible ) ]
]
[ titleDiv texts.collectiveLabel
, div [ class "flex flex-col space-y-2 md:space-y-1" ]
(List.map (mkItem "fa fa-bookmark font-light" sel Bookmark) model)
]
shares : Bool -> Texts -> Model -> Selection -> Html Msg
shares visible texts model sel =
let
bms =
List.map shareToBookmark model.all.shares
in
div
[ class ""
, classList [ ( "hidden", List.isEmpty bms || not visible ) ]
]
[ titleDiv texts.shareLabel
, div [ class "flex flex-col space-y-2 md:space-y-1" ]
(List.map (mkItem Icons.share sel Share) bms)
]
mkItem : String -> Selection -> Kind -> BookmarkedQuery -> Html Msg
mkItem icon sel kind bm =
a
[ class "flex flex-row items-center rounded px-1 py-1 hover:bg-blue-100 dark:hover:bg-slate-600"
, href "#"
, onClick (Toggle kind bm.id)
]
[ if isSelected sel kind bm.id then
i [ class "fa fa-check" ] []
else
i [ class icon ] []
, span [ class "ml-2" ] [ text bm.name ]
]
isSelected : Selection -> Kind -> String -> Bool
isSelected sel kind id =
Set.member id <|
case kind of
Bookmark ->
sel.bookmarks
Share ->
sel.shares
shareToBookmark : ShareDetail -> BookmarkedQuery
shareToBookmark share =
BookmarkedQuery share.id (Maybe.withDefault "-" share.name) share.name share.query False 0