Improve document list view

Replace the html table with something that has more vertical space,
but scales better horizontally. On most screens at least 6-8 entries
should be visible at once.
This commit is contained in:
Eike Kettner 2020-05-17 14:01:40 +02:00
parent 8a56cf0801
commit f45b40342c
5 changed files with 208 additions and 13 deletions

View File

@ -0,0 +1,187 @@
module Comp.ItemCardList exposing
( Model
, Msg(..)
, init
, nextItem
, prevItem
, update
, view
)
import Api.Model.ItemLight exposing (ItemLight)
import Api.Model.ItemLightGroup exposing (ItemLightGroup)
import Api.Model.ItemLightList exposing (ItemLightList)
import Data.Direction
import Data.Flags exposing (Flags)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Util.List
import Util.String
import Util.Time
type alias Model =
{ results : ItemLightList
}
type Msg
= SetResults ItemLightList
| SelectItem ItemLight
init : Model
init =
{ results = Api.Model.ItemLightList.empty
}
nextItem : Model -> String -> Maybe ItemLight
nextItem model id =
List.concatMap .items model.results.groups
|> Util.List.findNext (\i -> i.id == id)
prevItem : Model -> String -> Maybe ItemLight
prevItem model id =
List.concatMap .items model.results.groups
|> Util.List.findPrev (\i -> i.id == id)
--- Update
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Maybe ItemLight )
update _ msg model =
case msg of
SetResults list ->
let
newModel =
{ model | results = list }
in
( newModel, Cmd.none, Nothing )
SelectItem item ->
( model, Cmd.none, Just item )
--- View
view : Model -> Html Msg
view model =
div [ class "ui container" ]
(List.map viewGroup model.results.groups)
viewGroup : ItemLightGroup -> Html Msg
viewGroup group =
div [] <|
List.concat
[ [ div [ class "ui horizontal divider" ]
[ text group.name
]
]
, [ div [ class "ui one column grid" ]
(List.map viewItem group.items)
]
]
viewItem : ItemLight -> Html Msg
viewItem item =
let
dirIcon =
i [ class (Data.Direction.iconFromMaybe item.direction) ] []
corr =
List.filterMap identity [ item.corrOrg, item.corrPerson ]
|> List.map .name
|> List.intersperse ", "
|> String.concat
conc =
List.filterMap identity [ item.concPerson, item.concEquip ]
|> List.map .name
|> List.intersperse ", "
|> String.concat
dueDate =
Maybe.map Util.Time.formatDateShort item.dueDate
|> Maybe.withDefault ""
in
div [ class "column item-list" ]
[ a
[ class "ui fluid card"
, href "#"
, onClick (SelectItem item)
]
[ div [ class "content" ]
[ div [ class "header" ]
[ dirIcon
, Util.String.ellipsis 45 item.name |> text
]
, span [ class "meta" ]
[ div
[ classList
[ ( "ui blue ribbon label", True )
, ( "invisible", item.state /= "created" )
]
]
[ i [ class "exclamation icon" ] []
, text " New"
]
]
, span [ class "right floated meta" ]
[ Util.Time.formatDateShort item.date |> text
]
]
, div [ class "content" ]
[ div [ class "ui horizontal list" ]
[ div
[ class "item"
, title "Correspondent"
]
[ i [ class "envelope outline icon" ] []
, text " "
, Util.String.withDefault "-" corr |> text
]
, div
[ class "item"
, title "Concerning"
]
[ i [ class "comment outline icon" ] []
, text " "
, Util.String.withDefault "-" conc |> text
]
]
, div [ class "right floated meta" ]
[ div [ class "ui horizontal list" ]
[ div
[ class "item"
, title "Source"
]
[ text item.source
]
, div
[ class "item"
, title ("Due on " ++ dueDate)
]
[ div
[ classList
[ ( "ui basic grey label", True )
, ( "invisible hidden", item.dueDate == Nothing )
]
]
[ i [ class "bell icon" ] []
, text (" " ++ dueDate)
]
]
]
]
]
]
]

