docspell/modules/webapp/src/main/elm/Comp/ItemList.elm
Eike Kettner 831cd8b655 Initial version.
Features:

- Upload PDF files let them analyze

- Manage meta data and items

- See processing in webapp
2019-09-21 22:02:36 +02:00

236 lines
7.5 KiB
Elm

module Comp.ItemList exposing (Model
, emptyModel
, Msg(..)
, prevItem
, nextItem
, update
, view)
import Set exposing (Set)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)
import Api.Model.ItemLightList exposing (ItemLightList)
import Api.Model.ItemLightGroup exposing (ItemLightGroup)
import Api.Model.ItemLight exposing (ItemLight)
import Data.Flags exposing (Flags)
import Data.Direction
import Util.List
import Util.String
import Util.Time
import Util.Maybe
type alias Model =
{ results: ItemLightList
, openGroups: Set String
}
emptyModel: Model
emptyModel =
{ results = Api.Model.ItemLightList.empty
, openGroups = Set.empty
}
type Msg
= SetResults ItemLightList
| ToggleGroupState ItemLightGroup
| CollapseAll
| ExpandAll
| SelectItem ItemLight
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)
openAllGroups: Model -> Set String
openAllGroups model =
List.foldl
(\g -> \set -> Set.insert g.name set)
model.openGroups
model.results.groups
update: Flags -> Msg -> Model -> (Model, Cmd Msg, Maybe ItemLight)
update flags msg model =
case msg of
SetResults list ->
let
newModel = { model | results = list, openGroups = Set.empty }
in
({newModel|openGroups = openAllGroups newModel}, Cmd.none, Nothing)
ToggleGroupState group ->
let
m2 = if isGroupOpen model group then closeGroup model group
else openGroup model group
in
(m2, Cmd.none, Nothing)
CollapseAll ->
({model | openGroups = Set.empty }, Cmd.none, Nothing)
ExpandAll ->
let
open = openAllGroups model
in
({model | openGroups = open }, Cmd.none, Nothing)
SelectItem item ->
(model, Cmd.none, Just item)
view: Model -> Html Msg
view model =
div []
[div [class "ui ablue-comp menu"]
[div [class "right floated menu"]
[a [class "item"
,title "Expand all"
,onClick ExpandAll
,href ""
]
[i [class "double angle down icon"][]
]
,a [class "item"
,title "Collapse all"
,onClick CollapseAll
,href ""
]
[i [class "double angle up icon"][]
]
]
]
,div [class "ui middle aligned very relaxed divided basic list segment"]
(List.map (viewGroup model) model.results.groups)
]
isGroupOpen: Model -> ItemLightGroup -> Bool
isGroupOpen model group =
Set.member group.name model.openGroups
openGroup: Model -> ItemLightGroup -> Model
openGroup model group =
{ model | openGroups = Set.insert group.name model.openGroups }
closeGroup: Model -> ItemLightGroup -> Model
closeGroup model group =
{ model | openGroups = Set.remove group.name model.openGroups }
viewGroup: Model -> ItemLightGroup -> Html Msg
viewGroup model group =
let
groupOpen = isGroupOpen model group
children =
[i [classList [("large middle aligned icon", True)
,("caret right", not groupOpen)
,("caret down", groupOpen)
]][]
,div [class "content"]
[div [class "right floated content"]
[div [class "ui blue label"]
[List.length group.items |> String.fromInt |> text
]
]
,a [class "header"
,onClick (ToggleGroupState group)
,href ""
]
[text group.name
]
,div [class "description"]
[makeSummary group |> text
]
]
]
itemTable =
div [class "ui basic content segment no-margin"]
[(renderItemTable model group.items)
]
in
if isGroupOpen model group then
div [class "item"]
(List.append children [itemTable])
else
div [class "item"]
children
renderItemTable: Model -> List ItemLight -> Html Msg
renderItemTable model items =
table [class "ui selectable padded table"]
[thead []
[tr []
[th [class "collapsing"][]
,th [class "collapsing"][text "Name"]
,th [class "collapsing"][text "Date"]
,th [class "collapsing"][text "Source"]
,th [][text "Correspondent"]
,th [][text "Concerning"]
]
]
,tbody[]
(List.map (renderItemLine model) items)
]
renderItemLine: Model -> ItemLight -> Html Msg
renderItemLine model 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
in
tr [onClick (SelectItem item)]
[td [class "collapsing"]
[div [classList [("ui teal ribbon label", True)
,("invisible", item.state /= "created")
]
][text "New"
]
]
,td [class "collapsing"]
[ dirIcon
, Util.String.ellipsis 45 item.name |> text
]
,td [class "collapsing"]
[Util.Time.formatDateShort item.date |> text
,span [classList [("invisible", Util.Maybe.isEmpty item.dueDate)
]
]
[text " "
,div [class "ui basic label"]
[i [class "bell icon"][]
,Maybe.map Util.Time.formatDateShort item.dueDate |> Maybe.withDefault "" |> text
]
]
]
,td [class "collapsing"][text item.source]
,td [][text corr]
,td [][text conc]
]
makeSummary: ItemLightGroup -> String
makeSummary group =
let
corrOrgs = List.filterMap .corrOrg group.items
corrPers = List.filterMap .corrPerson group.items
concPers = List.filterMap .concPerson group.items
concEqui = List.filterMap .concEquip group.items
all = List.concat [corrOrgs, corrPers, concPers, concEqui]
in
List.map .name all
|> Util.List.distinct
|> List.intersperse ", "
|> String.concat