mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-04-04 10:29:34 +00:00
parent
05843876cc
commit
1eb1db730c
@ -12,10 +12,9 @@ module Comp.ItemCard exposing
|
||||
, ViewConfig
|
||||
, init
|
||||
, update
|
||||
, view2
|
||||
, view
|
||||
)
|
||||
|
||||
import Api
|
||||
import Api.Model.AttachmentLight exposing (AttachmentLight)
|
||||
import Api.Model.HighlightEntry exposing (HighlightEntry)
|
||||
import Api.Model.ItemLight exposing (ItemLight)
|
||||
@ -24,6 +23,7 @@ import Data.Direction
|
||||
import Data.Fields
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Icons as Icons
|
||||
import Data.ItemArrange exposing (ItemArrange)
|
||||
import Data.ItemSelection exposing (ItemSelection)
|
||||
import Data.ItemTemplate as IT
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
@ -52,6 +52,7 @@ type Msg
|
||||
| ToggleSelectItem (Set String) String
|
||||
| ItemDDMsg DD.Msg
|
||||
| SetLinkTarget LinkTarget
|
||||
| ToggleRowOpen String
|
||||
|
||||
|
||||
type alias ViewConfig =
|
||||
@ -61,6 +62,8 @@ type alias ViewConfig =
|
||||
, previewUrlFallback : ItemLight -> String
|
||||
, attachUrl : AttachmentLight -> String
|
||||
, detailPage : ItemLight -> Page
|
||||
, isRowOpen : Bool
|
||||
, arrange : ItemArrange
|
||||
}
|
||||
|
||||
|
||||
@ -69,6 +72,7 @@ type alias UpdateResult =
|
||||
, dragModel : DD.Model
|
||||
, selection : ItemSelection
|
||||
, linkTarget : LinkTarget
|
||||
, toggleRow : Maybe String
|
||||
}
|
||||
|
||||
|
||||
@ -112,12 +116,15 @@ currentPosition model item =
|
||||
update : DD.Model -> Msg -> Model -> UpdateResult
|
||||
update ddm msg model =
|
||||
case msg of
|
||||
ToggleRowOpen id ->
|
||||
UpdateResult model ddm Data.ItemSelection.Inactive LinkNone (Just id)
|
||||
|
||||
ItemDDMsg lm ->
|
||||
let
|
||||
ddd =
|
||||
DD.update lm ddm
|
||||
in
|
||||
UpdateResult model ddd.model Data.ItemSelection.Inactive LinkNone
|
||||
UpdateResult model ddd.model Data.ItemSelection.Inactive LinkNone Nothing
|
||||
|
||||
ToggleSelectItem ids id ->
|
||||
let
|
||||
@ -128,7 +135,7 @@ update ddm msg model =
|
||||
else
|
||||
Set.insert id ids
|
||||
in
|
||||
UpdateResult model ddm (Data.ItemSelection.Active newSet) LinkNone
|
||||
UpdateResult model ddm (Data.ItemSelection.Active newSet) LinkNone Nothing
|
||||
|
||||
CyclePreview item ->
|
||||
let
|
||||
@ -142,17 +149,28 @@ update ddm msg model =
|
||||
ddm
|
||||
Data.ItemSelection.Inactive
|
||||
LinkNone
|
||||
Nothing
|
||||
|
||||
SetLinkTarget target ->
|
||||
UpdateResult model ddm Data.ItemSelection.Inactive target
|
||||
UpdateResult model ddm Data.ItemSelection.Inactive target Nothing
|
||||
|
||||
|
||||
|
||||
--- View2
|
||||
|
||||
|
||||
view2 : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> ItemLight -> Html Msg
|
||||
view2 texts cfg settings flags model item =
|
||||
view : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> ItemLight -> Html Msg
|
||||
view texts cfg settings flags model item =
|
||||
case cfg.arrange of
|
||||
Data.ItemArrange.List ->
|
||||
viewRow texts cfg settings flags model item
|
||||
|
||||
Data.ItemArrange.Cards ->
|
||||
viewCard texts cfg settings flags model item
|
||||
|
||||
|
||||
viewRow : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> ItemLight -> Html Msg
|
||||
viewRow texts cfg settings flags model item =
|
||||
let
|
||||
isCreated =
|
||||
item.state == "created"
|
||||
@ -170,19 +188,304 @@ view2 texts cfg settings flags model item =
|
||||
else
|
||||
""
|
||||
|
||||
attachCount =
|
||||
List.length item.attachments
|
||||
|
||||
rowOpen =
|
||||
cfg.isRowOpen
|
||||
|
||||
mkAttachUrl attach =
|
||||
Data.UiSettings.pdfUrl settings flags (cfg.attachUrl attach)
|
||||
|
||||
mainAttach =
|
||||
currentAttachment model item
|
||||
|
||||
attachUrl =
|
||||
Maybe.map mkAttachUrl mainAttach
|
||||
|> Maybe.withDefault "/api/v1/sec/attachment/none"
|
||||
|
||||
fieldHidden f =
|
||||
Data.UiSettings.fieldHidden settings f
|
||||
|
||||
cardAction =
|
||||
case cfg.selection of
|
||||
Data.ItemSelection.Inactive ->
|
||||
[ Page.href (cfg.detailPage item)
|
||||
expandCollapseLink =
|
||||
a
|
||||
[ classList
|
||||
[ ( "my-auto flex text-lg w-4 text-left w-1", not rowOpen )
|
||||
, ( "flex w-full block text-xl bg-gray-50 dark:bg-bluegray-700 mb-2 rounded ", rowOpen )
|
||||
, ( "invisible", isSelected cfg item.id )
|
||||
]
|
||||
, href "#"
|
||||
, onClick (ToggleRowOpen item.id)
|
||||
]
|
||||
[ if rowOpen then
|
||||
i [ class "fa fa-caret-down pl-1" ] []
|
||||
|
||||
Data.ItemSelection.Active ids ->
|
||||
[ onClick (ToggleSelectItem ids item.id)
|
||||
, href "#"
|
||||
else
|
||||
i [ class "fa fa-caret-right" ] []
|
||||
]
|
||||
|
||||
titleTemplate =
|
||||
settings.cardTitleTemplate.template
|
||||
|
||||
subtitleTemplate =
|
||||
settings.cardSubtitleTemplate.template
|
||||
|
||||
dirIcon =
|
||||
i
|
||||
[ class (Data.Direction.iconFromMaybe2 item.direction)
|
||||
, class "mr-2 w-4 text-center"
|
||||
, classList [ ( "hidden", fieldHidden Data.Fields.Direction ) ]
|
||||
, IT.render IT.direction (templateCtx texts) item |> title
|
||||
]
|
||||
[]
|
||||
|
||||
newIcon =
|
||||
i
|
||||
[ class "fa fa-exclamation-circle mr-1"
|
||||
, class cardColor
|
||||
, title texts.new
|
||||
, classList [ ( "hidden", not isCreated ) ]
|
||||
]
|
||||
[]
|
||||
|
||||
trashIcon =
|
||||
i
|
||||
[ class Icons.trash
|
||||
, class "mr-1"
|
||||
, classList [ ( "hidden", not isDeleted ) ]
|
||||
]
|
||||
[]
|
||||
|
||||
dueDateLong =
|
||||
IT.render IT.dueDateLong (templateCtx texts) item
|
||||
|
||||
selectedDimmer =
|
||||
div
|
||||
[ classList
|
||||
[ ( "hidden", not (isSelected cfg item.id) )
|
||||
]
|
||||
, class S.dimmerRow
|
||||
]
|
||||
[ div [ class "text-2xl font-bold text-blue-100 hover:text-blue-200 dark:text-lightblue-300 dark:hover:text-lightblue-200" ]
|
||||
[ a
|
||||
(mkCardAction texts cfg settings item)
|
||||
[ i [ class "fa fa-check-circle" ] []
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
cardAction =
|
||||
mkCardAction texts cfg settings item
|
||||
in
|
||||
div
|
||||
([ classList [ ( "border border-gray-800 border-dashed dark:border-lightblue-500", isMultiSelectMode cfg ) ]
|
||||
, class "flex flex-col border-b pb-1 dark:border-bluegray-600 ds-item-row relative "
|
||||
, class cfg.extraClasses
|
||||
, id item.id
|
||||
]
|
||||
++ DD.draggable ItemDDMsg item.id
|
||||
)
|
||||
[ div
|
||||
[ class "h-14 flex flex-row space-x-1 justify-items-start truncate"
|
||||
, classList [ ( "hidden", rowOpen ) ]
|
||||
]
|
||||
[ div [ class "flex flex-row mr-1" ]
|
||||
[ expandCollapseLink
|
||||
, div
|
||||
[ class "flex pt-0.5 w-12"
|
||||
, classList [ ( "hidden", fieldHidden Data.Fields.PreviewImage ) ]
|
||||
]
|
||||
[ previewImage2 texts cfg settings model item
|
||||
]
|
||||
]
|
||||
, div [ class "flex flex-grow flex-col truncate text-left" ]
|
||||
[ div
|
||||
[ class "truncate w-full text-lg pointer font-medium"
|
||||
]
|
||||
[ trashIcon
|
||||
, newIcon
|
||||
, i
|
||||
[ class Icons.dueDate2
|
||||
, class "mr-1"
|
||||
, title (texts.dueOn ++ " " ++ dueDateLong)
|
||||
, classList [ ( "hidden", item.dueDate == Nothing ) ]
|
||||
]
|
||||
[]
|
||||
, a (href "#" :: cardAction)
|
||||
[ IT.render titleTemplate (templateCtx texts) item |> text
|
||||
]
|
||||
, a
|
||||
[ classList [ ( "hidden", List.length item.attachments == 1 ) ]
|
||||
, class "ml-2 opacity-50 text-xs hover:opacity-75"
|
||||
, title texts.cycleAttachments
|
||||
, href "#"
|
||||
, onClick (CyclePreview item)
|
||||
]
|
||||
[ currentPosition model item
|
||||
|> String.fromInt
|
||||
|> text
|
||||
, text "/"
|
||||
, text (attachCount |> String.fromInt)
|
||||
]
|
||||
]
|
||||
, div
|
||||
[ class "opacity-75 truncate flex flex-row items-center"
|
||||
, classList
|
||||
[ ( "hidden", IT.render subtitleTemplate (templateCtx texts) item == "" )
|
||||
]
|
||||
]
|
||||
[ div [ class "flex mr-2 flex-grow items-center" ]
|
||||
[ dirIcon
|
||||
, IT.render subtitleTemplate (templateCtx texts) item |> text
|
||||
]
|
||||
, div [ class "opacity-90" ]
|
||||
[ mainTagsAndFields2 settings "flex truncate overflow-hidden flex-nowrap text-xs justify-start hidden md:flex" item
|
||||
]
|
||||
]
|
||||
]
|
||||
, div [ class "flex items-end" ]
|
||||
[ a
|
||||
[ class S.secondaryBasicButtonPlain
|
||||
, class "px-2 py-1 border rounded "
|
||||
, href attachUrl
|
||||
, target "_blank"
|
||||
, title texts.openAttachmentFile
|
||||
]
|
||||
[ i [ class "fa fa-eye" ] []
|
||||
]
|
||||
, a
|
||||
[ class S.secondaryBasicButtonPlain
|
||||
, class "px-2 py-1 border rounded ml-2"
|
||||
, Page.href (cfg.detailPage item)
|
||||
, title texts.gotoDetail
|
||||
]
|
||||
[ i [ class "fa fa-edit" ] []
|
||||
]
|
||||
]
|
||||
]
|
||||
, div
|
||||
[ class "flex flex-col py-1"
|
||||
, classList [ ( "hidden", not rowOpen ) ]
|
||||
]
|
||||
[ expandCollapseLink
|
||||
, div [ class "flex flex-col sm:flex-row ml-2" ]
|
||||
[ div
|
||||
[ class "flex max-w-sm flex-col max-h-96 sm:max-h-full"
|
||||
, classList [ ( "hidden", fieldHidden Data.Fields.PreviewImage ) ]
|
||||
]
|
||||
[ previewImage2 texts cfg settings model item
|
||||
, previewMenu2 texts settings flags cfg model item (currentAttachment model item)
|
||||
]
|
||||
, div [ class "flex flex-grow flex-col ml-2 text-base" ]
|
||||
[ h3 [ class "text-xl tracking-wide font-bold" ]
|
||||
[ newIcon
|
||||
, trashIcon
|
||||
, IT.render titleTemplate (templateCtx texts) item |> text
|
||||
]
|
||||
, h4 [ class "opacity-75 font-normal mb-3" ]
|
||||
[ dirIcon
|
||||
, IT.render subtitleTemplate (templateCtx texts) item |> text
|
||||
]
|
||||
, div [ class "space-y-1 mb-3" ]
|
||||
[ div
|
||||
[ classList
|
||||
[ ( "hidden"
|
||||
, fieldHidden Data.Fields.CorrOrg
|
||||
&& fieldHidden Data.Fields.CorrPerson
|
||||
)
|
||||
]
|
||||
, title texts.basics.correspondent
|
||||
]
|
||||
(Icons.correspondentIcon2 "mr-2 w-4 text-center"
|
||||
:: Comp.LinkTarget.makeCorrLink item [ ( "hover:opacity-75", True ) ] SetLinkTarget
|
||||
)
|
||||
, div
|
||||
[ classList
|
||||
[ ( "hidden"
|
||||
, fieldHidden Data.Fields.ConcPerson
|
||||
&& fieldHidden Data.Fields.ConcEquip
|
||||
)
|
||||
]
|
||||
, title texts.basics.concerning
|
||||
]
|
||||
(Icons.concernedIcon2 "mr-2 w-4 text-center"
|
||||
:: Comp.LinkTarget.makeConcLink item [ ( "hover:opacity-75", True ) ] SetLinkTarget
|
||||
)
|
||||
, div
|
||||
[ classList
|
||||
[ ( "hidden", fieldHidden Data.Fields.Folder )
|
||||
]
|
||||
, class "hover:opacity-60"
|
||||
, title texts.basics.folder
|
||||
]
|
||||
[ Icons.folderIcon2 "mr-2"
|
||||
, Comp.LinkTarget.makeFolderLink item
|
||||
[ ( "hover:opacity-60", True ) ]
|
||||
SetLinkTarget
|
||||
]
|
||||
, div
|
||||
[ classList
|
||||
[ ( "hidden", fieldHidden Data.Fields.Date ) ]
|
||||
]
|
||||
[ Icons.dateIcon2 "mr-2"
|
||||
, IT.render IT.dateLong (templateCtx texts) item
|
||||
|> Util.String.withDefault "-"
|
||||
|> text
|
||||
]
|
||||
, div
|
||||
[ classList
|
||||
[ ( "hidden", fieldHidden Data.Fields.DueDate ) ]
|
||||
]
|
||||
[ Icons.dueDateIcon2 "mr-2"
|
||||
, dueDateLong
|
||||
|> Util.String.withDefault "-"
|
||||
|> text
|
||||
]
|
||||
, div
|
||||
[ classList
|
||||
[ ( "hidden", fieldHidden Data.Fields.SourceName ) ]
|
||||
]
|
||||
[ Icons.sourceIcon2 "mr-2"
|
||||
, Comp.LinkTarget.makeSourceLink
|
||||
[ ( "hover:opacity-60", True ) ]
|
||||
SetLinkTarget
|
||||
(IT.render IT.source (templateCtx texts) item)
|
||||
]
|
||||
]
|
||||
, mainTagsAndFields2 settings "justify-start text-sm" item
|
||||
, notesContent2 settings item
|
||||
]
|
||||
]
|
||||
]
|
||||
, fulltextResultsContent2 item
|
||||
, selectedDimmer
|
||||
]
|
||||
|
||||
|
||||
viewCard : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> ItemLight -> Html Msg
|
||||
viewCard texts cfg settings flags model item =
|
||||
let
|
||||
isCreated =
|
||||
item.state == "created"
|
||||
|
||||
isDeleted =
|
||||
item.state == "deleted"
|
||||
|
||||
cardColor =
|
||||
if isCreated then
|
||||
"text-blue-500 dark:text-lightblue-500"
|
||||
|
||||
else if isDeleted then
|
||||
"text-red-600 dark:text-orange-600"
|
||||
|
||||
else
|
||||
""
|
||||
|
||||
cardAction =
|
||||
mkCardAction texts cfg settings item
|
||||
|
||||
fieldHidden f =
|
||||
Data.UiSettings.fieldHidden settings f
|
||||
|
||||
selectedDimmer =
|
||||
div
|
||||
@ -215,7 +518,7 @@ view2 texts cfg settings flags model item =
|
||||
[]
|
||||
|
||||
else
|
||||
[ previewImage2 cfg settings cardAction model item
|
||||
[ previewImage2 texts cfg settings model item
|
||||
]
|
||||
)
|
||||
++ [ mainContent2 texts cardAction cardColor isCreated isDeleted settings cfg item
|
||||
@ -228,10 +531,37 @@ view2 texts cfg settings flags model item =
|
||||
)
|
||||
|
||||
|
||||
mkCardAction : Texts -> ViewConfig -> UiSettings -> ItemLight -> List (Attribute Msg)
|
||||
mkCardAction texts cfg settings item =
|
||||
case cfg.selection of
|
||||
Data.ItemSelection.Inactive ->
|
||||
case cfg.arrange of
|
||||
Data.ItemArrange.List ->
|
||||
if cfg.isRowOpen then
|
||||
[ Page.href (cfg.detailPage item)
|
||||
, title texts.gotoDetail
|
||||
]
|
||||
|
||||
else
|
||||
[ onClick (ToggleRowOpen item.id)
|
||||
, href "#"
|
||||
]
|
||||
|
||||
Data.ItemArrange.Cards ->
|
||||
[ Page.href (cfg.detailPage item)
|
||||
, title texts.gotoDetail
|
||||
]
|
||||
|
||||
Data.ItemSelection.Active ids ->
|
||||
[ onClick (ToggleSelectItem ids item.id)
|
||||
, href "#"
|
||||
]
|
||||
|
||||
|
||||
fulltextResultsContent2 : ItemLight -> Html Msg
|
||||
fulltextResultsContent2 item =
|
||||
div
|
||||
[ class "ds-card-search-hl flex flex-col text-sm px-2 bg-yellow-50 dark:bg-indigo-800 dark:bg-opacity-60 "
|
||||
[ class "ds-card-search-hl flex flex-col text-sm px-2 bg-yellow-50 dark:bg-indigo-800 dark:bg-opacity-10 bg-opacity-50"
|
||||
, classList
|
||||
[ ( "hidden", item.highlighting == [] )
|
||||
]
|
||||
@ -391,13 +721,13 @@ mainContent2 texts _ cardColor isCreated isDeleted settings _ item =
|
||||
, IT.render subtitlePattern (templateCtx texts) item |> text
|
||||
]
|
||||
, div [ class "" ]
|
||||
[ mainTagsAndFields2 settings item
|
||||
[ mainTagsAndFields2 settings "justify-end text-xs" item
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
mainTagsAndFields2 : UiSettings -> ItemLight -> Html Msg
|
||||
mainTagsAndFields2 settings item =
|
||||
mainTagsAndFields2 : UiSettings -> String -> ItemLight -> Html Msg
|
||||
mainTagsAndFields2 settings extraCss item =
|
||||
let
|
||||
fieldHidden f =
|
||||
Data.UiSettings.fieldHidden settings f
|
||||
@ -441,15 +771,16 @@ mainTagsAndFields2 settings item =
|
||||
in
|
||||
div
|
||||
[ classList
|
||||
[ ( "flex flex-row items-center flex-wrap justify-end text-xs font-medium my-1", True )
|
||||
[ ( "flex flex-row items-center flex-wrap font-medium", True )
|
||||
, ( "hidden", hideTags && hideFields )
|
||||
]
|
||||
, class extraCss
|
||||
]
|
||||
(renderFields ++ renderTags)
|
||||
|
||||
|
||||
previewImage2 : ViewConfig -> UiSettings -> List (Attribute Msg) -> Model -> ItemLight -> Html Msg
|
||||
previewImage2 cfg settings cardAction model item =
|
||||
previewImage2 : Texts -> ViewConfig -> UiSettings -> Model -> ItemLight -> Html Msg
|
||||
previewImage2 texts cfg settings model item =
|
||||
let
|
||||
mainAttach =
|
||||
currentAttachment model item
|
||||
@ -457,18 +788,37 @@ previewImage2 cfg settings cardAction model item =
|
||||
previewUrl =
|
||||
Maybe.map cfg.previewUrl mainAttach
|
||||
|> Maybe.withDefault (cfg.previewUrlFallback item)
|
||||
|
||||
isCardView =
|
||||
case cfg.arrange of
|
||||
Data.ItemArrange.List ->
|
||||
False
|
||||
|
||||
Data.ItemArrange.Cards ->
|
||||
True
|
||||
|
||||
isRowOpen =
|
||||
cfg.isRowOpen
|
||||
|
||||
isListView =
|
||||
not isCardView
|
||||
in
|
||||
a
|
||||
([ class "overflow-hidden block bg-gray-50 dark:bg-bluegray-700 dark:bg-opacity-40 border-gray-400 dark:hover:border-bluegray-500 rounded-t-lg"
|
||||
, class (Data.UiSettings.cardPreviewSize2 settings)
|
||||
([ class "overflow-hidden block bg-gray-50 dark:bg-bluegray-700 dark:bg-opacity-40 border-gray-400 dark:hover:border-bluegray-500 w-full"
|
||||
, classList
|
||||
[ ( "rounded-t-lg", isCardView )
|
||||
, ( Data.UiSettings.cardPreviewSize2 settings, isCardView && not isRowOpen )
|
||||
]
|
||||
]
|
||||
++ cardAction
|
||||
++ mkCardAction texts cfg settings item
|
||||
)
|
||||
[ img
|
||||
[ class "preview-image mx-auto pt-1"
|
||||
[ class "preview-image mx-auto"
|
||||
, classList
|
||||
[ ( "rounded-t-lg w-full -mt-1", settings.cardPreviewFullWidth )
|
||||
, ( Data.UiSettings.cardPreviewSize2 settings, not settings.cardPreviewFullWidth )
|
||||
[ ( "rounded-t-lg w-full -mt-1", settings.cardPreviewFullWidth && isCardView )
|
||||
, ( Data.UiSettings.cardPreviewSize2 settings, not settings.cardPreviewFullWidth && isCardView )
|
||||
, ( "h-12", isListView && not isRowOpen )
|
||||
, ( "border-t border-r border-l dark:border-bluegray-600", isListView && isRowOpen )
|
||||
]
|
||||
, src previewUrl
|
||||
]
|
||||
@ -514,8 +864,28 @@ previewMenu2 texts settings flags cfg model item mainAttach =
|
||||
[ Icons.dueDateIcon2 "mr-2"
|
||||
, text (" " ++ dueDate)
|
||||
]
|
||||
|
||||
isCardView =
|
||||
case cfg.arrange of
|
||||
Data.ItemArrange.List ->
|
||||
False
|
||||
|
||||
Data.ItemArrange.Cards ->
|
||||
True
|
||||
|
||||
isRowOpen =
|
||||
cfg.isRowOpen
|
||||
|
||||
isListView =
|
||||
not isCardView
|
||||
in
|
||||
div [ class "px-2 py-1 flex flex-row flex-wrap bg-gray-50 dark:bg-bluegray-700 dark:bg-opacity-40 border-0 rounded-b-lg md:text-sm" ]
|
||||
div
|
||||
[ class "px-2 py-1 flex flex-row flex-wrap bg-gray-50 dark:bg-bluegray-700 dark:bg-opacity-40 rounded-b-lg md:text-sm"
|
||||
, classList
|
||||
[ ( "border-0", isCardView || not isRowOpen )
|
||||
, ( "border-b border-l border-r dark:border-bluegray-600", isListView && isRowOpen )
|
||||
]
|
||||
]
|
||||
[ a
|
||||
[ class S.secondaryBasicButtonPlain
|
||||
, class "px-2 py-1 border rounded "
|
||||
@ -587,7 +957,7 @@ renderHighlightEntry2 entry =
|
||||
in
|
||||
div [ class "content" ]
|
||||
(div [ class "font-semibold" ]
|
||||
[ i [ class "fa fa-caret-right mr-1 " ] []
|
||||
[ i [ class "fa fa-file font-thin mr-1 " ] []
|
||||
, text (entry.name ++ ":")
|
||||
]
|
||||
:: List.map
|
||||
|
@ -14,7 +14,7 @@ module Comp.ItemCardList exposing
|
||||
, prevItem
|
||||
, update
|
||||
, updateDrag
|
||||
, view2
|
||||
, view
|
||||
)
|
||||
|
||||
import Api.Model.AttachmentLight exposing (AttachmentLight)
|
||||
@ -24,6 +24,7 @@ import Api.Model.ItemLightList exposing (ItemLightList)
|
||||
import Comp.ItemCard
|
||||
import Comp.LinkTarget exposing (LinkTarget)
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.ItemArrange exposing (ItemArrange)
|
||||
import Data.ItemSelection exposing (ItemSelection)
|
||||
import Data.Items
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
@ -32,6 +33,7 @@ import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Messages.Comp.ItemCardList exposing (Texts)
|
||||
import Page exposing (Page(..))
|
||||
import Set exposing (Set)
|
||||
import Styles as S
|
||||
import Util.ItemDragDrop as DD
|
||||
import Util.List
|
||||
@ -73,13 +75,9 @@ prevItem model id =
|
||||
--- Update
|
||||
|
||||
|
||||
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, LinkTarget )
|
||||
update : Flags -> Msg -> Model -> UpdateResult
|
||||
update flags msg model =
|
||||
let
|
||||
res =
|
||||
updateDrag DD.init flags msg model
|
||||
in
|
||||
( res.model, res.cmd, res.linkTarget )
|
||||
updateDrag DD.init flags msg model
|
||||
|
||||
|
||||
type alias UpdateResult =
|
||||
@ -88,6 +86,7 @@ type alias UpdateResult =
|
||||
, dragModel : DD.Model
|
||||
, selection : ItemSelection
|
||||
, linkTarget : LinkTarget
|
||||
, toggleOpenRow : Maybe String
|
||||
}
|
||||
|
||||
|
||||
@ -109,6 +108,7 @@ updateDrag dm _ msg model =
|
||||
dm
|
||||
Data.ItemSelection.Inactive
|
||||
Comp.LinkTarget.LinkNone
|
||||
Nothing
|
||||
|
||||
AddResults list ->
|
||||
if list.groups == [] then
|
||||
@ -117,6 +117,7 @@ updateDrag dm _ msg model =
|
||||
dm
|
||||
Data.ItemSelection.Inactive
|
||||
Comp.LinkTarget.LinkNone
|
||||
Nothing
|
||||
|
||||
else
|
||||
let
|
||||
@ -128,6 +129,7 @@ updateDrag dm _ msg model =
|
||||
dm
|
||||
Data.ItemSelection.Inactive
|
||||
Comp.LinkTarget.LinkNone
|
||||
Nothing
|
||||
|
||||
ItemCardMsg item lm ->
|
||||
let
|
||||
@ -146,6 +148,7 @@ updateDrag dm _ msg model =
|
||||
result.dragModel
|
||||
result.selection
|
||||
result.linkTarget
|
||||
result.toggleRow
|
||||
|
||||
RemoveItem id ->
|
||||
UpdateResult { model | results = removeItemById id model.results }
|
||||
@ -153,6 +156,7 @@ updateDrag dm _ msg model =
|
||||
dm
|
||||
Data.ItemSelection.Inactive
|
||||
Comp.LinkTarget.LinkNone
|
||||
Nothing
|
||||
|
||||
|
||||
|
||||
@ -166,22 +170,78 @@ type alias ViewConfig =
|
||||
, previewUrlFallback : ItemLight -> String
|
||||
, attachUrl : AttachmentLight -> String
|
||||
, detailPage : ItemLight -> Page
|
||||
, arrange : ItemArrange
|
||||
, showGroups : Bool
|
||||
, rowOpen : String -> Bool
|
||||
}
|
||||
|
||||
|
||||
view2 : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> Html Msg
|
||||
view2 texts cfg settings flags model =
|
||||
div
|
||||
[ classList
|
||||
[ ( "ds-item-list", True )
|
||||
, ( "ds-multi-select-mode", isMultiSelectMode cfg )
|
||||
view : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> Html Msg
|
||||
view texts cfg settings flags model =
|
||||
case cfg.arrange of
|
||||
Data.ItemArrange.Cards ->
|
||||
viewCards texts cfg settings flags model
|
||||
|
||||
Data.ItemArrange.List ->
|
||||
viewList texts cfg settings flags model
|
||||
|
||||
|
||||
viewList : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> Html Msg
|
||||
viewList texts cfg settings flags model =
|
||||
let
|
||||
items =
|
||||
Data.Items.unwrapGroups model.results.groups
|
||||
|
||||
listingCss =
|
||||
"grid grid-cols-1 space-y-1"
|
||||
in
|
||||
if cfg.showGroups then
|
||||
div [ class listingCss ]
|
||||
(List.map (viewGroup texts model cfg settings flags) model.results.groups)
|
||||
|
||||
else
|
||||
div [ class listingCss ]
|
||||
(List.map (viewItem texts model cfg settings flags) items)
|
||||
|
||||
|
||||
itemContainerCss : ViewConfig -> String
|
||||
itemContainerCss cfg =
|
||||
case cfg.arrange of
|
||||
Data.ItemArrange.Cards ->
|
||||
"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-2"
|
||||
|
||||
Data.ItemArrange.List ->
|
||||
"flex flex-col space-y-1"
|
||||
|
||||
|
||||
viewCards : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> Html Msg
|
||||
viewCards texts cfg settings flags model =
|
||||
let
|
||||
items =
|
||||
Data.Items.unwrapGroups model.results.groups
|
||||
in
|
||||
if cfg.showGroups then
|
||||
div
|
||||
[ classList
|
||||
[ ( "ds-item-list", True )
|
||||
, ( "ds-multi-select-mode", isMultiSelectMode cfg )
|
||||
]
|
||||
]
|
||||
]
|
||||
(List.map (viewGroup2 texts model cfg settings flags) model.results.groups)
|
||||
(List.map (viewGroup texts model cfg settings flags) model.results.groups)
|
||||
|
||||
else
|
||||
div
|
||||
[ class "ds-item-list"
|
||||
, class (itemContainerCss cfg)
|
||||
, classList
|
||||
[ ( "ds-multi-select-mode", isMultiSelectMode cfg )
|
||||
]
|
||||
]
|
||||
(List.map (viewItem texts model cfg settings flags) items)
|
||||
|
||||
|
||||
viewGroup2 : Texts -> Model -> ViewConfig -> UiSettings -> Flags -> ItemLightGroup -> Html Msg
|
||||
viewGroup2 texts model cfg settings flags group =
|
||||
viewGroup : Texts -> Model -> ViewConfig -> UiSettings -> Flags -> ItemLightGroup -> Html Msg
|
||||
viewGroup texts model cfg settings flags group =
|
||||
div [ class "ds-item-group" ]
|
||||
[ div
|
||||
[ class "flex py-1 mt-2 mb-2 flex flex-row items-center"
|
||||
@ -205,13 +265,13 @@ viewGroup2 texts model cfg settings flags group =
|
||||
]
|
||||
[]
|
||||
]
|
||||
, div [ class "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-2" ]
|
||||
(List.map (viewItem2 texts model cfg settings flags) group.items)
|
||||
, div [ class (itemContainerCss cfg) ]
|
||||
(List.map (viewItem texts model cfg settings flags) group.items)
|
||||
]
|
||||
|
||||
|
||||
viewItem2 : Texts -> Model -> ViewConfig -> UiSettings -> Flags -> ItemLight -> Html Msg
|
||||
viewItem2 texts model cfg settings flags item =
|
||||
viewItem : Texts -> Model -> ViewConfig -> UiSettings -> Flags -> ItemLight -> Html Msg
|
||||
viewItem texts model cfg settings flags item =
|
||||
let
|
||||
currentClass =
|
||||
if cfg.current == Just item.id then
|
||||
@ -220,15 +280,31 @@ viewItem2 texts model cfg settings flags item =
|
||||
else
|
||||
""
|
||||
|
||||
itemClass =
|
||||
case cfg.arrange of
|
||||
Data.ItemArrange.List ->
|
||||
" mb-1"
|
||||
|
||||
Data.ItemArrange.Cards ->
|
||||
""
|
||||
|
||||
vvcfg =
|
||||
Comp.ItemCard.ViewConfig cfg.selection currentClass cfg.previewUrl cfg.previewUrlFallback cfg.attachUrl cfg.detailPage
|
||||
{ selection = cfg.selection
|
||||
, extraClasses = currentClass ++ itemClass
|
||||
, previewUrl = cfg.previewUrl
|
||||
, previewUrlFallback = cfg.previewUrlFallback
|
||||
, attachUrl = cfg.attachUrl
|
||||
, detailPage = cfg.detailPage
|
||||
, isRowOpen = cfg.rowOpen item.id
|
||||
, arrange = cfg.arrange
|
||||
}
|
||||
|
||||
cardModel =
|
||||
Dict.get item.id model.itemCards
|
||||
|> Maybe.withDefault Comp.ItemCard.init
|
||||
|
||||
cardHtml =
|
||||
Comp.ItemCard.view2 texts.itemCard vvcfg settings flags cardModel item
|
||||
Comp.ItemCard.view texts.itemCard vvcfg settings flags cardModel item
|
||||
in
|
||||
Html.map (ItemCardMsg item) cardHtml
|
||||
|
||||
|
@ -130,12 +130,12 @@ view texts settings model =
|
||||
[ if isDeleted then
|
||||
div
|
||||
[ classList
|
||||
[ ( "text-red-500 dark:text-orange-600 text-4xl", True )
|
||||
[ ( " text-4xl", True )
|
||||
, ( "hidden", not isDeleted )
|
||||
]
|
||||
, title texts.basics.deleted
|
||||
]
|
||||
[ i [ class "mr-2 fa fa-trash-alt" ] []
|
||||
[ Icons.trashIcon "mr-2"
|
||||
]
|
||||
|
||||
else
|
||||
|
@ -72,6 +72,8 @@ module Data.Icons exposing
|
||||
, tagIcon2
|
||||
, tags2
|
||||
, tagsIcon2
|
||||
, trash
|
||||
, trashIcon
|
||||
)
|
||||
|
||||
import Data.CustomFieldType exposing (CustomFieldType)
|
||||
@ -81,6 +83,20 @@ import Svg
|
||||
import Svg.Attributes as SA
|
||||
|
||||
|
||||
trash : String
|
||||
trash =
|
||||
"fa fa-trash-alt text-red-500 dark:text-orange-600"
|
||||
|
||||
|
||||
trashIcon : String -> Html msg
|
||||
trashIcon classes =
|
||||
i
|
||||
[ class classes
|
||||
, class trash
|
||||
]
|
||||
[]
|
||||
|
||||
|
||||
share : String
|
||||
share =
|
||||
"fa fa-share-alt"
|
||||
|
36
modules/webapp/src/main/elm/Data/ItemArrange.elm
Normal file
36
modules/webapp/src/main/elm/Data/ItemArrange.elm
Normal file
@ -0,0 +1,36 @@
|
||||
{-
|
||||
Copyright 2020 Eike K. & Contributors
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
-}
|
||||
|
||||
|
||||
module Data.ItemArrange exposing (ItemArrange(..), asString, fromString)
|
||||
|
||||
|
||||
type ItemArrange
|
||||
= Cards
|
||||
| List
|
||||
|
||||
|
||||
asString : ItemArrange -> String
|
||||
asString arr =
|
||||
case arr of
|
||||
Cards ->
|
||||
"cards"
|
||||
|
||||
List ->
|
||||
"list"
|
||||
|
||||
|
||||
fromString : String -> Maybe ItemArrange
|
||||
fromString str =
|
||||
case String.toLower str of
|
||||
"cards" ->
|
||||
Just Cards
|
||||
|
||||
"list" ->
|
||||
Just List
|
||||
|
||||
_ ->
|
||||
Nothing
|
@ -12,6 +12,7 @@ module Data.Items exposing
|
||||
, idSet
|
||||
, length
|
||||
, replaceIn
|
||||
, unwrapGroups
|
||||
)
|
||||
|
||||
import Api.Model.ItemLight exposing (ItemLight)
|
||||
@ -27,6 +28,11 @@ flatten list =
|
||||
List.concatMap .items list.groups
|
||||
|
||||
|
||||
unwrapGroups : List ItemLightGroup -> List ItemLight
|
||||
unwrapGroups groups =
|
||||
List.concatMap .items groups
|
||||
|
||||
|
||||
concat : ItemLightList -> ItemLightList -> ItemLightList
|
||||
concat l0 l1 =
|
||||
let
|
||||
|
@ -36,6 +36,7 @@ import Data.BasicSize exposing (BasicSize)
|
||||
import Data.Color exposing (Color)
|
||||
import Data.Fields exposing (Field)
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.ItemArrange exposing (ItemArrange)
|
||||
import Data.ItemTemplate exposing (ItemTemplate)
|
||||
import Data.Pdf exposing (PdfMode)
|
||||
import Data.UiTheme exposing (UiTheme)
|
||||
@ -50,7 +51,7 @@ import Messages.UiLanguage exposing (UiLanguage)
|
||||
|
||||
|
||||
{-| Settings for the web ui. All fields should be optional, since it
|
||||
is loaded from local storage.
|
||||
is loaded from the server and mus be backward compatible.
|
||||
|
||||
Making fields optional, allows it to evolve without breaking previous
|
||||
versions. Also if a user is logged out, an empty object is send to
|
||||
@ -79,6 +80,8 @@ type alias StoredUiSettings =
|
||||
, sideMenuVisible : Bool
|
||||
, powerSearchEnabled : Bool
|
||||
, uiLang : Maybe String
|
||||
, itemSearchShowGroups : Bool
|
||||
, itemSearchArrange : Maybe String
|
||||
}
|
||||
|
||||
|
||||
@ -113,6 +116,8 @@ storedUiSettingsDecoder =
|
||||
|> P.optional "sideMenuVisible" Decode.bool False
|
||||
|> P.optional "powerSearchEnabled" Decode.bool False
|
||||
|> P.optional "uiLang" maybeString Nothing
|
||||
|> P.optional "itemSearchShowGroups" Decode.bool True
|
||||
|> P.optional "itemSearchArrange" maybeString Nothing
|
||||
|
||||
|
||||
storedUiSettingsEncode : StoredUiSettings -> Encode.Value
|
||||
@ -143,6 +148,8 @@ storedUiSettingsEncode value =
|
||||
, ( "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 )
|
||||
]
|
||||
|
||||
|
||||
@ -176,6 +183,8 @@ type alias UiSettings =
|
||||
, sideMenuVisible : Bool
|
||||
, powerSearchEnabled : Bool
|
||||
, uiLang : UiLanguage
|
||||
, itemSearchShowGroups : Bool
|
||||
, itemSearchArrange : ItemArrange
|
||||
}
|
||||
|
||||
|
||||
@ -248,6 +257,8 @@ defaults =
|
||||
, sideMenuVisible = True
|
||||
, powerSearchEnabled = False
|
||||
, uiLang = Messages.UiLanguage.English
|
||||
, itemSearchShowGroups = True
|
||||
, itemSearchArrange = Data.ItemArrange.Cards
|
||||
}
|
||||
|
||||
|
||||
@ -306,6 +317,10 @@ merge given fallback =
|
||||
, uiLang =
|
||||
Maybe.map Messages.fromIso2 given.uiLang
|
||||
|> Maybe.withDefault Messages.UiLanguage.English
|
||||
, itemSearchShowGroups = given.itemSearchShowGroups
|
||||
, itemSearchArrange =
|
||||
Maybe.andThen Data.ItemArrange.fromString given.itemSearchArrange
|
||||
|> Maybe.withDefault fallback.itemSearchArrange
|
||||
}
|
||||
|
||||
|
||||
@ -344,6 +359,8 @@ toStoredUiSettings settings =
|
||||
, sideMenuVisible = settings.sideMenuVisible
|
||||
, powerSearchEnabled = settings.powerSearchEnabled
|
||||
, uiLang = Just <| Messages.toIso2 settings.uiLang
|
||||
, itemSearchShowGroups = settings.itemSearchShowGroups
|
||||
, itemSearchArrange = Data.ItemArrange.asString settings.itemSearchArrange |> Just
|
||||
}
|
||||
|
||||
|
||||
|
@ -115,7 +115,7 @@ de =
|
||||
, addMoreFiles = "Diesem Dokument weitere Dateien anfügen"
|
||||
, confirmItemMetadata = "Metadaten bestätigen"
|
||||
, confirm = "Bestätige"
|
||||
, unconfirmItemMetadata = "Widerrufe Bestätigung"
|
||||
, unconfirmItemMetadata = "Widerrufe"
|
||||
, reprocessItem = "Das Dokument erneut verarbeiten"
|
||||
, deleteThisItem = "Das Dokument löschen"
|
||||
, undeleteThisItem = "Das Dokument wiederherstellen"
|
||||
|
@ -60,7 +60,7 @@ de =
|
||||
, chooseDirection = "Wähle eine Richtung…"
|
||||
, confirmUnconfirm = "Bestätige/Widerrufe Metadaten"
|
||||
, confirm = "Bestätige"
|
||||
, unconfirm = "Widerrufe Bestätigung"
|
||||
, unconfirm = "Widerrufe"
|
||||
, changeTagMode = "Wechsel den Änderungsmodus für Tags"
|
||||
, dueDateTab = "Fälligkeitsdatum"
|
||||
, direction = Messages.Data.Direction.de
|
||||
|
@ -49,6 +49,10 @@ type alias Texts =
|
||||
, nothingSelectedToShare : String
|
||||
, loadMore : String
|
||||
, thatsAll : String
|
||||
, showItemGroups : String
|
||||
, listView : String
|
||||
, tileView : String
|
||||
, expandCollapseRows : String
|
||||
}
|
||||
|
||||
|
||||
@ -83,6 +87,10 @@ gb =
|
||||
, nothingSelectedToShare = "Sharing everything doesn't work. You need to apply some criteria."
|
||||
, loadMore = "Load more…"
|
||||
, thatsAll = "That's all"
|
||||
, showItemGroups = "Group by month"
|
||||
, listView = "List view"
|
||||
, tileView = "Tile view"
|
||||
, expandCollapseRows = "Expand/Collapse all"
|
||||
}
|
||||
|
||||
|
||||
@ -117,4 +125,8 @@ de =
|
||||
, nothingSelectedToShare = "Alles kann nicht geteilt werden; es muss etwas gesucht werden."
|
||||
, loadMore = "Mehr laden…"
|
||||
, thatsAll = "Mehr gibt es nicht"
|
||||
, showItemGroups = "nach Monat gruppieren"
|
||||
, listView = "Listenansicht"
|
||||
, tileView = "Kachelansicht"
|
||||
, expandCollapseRows = "Alle ein-/ausklappen"
|
||||
}
|
||||
|
@ -26,6 +26,9 @@ type alias Texts =
|
||||
, powerSearchPlaceholder : String
|
||||
, normalSearchPlaceholder : String
|
||||
, extendedSearch : String
|
||||
, showItemGroups : String
|
||||
, listView : String
|
||||
, tileView : String
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +44,9 @@ gb =
|
||||
, powerSearchPlaceholder = "Extended search…"
|
||||
, extendedSearch = "Extended search query"
|
||||
, normalSearchPlaceholder = "Search…"
|
||||
, showItemGroups = "Group by month"
|
||||
, listView = "List view"
|
||||
, tileView = "Tile view"
|
||||
}
|
||||
|
||||
|
||||
@ -56,4 +62,7 @@ de =
|
||||
, powerSearchPlaceholder = "Erweiterte Suche…"
|
||||
, extendedSearch = "Erweiterte Suchanfrage"
|
||||
, normalSearchPlaceholder = "Suche…"
|
||||
, showItemGroups = "nach Monat gruppieren"
|
||||
, listView = "Listenansicht"
|
||||
, tileView = "Kachelansicht"
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ module Page.Home.Data exposing
|
||||
|
||||
import Api
|
||||
import Api.Model.BasicResult exposing (BasicResult)
|
||||
import Api.Model.ItemLight exposing (ItemLight)
|
||||
import Api.Model.ItemLightList exposing (ItemLightList)
|
||||
import Api.Model.SearchStats exposing (SearchStats)
|
||||
import Browser.Dom as Dom
|
||||
@ -40,6 +39,7 @@ import Comp.PowerSearchInput
|
||||
import Comp.PublishItems
|
||||
import Comp.SearchMenu
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.ItemArrange exposing (ItemArrange)
|
||||
import Data.ItemNav exposing (ItemNav)
|
||||
import Data.ItemQuery as Q
|
||||
import Data.Items
|
||||
@ -66,6 +66,8 @@ type alias Model =
|
||||
, scrollToCard : Maybe String
|
||||
, searchStats : SearchStats
|
||||
, powerSearchInput : Comp.PowerSearchInput.Model
|
||||
, viewMenuOpen : Bool
|
||||
, itemRowsOpen : Set String
|
||||
}
|
||||
|
||||
|
||||
@ -133,6 +135,8 @@ init flags viewMode =
|
||||
, viewMode = viewMode
|
||||
, searchStats = Api.Model.SearchStats.empty
|
||||
, powerSearchInput = Comp.PowerSearchInput.init
|
||||
, viewMenuOpen = False
|
||||
, itemRowsOpen = Set.empty
|
||||
}
|
||||
|
||||
|
||||
@ -230,6 +234,10 @@ type Msg
|
||||
| TogglePublishCurrentQueryView
|
||||
| PublishViewMsg Comp.PublishItems.Msg
|
||||
| RefreshView
|
||||
| ToggleViewMenu
|
||||
| ToggleShowGroups
|
||||
| ToggleArrange ItemArrange
|
||||
| ToggleExpandCollapseRows
|
||||
|
||||
|
||||
type SearchType
|
||||
|
@ -144,16 +144,40 @@ update mId key flags texts settings msg model =
|
||||
|
||||
( v, _ ) ->
|
||||
v
|
||||
|
||||
itemRows =
|
||||
case result.toggleOpenRow of
|
||||
Just rid ->
|
||||
if Set.member rid model.itemRowsOpen then
|
||||
Set.remove rid model.itemRowsOpen
|
||||
|
||||
else
|
||||
Set.insert rid model.itemRowsOpen
|
||||
|
||||
Nothing ->
|
||||
model.itemRowsOpen
|
||||
in
|
||||
withSub
|
||||
( { model
|
||||
| itemListModel = result.model
|
||||
, viewMode = nextView
|
||||
, itemRowsOpen = itemRows
|
||||
, dragDropData = DD.DragDropData result.dragModel Nothing
|
||||
}
|
||||
, Cmd.batch [ Cmd.map ItemCardListMsg result.cmd, searchMsg ]
|
||||
)
|
||||
|
||||
ToggleExpandCollapseRows ->
|
||||
let
|
||||
itemRows =
|
||||
if Set.isEmpty model.itemRowsOpen then
|
||||
Set.singleton "all"
|
||||
|
||||
else
|
||||
Set.empty
|
||||
in
|
||||
noSub ( { model | itemRowsOpen = itemRows, viewMenuOpen = False }, Cmd.none )
|
||||
|
||||
ItemSearchResp scroll (Ok list) ->
|
||||
let
|
||||
noff =
|
||||
@ -923,6 +947,29 @@ update mId key flags texts settings msg model =
|
||||
_ ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
ToggleViewMenu ->
|
||||
noSub ( { model | viewMenuOpen = not model.viewMenuOpen }, Cmd.none )
|
||||
|
||||
ToggleShowGroups ->
|
||||
let
|
||||
newSettings =
|
||||
{ settings | itemSearchShowGroups = not settings.itemSearchShowGroups }
|
||||
|
||||
cmd =
|
||||
Api.saveClientSettings flags newSettings (ClientSettingsSaveResp newSettings)
|
||||
in
|
||||
noSub ( { model | viewMenuOpen = False }, cmd )
|
||||
|
||||
ToggleArrange am ->
|
||||
let
|
||||
newSettings =
|
||||
{ settings | itemSearchArrange = am }
|
||||
|
||||
cmd =
|
||||
Api.saveClientSettings flags newSettings (ClientSettingsSaveResp newSettings)
|
||||
in
|
||||
noSub ( { model | viewMenuOpen = False }, cmd )
|
||||
|
||||
|
||||
|
||||
--- Helpers
|
||||
|
@ -19,7 +19,7 @@ import Comp.SearchMenu
|
||||
import Comp.SearchStatsView
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.Icons as Icons
|
||||
import Data.ItemQuery as Q
|
||||
import Data.ItemArrange
|
||||
import Data.ItemSelection
|
||||
import Data.SearchMode
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
@ -182,7 +182,7 @@ itemsBar texts flags settings model =
|
||||
SelectView svm ->
|
||||
[ editMenuBar texts model svm ]
|
||||
|
||||
PublishView query ->
|
||||
PublishView _ ->
|
||||
[ defaultMenuBar texts flags settings model ]
|
||||
|
||||
|
||||
@ -248,6 +248,12 @@ defaultMenuBar texts flags settings model =
|
||||
, Html.map PowerSearchMsg
|
||||
(Comp.PowerSearchInput.viewResult [] model.powerSearchInput)
|
||||
]
|
||||
|
||||
isCardView =
|
||||
settings.itemSearchArrange == Data.ItemArrange.Cards
|
||||
|
||||
isListView =
|
||||
settings.itemSearchArrange == Data.ItemArrange.List
|
||||
in
|
||||
MB.view
|
||||
{ end =
|
||||
@ -293,6 +299,61 @@ defaultMenuBar texts flags settings model =
|
||||
, ( "bg-gray-200 dark:bg-bluegray-600", selectActive model )
|
||||
]
|
||||
}
|
||||
, MB.Dropdown
|
||||
{ linkIcon = "fa fa-grip-vertical"
|
||||
, label = ""
|
||||
, linkClass =
|
||||
[ ( S.secondaryBasicButton, True )
|
||||
]
|
||||
, toggleMenu = ToggleViewMenu
|
||||
, menuOpen = model.viewMenuOpen
|
||||
, items =
|
||||
[ { icon =
|
||||
if settings.itemSearchShowGroups then
|
||||
i [ class "fa fa-check-square font-thin" ] []
|
||||
|
||||
else
|
||||
i [ class "fa fa-square font-thin" ] []
|
||||
, label = texts.showItemGroups
|
||||
, attrs =
|
||||
[ href "#"
|
||||
, onClick ToggleShowGroups
|
||||
]
|
||||
}
|
||||
, { icon =
|
||||
if isListView then
|
||||
i [ class "fa fa-check" ] []
|
||||
|
||||
else
|
||||
i [ class "fa fa-list" ] []
|
||||
, label = texts.listView
|
||||
, attrs =
|
||||
[ href "#"
|
||||
, onClick (ToggleArrange Data.ItemArrange.List)
|
||||
]
|
||||
}
|
||||
, { icon =
|
||||
if isCardView then
|
||||
i [ class "fa fa-check" ] []
|
||||
|
||||
else
|
||||
i [ class "fa fa-th-large" ] []
|
||||
, label = texts.tileView
|
||||
, attrs =
|
||||
[ href "#"
|
||||
, onClick (ToggleArrange Data.ItemArrange.Cards)
|
||||
]
|
||||
}
|
||||
, { icon = i [ class "fa fa-compress" ] []
|
||||
, label = texts.expandCollapseRows
|
||||
, attrs =
|
||||
[ href "#"
|
||||
, classList [ ( "hidden", not isListView ) ]
|
||||
, onClick ToggleExpandCollapseRows
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
, start =
|
||||
[ MB.CustomElement <|
|
||||
@ -469,13 +530,16 @@ itemCardList texts flags settings model =
|
||||
Api.itemBasePreviewURL item.id
|
||||
|
||||
viewCfg sel =
|
||||
Comp.ItemCardList.ViewConfig
|
||||
model.scrollToCard
|
||||
sel
|
||||
previewUrl
|
||||
previewUrlFallback
|
||||
(.id >> Api.fileURL)
|
||||
(.id >> ItemDetailPage)
|
||||
{ current = model.scrollToCard
|
||||
, selection = sel
|
||||
, previewUrl = previewUrl
|
||||
, previewUrlFallback = previewUrlFallback
|
||||
, attachUrl = .id >> Api.fileURL
|
||||
, detailPage = .id >> ItemDetailPage
|
||||
, arrange = settings.itemSearchArrange
|
||||
, showGroups = settings.itemSearchShowGroups
|
||||
, rowOpen = \id -> Set.member "all" model.itemRowsOpen || Set.member id model.itemRowsOpen
|
||||
}
|
||||
|
||||
itemViewCfg =
|
||||
case model.viewMode of
|
||||
@ -486,7 +550,7 @@ itemCardList texts flags settings model =
|
||||
viewCfg Data.ItemSelection.Inactive
|
||||
in
|
||||
[ Html.map ItemCardListMsg
|
||||
(Comp.ItemCardList.view2 texts.itemCardList
|
||||
(Comp.ItemCardList.view texts.itemCardList
|
||||
itemViewCfg
|
||||
settings
|
||||
flags
|
||||
|
@ -17,7 +17,10 @@ import Comp.PowerSearchInput
|
||||
import Comp.SearchMenu
|
||||
import Comp.SharePasswordForm
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.ItemArrange exposing (ItemArrange)
|
||||
import Http
|
||||
import Page.Home.Data exposing (Msg(..))
|
||||
import Set exposing (Set)
|
||||
import Util.Html exposing (KeyCode)
|
||||
|
||||
|
||||
@ -50,6 +53,12 @@ type alias Model =
|
||||
, initialized : Bool
|
||||
, contentSearch : Maybe String
|
||||
, searchMode : SearchBarMode
|
||||
, viewMode :
|
||||
{ menuOpen : Bool
|
||||
, showGroups : Bool
|
||||
, arrange : ItemArrange
|
||||
, rowsOpen : Set String
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -66,6 +75,12 @@ emptyModel flags =
|
||||
, initialized = False
|
||||
, contentSearch = Nothing
|
||||
, searchMode = SearchBarContent
|
||||
, viewMode =
|
||||
{ menuOpen = False
|
||||
, showGroups = True
|
||||
, arrange = Data.ItemArrange.Cards
|
||||
, rowsOpen = Set.empty
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -100,3 +115,6 @@ type Msg
|
||||
| ToggleSearchBar
|
||||
| SetContentSearch String
|
||||
| ContentSearchKey (Maybe KeyCode)
|
||||
| ToggleViewMenu
|
||||
| ToggleArrange ItemArrange
|
||||
| ToggleShowGroups
|
||||
|
@ -11,6 +11,7 @@ import Comp.Basic as B
|
||||
import Comp.MenuBar as MB
|
||||
import Comp.PowerSearchInput
|
||||
import Data.Flags exposing (Flags)
|
||||
import Data.ItemArrange
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onClick, onInput)
|
||||
@ -108,6 +109,43 @@ view texts flags model =
|
||||
, handler = onClick ResetSearch
|
||||
, attrs = [ href "#" ]
|
||||
}
|
||||
, MB.Dropdown
|
||||
{ linkIcon = "fa fa-grip-vertical"
|
||||
, label = ""
|
||||
, linkClass =
|
||||
[ ( S.secondaryBasicButton, True )
|
||||
]
|
||||
, toggleMenu = ToggleViewMenu
|
||||
, menuOpen = model.viewMode.menuOpen
|
||||
, items =
|
||||
[ { icon =
|
||||
if model.viewMode.showGroups then
|
||||
i [ class "fa fa-check-square font-thin" ] []
|
||||
|
||||
else
|
||||
i [ class "fa fa-square font-thin" ] []
|
||||
, label = texts.showItemGroups
|
||||
, attrs =
|
||||
[ href "#"
|
||||
, onClick ToggleShowGroups
|
||||
]
|
||||
}
|
||||
, { icon = i [ class "fa fa-list" ] []
|
||||
, label = texts.listView
|
||||
, attrs =
|
||||
[ href "#"
|
||||
, onClick (ToggleArrange Data.ItemArrange.List)
|
||||
]
|
||||
}
|
||||
, { icon = i [ class "fa fa-th-large" ] []
|
||||
, label = texts.tileView
|
||||
, attrs =
|
||||
[ href "#"
|
||||
, onClick (ToggleArrange Data.ItemArrange.Cards)
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
, rootClasses = "mb-2 pt-1 dark:bg-bluegray-700 items-center text-sm"
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ import Html.Attributes exposing (..)
|
||||
import Messages.Page.Share exposing (Texts)
|
||||
import Page exposing (Page(..))
|
||||
import Page.Share.Data exposing (Model, Msg(..))
|
||||
import Set
|
||||
|
||||
|
||||
view : Texts -> UiSettings -> Flags -> String -> Model -> Html Msg
|
||||
@ -29,9 +30,12 @@ view texts settings flags shareId model =
|
||||
, previewUrlFallback = \item -> Api.shareItemBasePreviewURL item.id
|
||||
, attachUrl = .id >> Api.shareFileURL
|
||||
, detailPage = \item -> ShareDetailPage shareId item.id
|
||||
, arrange = model.viewMode.arrange
|
||||
, showGroups = model.viewMode.showGroups
|
||||
, rowOpen = \id -> Set.member id model.viewMode.rowsOpen
|
||||
}
|
||||
in
|
||||
div []
|
||||
[ Html.map ItemListMsg
|
||||
(Comp.ItemCardList.view2 texts.itemCardList viewCfg settings flags model.itemListModel)
|
||||
(Comp.ItemCardList.view texts.itemCardList viewCfg settings flags model.itemListModel)
|
||||
]
|
||||
|
@ -19,6 +19,7 @@ import Data.ItemQuery as Q
|
||||
import Data.SearchMode
|
||||
import Data.UiSettings exposing (UiSettings)
|
||||
import Page.Share.Data exposing (..)
|
||||
import Set
|
||||
import Util.Html
|
||||
import Util.Maybe
|
||||
import Util.Update
|
||||
@ -161,16 +162,31 @@ update flags settings shareId msg model =
|
||||
|
||||
ItemListMsg lm ->
|
||||
let
|
||||
( im, ic, linkTarget ) =
|
||||
result =
|
||||
Comp.ItemCardList.update flags lm model.itemListModel
|
||||
|
||||
searchMsg =
|
||||
Maybe.map Util.Update.cmdUnit (linkTargetMsg linkTarget)
|
||||
Maybe.map Util.Update.cmdUnit (linkTargetMsg result.linkTarget)
|
||||
|> Maybe.withDefault Cmd.none
|
||||
|
||||
vm =
|
||||
model.viewMode
|
||||
|
||||
itemRows =
|
||||
case result.toggleOpenRow of
|
||||
Just rid ->
|
||||
if Set.member rid vm.rowsOpen then
|
||||
Set.remove rid vm.rowsOpen
|
||||
|
||||
else
|
||||
Set.insert rid vm.rowsOpen
|
||||
|
||||
Nothing ->
|
||||
vm.rowsOpen
|
||||
in
|
||||
noSub
|
||||
( { model | itemListModel = im }
|
||||
, Cmd.batch [ Cmd.map ItemListMsg ic, searchMsg ]
|
||||
( { model | itemListModel = result.model, viewMode = { vm | rowsOpen = itemRows } }
|
||||
, Cmd.batch [ Cmd.map ItemListMsg result.cmd, searchMsg ]
|
||||
)
|
||||
|
||||
ToggleSearchBar ->
|
||||
@ -196,6 +212,36 @@ update flags settings shareId msg model =
|
||||
ContentSearchKey _ ->
|
||||
noSub ( model, Cmd.none )
|
||||
|
||||
ToggleShowGroups ->
|
||||
let
|
||||
vm =
|
||||
model.viewMode
|
||||
|
||||
next =
|
||||
{ vm | showGroups = not vm.showGroups, menuOpen = False }
|
||||
in
|
||||
noSub ( { model | viewMode = next }, Cmd.none )
|
||||
|
||||
ToggleViewMenu ->
|
||||
let
|
||||
vm =
|
||||
model.viewMode
|
||||
|
||||
next =
|
||||
{ vm | menuOpen = not vm.menuOpen }
|
||||
in
|
||||
noSub ( { model | viewMode = next }, Cmd.none )
|
||||
|
||||
ToggleArrange am ->
|
||||
let
|
||||
vm =
|
||||
model.viewMode
|
||||
|
||||
next =
|
||||
{ vm | arrange = am, menuOpen = False }
|
||||
in
|
||||
noSub ( { model | viewMode = next }, Cmd.none )
|
||||
|
||||
|
||||
noSub : ( Model, Cmd Msg ) -> UpdateResult
|
||||
noSub ( m, c ) =
|
||||
|
@ -375,6 +375,11 @@ dimmerCard =
|
||||
" absolute top-0 left-0 w-full h-full bg-black bg-opacity-60 dark:bg-lightblue-900 dark:bg-opacity-60 z-30 flex flex-col items-center justify-center px-4 py-2 "
|
||||
|
||||
|
||||
dimmerRow : String
|
||||
dimmerRow =
|
||||
" absolute top-0 left-0 w-full h-full bg-black bg-opacity-50 dark:bg-lightblue-900 dark:bg-opacity-50 z-30 flex flex-row items-center px-1 py-2 "
|
||||
|
||||
|
||||
tableMain : String
|
||||
tableMain =
|
||||
"border-collapse table w-full"
|
||||
|
@ -16,6 +16,9 @@
|
||||
.ds-item-card.current {
|
||||
@apply shadow-lg dark:border-lightblue-600;
|
||||
}
|
||||
.ds-item-row.current {
|
||||
@apply bg-gray-200 bg-opacity-50 dark:bg-lightblue-600 dark:bg-opacity-10;
|
||||
}
|
||||
|
||||
.elm-datepicker--input {
|
||||
@apply pl-10 rounded w-full placeholder-gray-400 dark:text-bluegray-200 dark:border-bluegray-500;
|
||||
@ -188,6 +191,6 @@
|
||||
}
|
||||
|
||||
.ds-card-search-hl strong {
|
||||
@apply bg-lime-200 dark:bg-lightblue-700 italic font-bold px-1;
|
||||
@apply bg-lime-200 dark:bg-lightblue-700 italic font-bold px-1 bg-opacity-60 dark:bg-opacity-60;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user