View File

@ -7,14 +7,14 @@ module Page.Home.Data exposing
)
import Api.Model.ItemLightList exposing (ItemLightList)
import Comp.ItemList
import Comp.ItemCardList
import Comp.SearchMenu
import Http
type alias Model =
{ searchMenuModel : Comp.SearchMenu.Model
, itemListModel : Comp.ItemList.Model
, itemListModel : Comp.ItemCardList.Model
, searchInProgress : Bool
, viewMode : ViewMode
}
@ -23,7 +23,7 @@ type alias Model =
emptyModel : Model
emptyModel =
{ searchMenuModel = Comp.SearchMenu.emptyModel
, itemListModel = Comp.ItemList.emptyModel
, itemListModel = Comp.ItemCardList.init
, searchInProgress = False
, viewMode = Listing
}
@ -33,7 +33,7 @@ type Msg
= Init
| SearchMenuMsg Comp.SearchMenu.Msg
| ResetSearch
| ItemListMsg Comp.ItemList.Msg
| ItemCardListMsg Comp.ItemCardList.Msg
| ItemSearchResp (Result Http.Error ItemLightList)
| DoSearch
@ -47,10 +47,10 @@ itemNav : String -> Model -> { prev : Maybe String, next : Maybe String }
itemNav id model =
let
prev =
Comp.ItemList.prevItem model.itemListModel id
Comp.ItemCardList.prevItem model.itemListModel id
next =
Comp.ItemList.nextItem model.itemListModel id
Comp.ItemCardList.nextItem model.itemListModel id
in
{ prev = Maybe.map .id prev
, next = Maybe.map .id next

View File

@ -2,7 +2,7 @@ module Page.Home.Update exposing (update)
import Api
import Browser.Navigation as Nav
import Comp.ItemList
import Comp.ItemCardList
import Comp.SearchMenu
import Data.Flags exposing (Flags)
import Page exposing (Page(..))
@ -40,10 +40,10 @@ update key flags msg model =
in
( m2, Cmd.batch [ c2, Cmd.map SearchMenuMsg (Tuple.second nextState.modelCmd) ] )
ItemListMsg m ->
ItemCardListMsg m ->
let
( m2, c2, mitem ) =
Comp.ItemList.update flags m model.itemListModel
Comp.ItemCardList.update flags m model.itemListModel
cmd =
case mitem of
@ -53,14 +53,14 @@ update key flags msg model =
Nothing ->
Cmd.none
in
( { model | itemListModel = m2 }, Cmd.batch [ Cmd.map ItemListMsg c2, cmd ] )
( { model | itemListModel = m2 }, Cmd.batch [ Cmd.map ItemCardListMsg c2, cmd ] )
ItemSearchResp (Ok list) ->
let
m =
{ model | searchInProgress = False, viewMode = Listing }
in
update key flags (ItemListMsg (Comp.ItemList.SetResults list)) m
update key flags (ItemCardListMsg (Comp.ItemCardList.SetResults list)) m
ItemSearchResp (Err _) ->
( { model | searchInProgress = False }, Cmd.none )

View File

@ -1,6 +1,6 @@
module Page.Home.View exposing (view)
import Comp.ItemList
import Comp.ItemCardList
import Comp.SearchMenu
import Html exposing (..)
import Html.Attributes exposing (..)
@ -45,7 +45,7 @@ view model =
resultPlaceholder
else
Html.map ItemListMsg (Comp.ItemList.view model.itemListModel)
Html.map ItemCardListMsg (Comp.ItemCardList.view model.itemListModel)
Detail ->
div [] []

View File

@ -132,6 +132,14 @@ textarea.markdown-editor {
padding-right: 1em;
}
.default-layout .ui.grid > .column.item-list:not(.row) {
padding-top: 0.3em;
padding-bottom: 0.6em;
}
.default-layout .ui.grid > .column.item-list:not(.row):last-child {
padding-bottom: 1.5rem;
}
label span.muted {
font-size: smaller;
color: rgba(0,0,0,0.6);