Merge pull request #1221 from eikek/feature/list-view

Select list/tile view and store to ui settings
This commit is contained in:
mergify[bot]
2021-12-15 21:47:57 +00:00
committed by GitHub
20 changed files with 850 additions and 75 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

View 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

View File

@ -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

View File

@ -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
} }

View File

@ -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"

View File

@ -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

View File

@ -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"
} }

View File

@ -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"
} }

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"
} }

View File

@ -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)
] ]

View File

@ -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 ) =

View File

@ -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"

View File

@ -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;
} }
} }