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