mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-06-22 10:28:27 +00:00
@ -12,10 +12,9 @@ module Comp.ItemCard exposing
|
|||||||
, ViewConfig
|
, ViewConfig
|
||||||
, init
|
, init
|
||||||
, update
|
, update
|
||||||
, view2
|
, view
|
||||||
)
|
)
|
||||||
|
|
||||||
import Api
|
|
||||||
import Api.Model.AttachmentLight exposing (AttachmentLight)
|
import Api.Model.AttachmentLight exposing (AttachmentLight)
|
||||||
import Api.Model.HighlightEntry exposing (HighlightEntry)
|
import Api.Model.HighlightEntry exposing (HighlightEntry)
|
||||||
import Api.Model.ItemLight exposing (ItemLight)
|
import Api.Model.ItemLight exposing (ItemLight)
|
||||||
@ -24,6 +23,7 @@ import Data.Direction
|
|||||||
import Data.Fields
|
import Data.Fields
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
import Data.Icons as Icons
|
import Data.Icons as Icons
|
||||||
|
import Data.ItemArrange exposing (ItemArrange)
|
||||||
import Data.ItemSelection exposing (ItemSelection)
|
import Data.ItemSelection exposing (ItemSelection)
|
||||||
import Data.ItemTemplate as IT
|
import Data.ItemTemplate as IT
|
||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
@ -52,6 +52,7 @@ type Msg
|
|||||||
| ToggleSelectItem (Set String) String
|
| ToggleSelectItem (Set String) String
|
||||||
| ItemDDMsg DD.Msg
|
| ItemDDMsg DD.Msg
|
||||||
| SetLinkTarget LinkTarget
|
| SetLinkTarget LinkTarget
|
||||||
|
| ToggleRowOpen String
|
||||||
|
|
||||||
|
|
||||||
type alias ViewConfig =
|
type alias ViewConfig =
|
||||||
@ -61,6 +62,8 @@ type alias ViewConfig =
|
|||||||
, previewUrlFallback : ItemLight -> String
|
, previewUrlFallback : ItemLight -> String
|
||||||
, attachUrl : AttachmentLight -> String
|
, attachUrl : AttachmentLight -> String
|
||||||
, detailPage : ItemLight -> Page
|
, detailPage : ItemLight -> Page
|
||||||
|
, isRowOpen : Bool
|
||||||
|
, arrange : ItemArrange
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -69,6 +72,7 @@ type alias UpdateResult =
|
|||||||
, dragModel : DD.Model
|
, dragModel : DD.Model
|
||||||
, selection : ItemSelection
|
, selection : ItemSelection
|
||||||
, linkTarget : LinkTarget
|
, linkTarget : LinkTarget
|
||||||
|
, toggleRow : Maybe String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -112,12 +116,15 @@ currentPosition model item =
|
|||||||
update : DD.Model -> Msg -> Model -> UpdateResult
|
update : DD.Model -> Msg -> Model -> UpdateResult
|
||||||
update ddm msg model =
|
update ddm msg model =
|
||||||
case msg of
|
case msg of
|
||||||
|
ToggleRowOpen id ->
|
||||||
|
UpdateResult model ddm Data.ItemSelection.Inactive LinkNone (Just id)
|
||||||
|
|
||||||
ItemDDMsg lm ->
|
ItemDDMsg lm ->
|
||||||
let
|
let
|
||||||
ddd =
|
ddd =
|
||||||
DD.update lm ddm
|
DD.update lm ddm
|
||||||
in
|
in
|
||||||
UpdateResult model ddd.model Data.ItemSelection.Inactive LinkNone
|
UpdateResult model ddd.model Data.ItemSelection.Inactive LinkNone Nothing
|
||||||
|
|
||||||
ToggleSelectItem ids id ->
|
ToggleSelectItem ids id ->
|
||||||
let
|
let
|
||||||
@ -128,7 +135,7 @@ update ddm msg model =
|
|||||||
else
|
else
|
||||||
Set.insert id ids
|
Set.insert id ids
|
||||||
in
|
in
|
||||||
UpdateResult model ddm (Data.ItemSelection.Active newSet) LinkNone
|
UpdateResult model ddm (Data.ItemSelection.Active newSet) LinkNone Nothing
|
||||||
|
|
||||||
CyclePreview item ->
|
CyclePreview item ->
|
||||||
let
|
let
|
||||||
@ -142,17 +149,28 @@ update ddm msg model =
|
|||||||
ddm
|
ddm
|
||||||
Data.ItemSelection.Inactive
|
Data.ItemSelection.Inactive
|
||||||
LinkNone
|
LinkNone
|
||||||
|
Nothing
|
||||||
|
|
||||||
SetLinkTarget target ->
|
SetLinkTarget target ->
|
||||||
UpdateResult model ddm Data.ItemSelection.Inactive target
|
UpdateResult model ddm Data.ItemSelection.Inactive target Nothing
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--- View2
|
--- View2
|
||||||
|
|
||||||
|
|
||||||
view2 : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> ItemLight -> Html Msg
|
view : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> ItemLight -> Html Msg
|
||||||
view2 texts cfg settings flags model item =
|
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
|
let
|
||||||
isCreated =
|
isCreated =
|
||||||
item.state == "created"
|
item.state == "created"
|
||||||
@ -170,19 +188,304 @@ view2 texts cfg settings flags model item =
|
|||||||
else
|
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 =
|
fieldHidden f =
|
||||||
Data.UiSettings.fieldHidden settings f
|
Data.UiSettings.fieldHidden settings f
|
||||||
|
|
||||||
cardAction =
|
expandCollapseLink =
|
||||||
case cfg.selection of
|
a
|
||||||
Data.ItemSelection.Inactive ->
|
[ classList
|
||||||
[ Page.href (cfg.detailPage item)
|
[ ( "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" ] []
|
||||||
|
|
||||||
|
else
|
||||||
|
i [ class "fa fa-caret-right" ] []
|
||||||
]
|
]
|
||||||
|
|
||||||
Data.ItemSelection.Active ids ->
|
titleTemplate =
|
||||||
[ onClick (ToggleSelectItem ids item.id)
|
settings.cardTitleTemplate.template
|
||||||
, href "#"
|
|
||||||
|
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 =
|
selectedDimmer =
|
||||||
div
|
div
|
||||||
@ -215,7 +518,7 @@ view2 texts cfg settings flags model item =
|
|||||||
[]
|
[]
|
||||||
|
|
||||||
else
|
else
|
||||||
[ previewImage2 cfg settings cardAction model item
|
[ previewImage2 texts cfg settings model item
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
++ [ mainContent2 texts cardAction cardColor isCreated isDeleted settings cfg 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 : ItemLight -> Html Msg
|
||||||
fulltextResultsContent2 item =
|
fulltextResultsContent2 item =
|
||||||
div
|
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
|
, classList
|
||||||
[ ( "hidden", item.highlighting == [] )
|
[ ( "hidden", item.highlighting == [] )
|
||||||
]
|
]
|
||||||
@ -391,13 +721,13 @@ mainContent2 texts _ cardColor isCreated isDeleted settings _ item =
|
|||||||
, IT.render subtitlePattern (templateCtx texts) item |> text
|
, IT.render subtitlePattern (templateCtx texts) item |> text
|
||||||
]
|
]
|
||||||
, div [ class "" ]
|
, div [ class "" ]
|
||||||
[ mainTagsAndFields2 settings item
|
[ mainTagsAndFields2 settings "justify-end text-xs" item
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
mainTagsAndFields2 : UiSettings -> ItemLight -> Html Msg
|
mainTagsAndFields2 : UiSettings -> String -> ItemLight -> Html Msg
|
||||||
mainTagsAndFields2 settings item =
|
mainTagsAndFields2 settings extraCss item =
|
||||||
let
|
let
|
||||||
fieldHidden f =
|
fieldHidden f =
|
||||||
Data.UiSettings.fieldHidden settings f
|
Data.UiSettings.fieldHidden settings f
|
||||||
@ -441,15 +771,16 @@ mainTagsAndFields2 settings item =
|
|||||||
in
|
in
|
||||||
div
|
div
|
||||||
[ classList
|
[ 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 )
|
, ( "hidden", hideTags && hideFields )
|
||||||
]
|
]
|
||||||
|
, class extraCss
|
||||||
]
|
]
|
||||||
(renderFields ++ renderTags)
|
(renderFields ++ renderTags)
|
||||||
|
|
||||||
|
|
||||||
previewImage2 : ViewConfig -> UiSettings -> List (Attribute Msg) -> Model -> ItemLight -> Html Msg
|
previewImage2 : Texts -> ViewConfig -> UiSettings -> Model -> ItemLight -> Html Msg
|
||||||
previewImage2 cfg settings cardAction model item =
|
previewImage2 texts cfg settings model item =
|
||||||
let
|
let
|
||||||
mainAttach =
|
mainAttach =
|
||||||
currentAttachment model item
|
currentAttachment model item
|
||||||
@ -457,18 +788,37 @@ previewImage2 cfg settings cardAction model item =
|
|||||||
previewUrl =
|
previewUrl =
|
||||||
Maybe.map cfg.previewUrl mainAttach
|
Maybe.map cfg.previewUrl mainAttach
|
||||||
|> Maybe.withDefault (cfg.previewUrlFallback item)
|
|> 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
|
in
|
||||||
a
|
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 "overflow-hidden block bg-gray-50 dark:bg-bluegray-700 dark:bg-opacity-40 border-gray-400 dark:hover:border-bluegray-500 w-full"
|
||||||
, class (Data.UiSettings.cardPreviewSize2 settings)
|
, classList
|
||||||
|
[ ( "rounded-t-lg", isCardView )
|
||||||
|
, ( Data.UiSettings.cardPreviewSize2 settings, isCardView && not isRowOpen )
|
||||||
]
|
]
|
||||||
++ cardAction
|
]
|
||||||
|
++ mkCardAction texts cfg settings item
|
||||||
)
|
)
|
||||||
[ img
|
[ img
|
||||||
[ class "preview-image mx-auto pt-1"
|
[ class "preview-image mx-auto"
|
||||||
, classList
|
, classList
|
||||||
[ ( "rounded-t-lg w-full -mt-1", settings.cardPreviewFullWidth )
|
[ ( "rounded-t-lg w-full -mt-1", settings.cardPreviewFullWidth && isCardView )
|
||||||
, ( Data.UiSettings.cardPreviewSize2 settings, not settings.cardPreviewFullWidth )
|
, ( 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
|
, src previewUrl
|
||||||
]
|
]
|
||||||
@ -514,8 +864,28 @@ previewMenu2 texts settings flags cfg model item mainAttach =
|
|||||||
[ Icons.dueDateIcon2 "mr-2"
|
[ Icons.dueDateIcon2 "mr-2"
|
||||||
, text (" " ++ dueDate)
|
, text (" " ++ dueDate)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
isCardView =
|
||||||
|
case cfg.arrange of
|
||||||
|
Data.ItemArrange.List ->
|
||||||
|
False
|
||||||
|
|
||||||
|
Data.ItemArrange.Cards ->
|
||||||
|
True
|
||||||
|
|
||||||
|
isRowOpen =
|
||||||
|
cfg.isRowOpen
|
||||||
|
|
||||||
|
isListView =
|
||||||
|
not isCardView
|
||||||
in
|
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
|
[ a
|
||||||
[ class S.secondaryBasicButtonPlain
|
[ class S.secondaryBasicButtonPlain
|
||||||
, class "px-2 py-1 border rounded "
|
, class "px-2 py-1 border rounded "
|
||||||
@ -587,7 +957,7 @@ renderHighlightEntry2 entry =
|
|||||||
in
|
in
|
||||||
div [ class "content" ]
|
div [ class "content" ]
|
||||||
(div [ class "font-semibold" ]
|
(div [ class "font-semibold" ]
|
||||||
[ i [ class "fa fa-caret-right mr-1 " ] []
|
[ i [ class "fa fa-file font-thin mr-1 " ] []
|
||||||
, text (entry.name ++ ":")
|
, text (entry.name ++ ":")
|
||||||
]
|
]
|
||||||
:: List.map
|
:: List.map
|
||||||
|
@ -14,7 +14,7 @@ module Comp.ItemCardList exposing
|
|||||||
, prevItem
|
, prevItem
|
||||||
, update
|
, update
|
||||||
, updateDrag
|
, updateDrag
|
||||||
, view2
|
, view
|
||||||
)
|
)
|
||||||
|
|
||||||
import Api.Model.AttachmentLight exposing (AttachmentLight)
|
import Api.Model.AttachmentLight exposing (AttachmentLight)
|
||||||
@ -24,6 +24,7 @@ import Api.Model.ItemLightList exposing (ItemLightList)
|
|||||||
import Comp.ItemCard
|
import Comp.ItemCard
|
||||||
import Comp.LinkTarget exposing (LinkTarget)
|
import Comp.LinkTarget exposing (LinkTarget)
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
|
import Data.ItemArrange exposing (ItemArrange)
|
||||||
import Data.ItemSelection exposing (ItemSelection)
|
import Data.ItemSelection exposing (ItemSelection)
|
||||||
import Data.Items
|
import Data.Items
|
||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
@ -32,6 +33,7 @@ import Html exposing (..)
|
|||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Messages.Comp.ItemCardList exposing (Texts)
|
import Messages.Comp.ItemCardList exposing (Texts)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
|
import Set exposing (Set)
|
||||||
import Styles as S
|
import Styles as S
|
||||||
import Util.ItemDragDrop as DD
|
import Util.ItemDragDrop as DD
|
||||||
import Util.List
|
import Util.List
|
||||||
@ -73,13 +75,9 @@ prevItem model id =
|
|||||||
--- Update
|
--- Update
|
||||||
|
|
||||||
|
|
||||||
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, LinkTarget )
|
update : Flags -> Msg -> Model -> UpdateResult
|
||||||
update flags msg model =
|
update flags msg model =
|
||||||
let
|
|
||||||
res =
|
|
||||||
updateDrag DD.init flags msg model
|
updateDrag DD.init flags msg model
|
||||||
in
|
|
||||||
( res.model, res.cmd, res.linkTarget )
|
|
||||||
|
|
||||||
|
|
||||||
type alias UpdateResult =
|
type alias UpdateResult =
|
||||||
@ -88,6 +86,7 @@ type alias UpdateResult =
|
|||||||
, dragModel : DD.Model
|
, dragModel : DD.Model
|
||||||
, selection : ItemSelection
|
, selection : ItemSelection
|
||||||
, linkTarget : LinkTarget
|
, linkTarget : LinkTarget
|
||||||
|
, toggleOpenRow : Maybe String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -109,6 +108,7 @@ updateDrag dm _ msg model =
|
|||||||
dm
|
dm
|
||||||
Data.ItemSelection.Inactive
|
Data.ItemSelection.Inactive
|
||||||
Comp.LinkTarget.LinkNone
|
Comp.LinkTarget.LinkNone
|
||||||
|
Nothing
|
||||||
|
|
||||||
AddResults list ->
|
AddResults list ->
|
||||||
if list.groups == [] then
|
if list.groups == [] then
|
||||||
@ -117,6 +117,7 @@ updateDrag dm _ msg model =
|
|||||||
dm
|
dm
|
||||||
Data.ItemSelection.Inactive
|
Data.ItemSelection.Inactive
|
||||||
Comp.LinkTarget.LinkNone
|
Comp.LinkTarget.LinkNone
|
||||||
|
Nothing
|
||||||
|
|
||||||
else
|
else
|
||||||
let
|
let
|
||||||
@ -128,6 +129,7 @@ updateDrag dm _ msg model =
|
|||||||
dm
|
dm
|
||||||
Data.ItemSelection.Inactive
|
Data.ItemSelection.Inactive
|
||||||
Comp.LinkTarget.LinkNone
|
Comp.LinkTarget.LinkNone
|
||||||
|
Nothing
|
||||||
|
|
||||||
ItemCardMsg item lm ->
|
ItemCardMsg item lm ->
|
||||||
let
|
let
|
||||||
@ -146,6 +148,7 @@ updateDrag dm _ msg model =
|
|||||||
result.dragModel
|
result.dragModel
|
||||||
result.selection
|
result.selection
|
||||||
result.linkTarget
|
result.linkTarget
|
||||||
|
result.toggleRow
|
||||||
|
|
||||||
RemoveItem id ->
|
RemoveItem id ->
|
||||||
UpdateResult { model | results = removeItemById id model.results }
|
UpdateResult { model | results = removeItemById id model.results }
|
||||||
@ -153,6 +156,7 @@ updateDrag dm _ msg model =
|
|||||||
dm
|
dm
|
||||||
Data.ItemSelection.Inactive
|
Data.ItemSelection.Inactive
|
||||||
Comp.LinkTarget.LinkNone
|
Comp.LinkTarget.LinkNone
|
||||||
|
Nothing
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -166,22 +170,78 @@ type alias ViewConfig =
|
|||||||
, previewUrlFallback : ItemLight -> String
|
, previewUrlFallback : ItemLight -> String
|
||||||
, attachUrl : AttachmentLight -> String
|
, attachUrl : AttachmentLight -> String
|
||||||
, detailPage : ItemLight -> Page
|
, detailPage : ItemLight -> Page
|
||||||
|
, arrange : ItemArrange
|
||||||
|
, showGroups : Bool
|
||||||
|
, rowOpen : String -> Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
view2 : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> Html Msg
|
view : Texts -> ViewConfig -> UiSettings -> Flags -> Model -> Html Msg
|
||||||
view2 texts cfg settings flags model =
|
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
|
div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "ds-item-list", True )
|
[ ( "ds-item-list", True )
|
||||||
, ( "ds-multi-select-mode", isMultiSelectMode cfg )
|
, ( "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
|
viewGroup : Texts -> Model -> ViewConfig -> UiSettings -> Flags -> ItemLightGroup -> Html Msg
|
||||||
viewGroup2 texts model cfg settings flags group =
|
viewGroup texts model cfg settings flags group =
|
||||||
div [ class "ds-item-group" ]
|
div [ class "ds-item-group" ]
|
||||||
[ div
|
[ div
|
||||||
[ class "flex py-1 mt-2 mb-2 flex flex-row items-center"
|
[ 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" ]
|
, div [ class (itemContainerCss cfg) ]
|
||||||
(List.map (viewItem2 texts model cfg settings flags) group.items)
|
(List.map (viewItem texts model cfg settings flags) group.items)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
viewItem2 : Texts -> Model -> ViewConfig -> UiSettings -> Flags -> ItemLight -> Html Msg
|
viewItem : Texts -> Model -> ViewConfig -> UiSettings -> Flags -> ItemLight -> Html Msg
|
||||||
viewItem2 texts model cfg settings flags item =
|
viewItem texts model cfg settings flags item =
|
||||||
let
|
let
|
||||||
currentClass =
|
currentClass =
|
||||||
if cfg.current == Just item.id then
|
if cfg.current == Just item.id then
|
||||||
@ -220,15 +280,31 @@ viewItem2 texts model cfg settings flags item =
|
|||||||
else
|
else
|
||||||
""
|
""
|
||||||
|
|
||||||
|
itemClass =
|
||||||
|
case cfg.arrange of
|
||||||
|
Data.ItemArrange.List ->
|
||||||
|
" mb-1"
|
||||||
|
|
||||||
|
Data.ItemArrange.Cards ->
|
||||||
|
""
|
||||||
|
|
||||||
vvcfg =
|
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 =
|
cardModel =
|
||||||
Dict.get item.id model.itemCards
|
Dict.get item.id model.itemCards
|
||||||
|> Maybe.withDefault Comp.ItemCard.init
|
|> Maybe.withDefault Comp.ItemCard.init
|
||||||
|
|
||||||
cardHtml =
|
cardHtml =
|
||||||
Comp.ItemCard.view2 texts.itemCard vvcfg settings flags cardModel item
|
Comp.ItemCard.view texts.itemCard vvcfg settings flags cardModel item
|
||||||
in
|
in
|
||||||
Html.map (ItemCardMsg item) cardHtml
|
Html.map (ItemCardMsg item) cardHtml
|
||||||
|
|
||||||
|
@ -130,12 +130,12 @@ view texts settings model =
|
|||||||
[ if isDeleted then
|
[ if isDeleted then
|
||||||
div
|
div
|
||||||
[ classList
|
[ classList
|
||||||
[ ( "text-red-500 dark:text-orange-600 text-4xl", True )
|
[ ( " text-4xl", True )
|
||||||
, ( "hidden", not isDeleted )
|
, ( "hidden", not isDeleted )
|
||||||
]
|
]
|
||||||
, title texts.basics.deleted
|
, title texts.basics.deleted
|
||||||
]
|
]
|
||||||
[ i [ class "mr-2 fa fa-trash-alt" ] []
|
[ Icons.trashIcon "mr-2"
|
||||||
]
|
]
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -72,6 +72,8 @@ module Data.Icons exposing
|
|||||||
, tagIcon2
|
, tagIcon2
|
||||||
, tags2
|
, tags2
|
||||||
, tagsIcon2
|
, tagsIcon2
|
||||||
|
, trash
|
||||||
|
, trashIcon
|
||||||
)
|
)
|
||||||
|
|
||||||
import Data.CustomFieldType exposing (CustomFieldType)
|
import Data.CustomFieldType exposing (CustomFieldType)
|
||||||
@ -81,6 +83,20 @@ import Svg
|
|||||||
import Svg.Attributes as SA
|
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 : String
|
||||||
share =
|
share =
|
||||||
"fa fa-share-alt"
|
"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
|
, idSet
|
||||||
, length
|
, length
|
||||||
, replaceIn
|
, replaceIn
|
||||||
|
, unwrapGroups
|
||||||
)
|
)
|
||||||
|
|
||||||
import Api.Model.ItemLight exposing (ItemLight)
|
import Api.Model.ItemLight exposing (ItemLight)
|
||||||
@ -27,6 +28,11 @@ flatten list =
|
|||||||
List.concatMap .items list.groups
|
List.concatMap .items list.groups
|
||||||
|
|
||||||
|
|
||||||
|
unwrapGroups : List ItemLightGroup -> List ItemLight
|
||||||
|
unwrapGroups groups =
|
||||||
|
List.concatMap .items groups
|
||||||
|
|
||||||
|
|
||||||
concat : ItemLightList -> ItemLightList -> ItemLightList
|
concat : ItemLightList -> ItemLightList -> ItemLightList
|
||||||
concat l0 l1 =
|
concat l0 l1 =
|
||||||
let
|
let
|
||||||
|
@ -36,6 +36,7 @@ import Data.BasicSize exposing (BasicSize)
|
|||||||
import Data.Color exposing (Color)
|
import Data.Color exposing (Color)
|
||||||
import Data.Fields exposing (Field)
|
import Data.Fields exposing (Field)
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
|
import Data.ItemArrange exposing (ItemArrange)
|
||||||
import Data.ItemTemplate exposing (ItemTemplate)
|
import Data.ItemTemplate exposing (ItemTemplate)
|
||||||
import Data.Pdf exposing (PdfMode)
|
import Data.Pdf exposing (PdfMode)
|
||||||
import Data.UiTheme exposing (UiTheme)
|
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
|
{-| 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
|
Making fields optional, allows it to evolve without breaking previous
|
||||||
versions. Also if a user is logged out, an empty object is send to
|
versions. Also if a user is logged out, an empty object is send to
|
||||||
@ -79,6 +80,8 @@ type alias StoredUiSettings =
|
|||||||
, sideMenuVisible : Bool
|
, sideMenuVisible : Bool
|
||||||
, powerSearchEnabled : Bool
|
, powerSearchEnabled : Bool
|
||||||
, uiLang : Maybe String
|
, uiLang : Maybe String
|
||||||
|
, itemSearchShowGroups : Bool
|
||||||
|
, itemSearchArrange : Maybe String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -113,6 +116,8 @@ storedUiSettingsDecoder =
|
|||||||
|> P.optional "sideMenuVisible" Decode.bool False
|
|> P.optional "sideMenuVisible" Decode.bool False
|
||||||
|> P.optional "powerSearchEnabled" Decode.bool False
|
|> P.optional "powerSearchEnabled" Decode.bool False
|
||||||
|> P.optional "uiLang" maybeString Nothing
|
|> P.optional "uiLang" maybeString Nothing
|
||||||
|
|> P.optional "itemSearchShowGroups" Decode.bool True
|
||||||
|
|> P.optional "itemSearchArrange" maybeString Nothing
|
||||||
|
|
||||||
|
|
||||||
storedUiSettingsEncode : StoredUiSettings -> Encode.Value
|
storedUiSettingsEncode : StoredUiSettings -> Encode.Value
|
||||||
@ -143,6 +148,8 @@ storedUiSettingsEncode value =
|
|||||||
, ( "sideMenuVisible", Encode.bool value.sideMenuVisible )
|
, ( "sideMenuVisible", Encode.bool value.sideMenuVisible )
|
||||||
, ( "powerSearchEnabled", Encode.bool value.powerSearchEnabled )
|
, ( "powerSearchEnabled", Encode.bool value.powerSearchEnabled )
|
||||||
, ( "uiLang", maybeEnc Encode.string value.uiLang )
|
, ( "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
|
, sideMenuVisible : Bool
|
||||||
, powerSearchEnabled : Bool
|
, powerSearchEnabled : Bool
|
||||||
, uiLang : UiLanguage
|
, uiLang : UiLanguage
|
||||||
|
, itemSearchShowGroups : Bool
|
||||||
|
, itemSearchArrange : ItemArrange
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -248,6 +257,8 @@ defaults =
|
|||||||
, sideMenuVisible = True
|
, sideMenuVisible = True
|
||||||
, powerSearchEnabled = False
|
, powerSearchEnabled = False
|
||||||
, uiLang = Messages.UiLanguage.English
|
, uiLang = Messages.UiLanguage.English
|
||||||
|
, itemSearchShowGroups = True
|
||||||
|
, itemSearchArrange = Data.ItemArrange.Cards
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -306,6 +317,10 @@ merge given fallback =
|
|||||||
, uiLang =
|
, uiLang =
|
||||||
Maybe.map Messages.fromIso2 given.uiLang
|
Maybe.map Messages.fromIso2 given.uiLang
|
||||||
|> Maybe.withDefault Messages.UiLanguage.English
|
|> 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
|
, sideMenuVisible = settings.sideMenuVisible
|
||||||
, powerSearchEnabled = settings.powerSearchEnabled
|
, powerSearchEnabled = settings.powerSearchEnabled
|
||||||
, uiLang = Just <| Messages.toIso2 settings.uiLang
|
, 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"
|
, addMoreFiles = "Diesem Dokument weitere Dateien anfügen"
|
||||||
, confirmItemMetadata = "Metadaten bestätigen"
|
, confirmItemMetadata = "Metadaten bestätigen"
|
||||||
, confirm = "Bestätige"
|
, confirm = "Bestätige"
|
||||||
, unconfirmItemMetadata = "Widerrufe Bestätigung"
|
, unconfirmItemMetadata = "Widerrufe"
|
||||||
, reprocessItem = "Das Dokument erneut verarbeiten"
|
, reprocessItem = "Das Dokument erneut verarbeiten"
|
||||||
, deleteThisItem = "Das Dokument löschen"
|
, deleteThisItem = "Das Dokument löschen"
|
||||||
, undeleteThisItem = "Das Dokument wiederherstellen"
|
, undeleteThisItem = "Das Dokument wiederherstellen"
|
||||||
|
@ -60,7 +60,7 @@ de =
|
|||||||
, chooseDirection = "Wähle eine Richtung…"
|
, chooseDirection = "Wähle eine Richtung…"
|
||||||
, confirmUnconfirm = "Bestätige/Widerrufe Metadaten"
|
, confirmUnconfirm = "Bestätige/Widerrufe Metadaten"
|
||||||
, confirm = "Bestätige"
|
, confirm = "Bestätige"
|
||||||
, unconfirm = "Widerrufe Bestätigung"
|
, unconfirm = "Widerrufe"
|
||||||
, changeTagMode = "Wechsel den Änderungsmodus für Tags"
|
, changeTagMode = "Wechsel den Änderungsmodus für Tags"
|
||||||
, dueDateTab = "Fälligkeitsdatum"
|
, dueDateTab = "Fälligkeitsdatum"
|
||||||
, direction = Messages.Data.Direction.de
|
, direction = Messages.Data.Direction.de
|
||||||
|
@ -49,6 +49,10 @@ type alias Texts =
|
|||||||
, nothingSelectedToShare : String
|
, nothingSelectedToShare : String
|
||||||
, loadMore : String
|
, loadMore : String
|
||||||
, thatsAll : 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."
|
, nothingSelectedToShare = "Sharing everything doesn't work. You need to apply some criteria."
|
||||||
, loadMore = "Load more…"
|
, loadMore = "Load more…"
|
||||||
, thatsAll = "That's all"
|
, 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."
|
, nothingSelectedToShare = "Alles kann nicht geteilt werden; es muss etwas gesucht werden."
|
||||||
, loadMore = "Mehr laden…"
|
, loadMore = "Mehr laden…"
|
||||||
, thatsAll = "Mehr gibt es nicht"
|
, 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
|
, powerSearchPlaceholder : String
|
||||||
, normalSearchPlaceholder : String
|
, normalSearchPlaceholder : String
|
||||||
, extendedSearch : String
|
, extendedSearch : String
|
||||||
|
, showItemGroups : String
|
||||||
|
, listView : String
|
||||||
|
, tileView : String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -41,6 +44,9 @@ gb =
|
|||||||
, powerSearchPlaceholder = "Extended search…"
|
, powerSearchPlaceholder = "Extended search…"
|
||||||
, extendedSearch = "Extended search query"
|
, extendedSearch = "Extended search query"
|
||||||
, normalSearchPlaceholder = "Search…"
|
, normalSearchPlaceholder = "Search…"
|
||||||
|
, showItemGroups = "Group by month"
|
||||||
|
, listView = "List view"
|
||||||
|
, tileView = "Tile view"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -56,4 +62,7 @@ de =
|
|||||||
, powerSearchPlaceholder = "Erweiterte Suche…"
|
, powerSearchPlaceholder = "Erweiterte Suche…"
|
||||||
, extendedSearch = "Erweiterte Suchanfrage"
|
, extendedSearch = "Erweiterte Suchanfrage"
|
||||||
, normalSearchPlaceholder = "Suche…"
|
, normalSearchPlaceholder = "Suche…"
|
||||||
|
, showItemGroups = "nach Monat gruppieren"
|
||||||
|
, listView = "Listenansicht"
|
||||||
|
, tileView = "Kachelansicht"
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ module Page.Home.Data exposing
|
|||||||
|
|
||||||
import Api
|
import Api
|
||||||
import Api.Model.BasicResult exposing (BasicResult)
|
import Api.Model.BasicResult exposing (BasicResult)
|
||||||
import Api.Model.ItemLight exposing (ItemLight)
|
|
||||||
import Api.Model.ItemLightList exposing (ItemLightList)
|
import Api.Model.ItemLightList exposing (ItemLightList)
|
||||||
import Api.Model.SearchStats exposing (SearchStats)
|
import Api.Model.SearchStats exposing (SearchStats)
|
||||||
import Browser.Dom as Dom
|
import Browser.Dom as Dom
|
||||||
@ -40,6 +39,7 @@ import Comp.PowerSearchInput
|
|||||||
import Comp.PublishItems
|
import Comp.PublishItems
|
||||||
import Comp.SearchMenu
|
import Comp.SearchMenu
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
|
import Data.ItemArrange exposing (ItemArrange)
|
||||||
import Data.ItemNav exposing (ItemNav)
|
import Data.ItemNav exposing (ItemNav)
|
||||||
import Data.ItemQuery as Q
|
import Data.ItemQuery as Q
|
||||||
import Data.Items
|
import Data.Items
|
||||||
@ -66,6 +66,8 @@ type alias Model =
|
|||||||
, scrollToCard : Maybe String
|
, scrollToCard : Maybe String
|
||||||
, searchStats : SearchStats
|
, searchStats : SearchStats
|
||||||
, powerSearchInput : Comp.PowerSearchInput.Model
|
, powerSearchInput : Comp.PowerSearchInput.Model
|
||||||
|
, viewMenuOpen : Bool
|
||||||
|
, itemRowsOpen : Set String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -133,6 +135,8 @@ init flags viewMode =
|
|||||||
, viewMode = viewMode
|
, viewMode = viewMode
|
||||||
, searchStats = Api.Model.SearchStats.empty
|
, searchStats = Api.Model.SearchStats.empty
|
||||||
, powerSearchInput = Comp.PowerSearchInput.init
|
, powerSearchInput = Comp.PowerSearchInput.init
|
||||||
|
, viewMenuOpen = False
|
||||||
|
, itemRowsOpen = Set.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -230,6 +234,10 @@ type Msg
|
|||||||
| TogglePublishCurrentQueryView
|
| TogglePublishCurrentQueryView
|
||||||
| PublishViewMsg Comp.PublishItems.Msg
|
| PublishViewMsg Comp.PublishItems.Msg
|
||||||
| RefreshView
|
| RefreshView
|
||||||
|
| ToggleViewMenu
|
||||||
|
| ToggleShowGroups
|
||||||
|
| ToggleArrange ItemArrange
|
||||||
|
| ToggleExpandCollapseRows
|
||||||
|
|
||||||
|
|
||||||
type SearchType
|
type SearchType
|
||||||
|
@ -144,16 +144,40 @@ update mId key flags texts settings msg model =
|
|||||||
|
|
||||||
( v, _ ) ->
|
( v, _ ) ->
|
||||||
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
|
in
|
||||||
withSub
|
withSub
|
||||||
( { model
|
( { model
|
||||||
| itemListModel = result.model
|
| itemListModel = result.model
|
||||||
, viewMode = nextView
|
, viewMode = nextView
|
||||||
|
, itemRowsOpen = itemRows
|
||||||
, dragDropData = DD.DragDropData result.dragModel Nothing
|
, dragDropData = DD.DragDropData result.dragModel Nothing
|
||||||
}
|
}
|
||||||
, Cmd.batch [ Cmd.map ItemCardListMsg result.cmd, searchMsg ]
|
, 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) ->
|
ItemSearchResp scroll (Ok list) ->
|
||||||
let
|
let
|
||||||
noff =
|
noff =
|
||||||
@ -923,6 +947,29 @@ update mId key flags texts settings msg model =
|
|||||||
_ ->
|
_ ->
|
||||||
noSub ( model, Cmd.none )
|
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
|
--- Helpers
|
||||||
|
@ -19,7 +19,7 @@ import Comp.SearchMenu
|
|||||||
import Comp.SearchStatsView
|
import Comp.SearchStatsView
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
import Data.Icons as Icons
|
import Data.Icons as Icons
|
||||||
import Data.ItemQuery as Q
|
import Data.ItemArrange
|
||||||
import Data.ItemSelection
|
import Data.ItemSelection
|
||||||
import Data.SearchMode
|
import Data.SearchMode
|
||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
@ -182,7 +182,7 @@ itemsBar texts flags settings model =
|
|||||||
SelectView svm ->
|
SelectView svm ->
|
||||||
[ editMenuBar texts model svm ]
|
[ editMenuBar texts model svm ]
|
||||||
|
|
||||||
PublishView query ->
|
PublishView _ ->
|
||||||
[ defaultMenuBar texts flags settings model ]
|
[ defaultMenuBar texts flags settings model ]
|
||||||
|
|
||||||
|
|
||||||
@ -248,6 +248,12 @@ defaultMenuBar texts flags settings model =
|
|||||||
, Html.map PowerSearchMsg
|
, Html.map PowerSearchMsg
|
||||||
(Comp.PowerSearchInput.viewResult [] model.powerSearchInput)
|
(Comp.PowerSearchInput.viewResult [] model.powerSearchInput)
|
||||||
]
|
]
|
||||||
|
|
||||||
|
isCardView =
|
||||||
|
settings.itemSearchArrange == Data.ItemArrange.Cards
|
||||||
|
|
||||||
|
isListView =
|
||||||
|
settings.itemSearchArrange == Data.ItemArrange.List
|
||||||
in
|
in
|
||||||
MB.view
|
MB.view
|
||||||
{ end =
|
{ end =
|
||||||
@ -293,6 +299,61 @@ defaultMenuBar texts flags settings model =
|
|||||||
, ( "bg-gray-200 dark:bg-bluegray-600", selectActive 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 =
|
, start =
|
||||||
[ MB.CustomElement <|
|
[ MB.CustomElement <|
|
||||||
@ -469,13 +530,16 @@ itemCardList texts flags settings model =
|
|||||||
Api.itemBasePreviewURL item.id
|
Api.itemBasePreviewURL item.id
|
||||||
|
|
||||||
viewCfg sel =
|
viewCfg sel =
|
||||||
Comp.ItemCardList.ViewConfig
|
{ current = model.scrollToCard
|
||||||
model.scrollToCard
|
, selection = sel
|
||||||
sel
|
, previewUrl = previewUrl
|
||||||
previewUrl
|
, previewUrlFallback = previewUrlFallback
|
||||||
previewUrlFallback
|
, attachUrl = .id >> Api.fileURL
|
||||||
(.id >> Api.fileURL)
|
, detailPage = .id >> ItemDetailPage
|
||||||
(.id >> ItemDetailPage)
|
, arrange = settings.itemSearchArrange
|
||||||
|
, showGroups = settings.itemSearchShowGroups
|
||||||
|
, rowOpen = \id -> Set.member "all" model.itemRowsOpen || Set.member id model.itemRowsOpen
|
||||||
|
}
|
||||||
|
|
||||||
itemViewCfg =
|
itemViewCfg =
|
||||||
case model.viewMode of
|
case model.viewMode of
|
||||||
@ -486,7 +550,7 @@ itemCardList texts flags settings model =
|
|||||||
viewCfg Data.ItemSelection.Inactive
|
viewCfg Data.ItemSelection.Inactive
|
||||||
in
|
in
|
||||||
[ Html.map ItemCardListMsg
|
[ Html.map ItemCardListMsg
|
||||||
(Comp.ItemCardList.view2 texts.itemCardList
|
(Comp.ItemCardList.view texts.itemCardList
|
||||||
itemViewCfg
|
itemViewCfg
|
||||||
settings
|
settings
|
||||||
flags
|
flags
|
||||||
|
@ -17,7 +17,10 @@ import Comp.PowerSearchInput
|
|||||||
import Comp.SearchMenu
|
import Comp.SearchMenu
|
||||||
import Comp.SharePasswordForm
|
import Comp.SharePasswordForm
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
|
import Data.ItemArrange exposing (ItemArrange)
|
||||||
import Http
|
import Http
|
||||||
|
import Page.Home.Data exposing (Msg(..))
|
||||||
|
import Set exposing (Set)
|
||||||
import Util.Html exposing (KeyCode)
|
import Util.Html exposing (KeyCode)
|
||||||
|
|
||||||
|
|
||||||
@ -50,6 +53,12 @@ type alias Model =
|
|||||||
, initialized : Bool
|
, initialized : Bool
|
||||||
, contentSearch : Maybe String
|
, contentSearch : Maybe String
|
||||||
, searchMode : SearchBarMode
|
, searchMode : SearchBarMode
|
||||||
|
, viewMode :
|
||||||
|
{ menuOpen : Bool
|
||||||
|
, showGroups : Bool
|
||||||
|
, arrange : ItemArrange
|
||||||
|
, rowsOpen : Set String
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -66,6 +75,12 @@ emptyModel flags =
|
|||||||
, initialized = False
|
, initialized = False
|
||||||
, contentSearch = Nothing
|
, contentSearch = Nothing
|
||||||
, searchMode = SearchBarContent
|
, searchMode = SearchBarContent
|
||||||
|
, viewMode =
|
||||||
|
{ menuOpen = False
|
||||||
|
, showGroups = True
|
||||||
|
, arrange = Data.ItemArrange.Cards
|
||||||
|
, rowsOpen = Set.empty
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -100,3 +115,6 @@ type Msg
|
|||||||
| ToggleSearchBar
|
| ToggleSearchBar
|
||||||
| SetContentSearch String
|
| SetContentSearch String
|
||||||
| ContentSearchKey (Maybe KeyCode)
|
| ContentSearchKey (Maybe KeyCode)
|
||||||
|
| ToggleViewMenu
|
||||||
|
| ToggleArrange ItemArrange
|
||||||
|
| ToggleShowGroups
|
||||||
|
@ -11,6 +11,7 @@ import Comp.Basic as B
|
|||||||
import Comp.MenuBar as MB
|
import Comp.MenuBar as MB
|
||||||
import Comp.PowerSearchInput
|
import Comp.PowerSearchInput
|
||||||
import Data.Flags exposing (Flags)
|
import Data.Flags exposing (Flags)
|
||||||
|
import Data.ItemArrange
|
||||||
import Html exposing (..)
|
import Html exposing (..)
|
||||||
import Html.Attributes exposing (..)
|
import Html.Attributes exposing (..)
|
||||||
import Html.Events exposing (onClick, onInput)
|
import Html.Events exposing (onClick, onInput)
|
||||||
@ -108,6 +109,43 @@ view texts flags model =
|
|||||||
, handler = onClick ResetSearch
|
, handler = onClick ResetSearch
|
||||||
, attrs = [ href "#" ]
|
, 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"
|
, 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 Messages.Page.Share exposing (Texts)
|
||||||
import Page exposing (Page(..))
|
import Page exposing (Page(..))
|
||||||
import Page.Share.Data exposing (Model, Msg(..))
|
import Page.Share.Data exposing (Model, Msg(..))
|
||||||
|
import Set
|
||||||
|
|
||||||
|
|
||||||
view : Texts -> UiSettings -> Flags -> String -> Model -> Html Msg
|
view : Texts -> UiSettings -> Flags -> String -> Model -> Html Msg
|
||||||
@ -29,9 +30,12 @@ view texts settings flags shareId model =
|
|||||||
, previewUrlFallback = \item -> Api.shareItemBasePreviewURL item.id
|
, previewUrlFallback = \item -> Api.shareItemBasePreviewURL item.id
|
||||||
, attachUrl = .id >> Api.shareFileURL
|
, attachUrl = .id >> Api.shareFileURL
|
||||||
, detailPage = \item -> ShareDetailPage shareId item.id
|
, detailPage = \item -> ShareDetailPage shareId item.id
|
||||||
|
, arrange = model.viewMode.arrange
|
||||||
|
, showGroups = model.viewMode.showGroups
|
||||||
|
, rowOpen = \id -> Set.member id model.viewMode.rowsOpen
|
||||||
}
|
}
|
||||||
in
|
in
|
||||||
div []
|
div []
|
||||||
[ Html.map ItemListMsg
|
[ 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.SearchMode
|
||||||
import Data.UiSettings exposing (UiSettings)
|
import Data.UiSettings exposing (UiSettings)
|
||||||
import Page.Share.Data exposing (..)
|
import Page.Share.Data exposing (..)
|
||||||
|
import Set
|
||||||
import Util.Html
|
import Util.Html
|
||||||
import Util.Maybe
|
import Util.Maybe
|
||||||
import Util.Update
|
import Util.Update
|
||||||
@ -161,16 +162,31 @@ update flags settings shareId msg model =
|
|||||||
|
|
||||||
ItemListMsg lm ->
|
ItemListMsg lm ->
|
||||||
let
|
let
|
||||||
( im, ic, linkTarget ) =
|
result =
|
||||||
Comp.ItemCardList.update flags lm model.itemListModel
|
Comp.ItemCardList.update flags lm model.itemListModel
|
||||||
|
|
||||||
searchMsg =
|
searchMsg =
|
||||||
Maybe.map Util.Update.cmdUnit (linkTargetMsg linkTarget)
|
Maybe.map Util.Update.cmdUnit (linkTargetMsg result.linkTarget)
|
||||||
|> Maybe.withDefault Cmd.none
|
|> 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
|
in
|
||||||
noSub
|
noSub
|
||||||
( { model | itemListModel = im }
|
( { model | itemListModel = result.model, viewMode = { vm | rowsOpen = itemRows } }
|
||||||
, Cmd.batch [ Cmd.map ItemListMsg ic, searchMsg ]
|
, Cmd.batch [ Cmd.map ItemListMsg result.cmd, searchMsg ]
|
||||||
)
|
)
|
||||||
|
|
||||||
ToggleSearchBar ->
|
ToggleSearchBar ->
|
||||||
@ -196,6 +212,36 @@ update flags settings shareId msg model =
|
|||||||
ContentSearchKey _ ->
|
ContentSearchKey _ ->
|
||||||
noSub ( model, Cmd.none )
|
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 : ( Model, Cmd Msg ) -> UpdateResult
|
||||||
noSub ( m, c ) =
|
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 "
|
" 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 : String
|
||||||
tableMain =
|
tableMain =
|
||||||
"border-collapse table w-full"
|
"border-collapse table w-full"
|
||||||
|
@ -16,6 +16,9 @@
|
|||||||
.ds-item-card.current {
|
.ds-item-card.current {
|
||||||
@apply shadow-lg dark:border-lightblue-600;
|
@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 {
|
.elm-datepicker--input {
|
||||||
@apply pl-10 rounded w-full placeholder-gray-400 dark:text-bluegray-200 dark:border-bluegray-500;
|
@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 {
|
.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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user