docspell/modules/webapp/src/main/elm/Comp/BoxQueryView.elm
eikek b664b5771d Fixes in dashboard table view
- The first tag was rendered with slightly higher height than the rest
- Columns between first and last are hidden on small screens
- Use `break-all` to break all words if necessary without trying to
  keep whole words
2022-02-23 23:26:22 +01:00

244 lines
6.0 KiB
Elm

{-
Copyright 2020 Eike K. & Contributors
SPDX-License-Identifier: AGPL-3.0-or-later
-}
module Comp.BoxQueryView exposing (Model, Msg, init, reloadData, update, view)
import Api
import Api.Model.ItemLight exposing (ItemLight)
import Api.Model.ItemLightList exposing (ItemLightList)
import Api.Model.ItemQuery exposing (ItemQuery)
import Comp.Basic
import Comp.ItemColumnView
import Data.BoxContent exposing (QueryData, SearchQuery(..))
import Data.Flags exposing (Flags)
import Data.ItemColumn as IC exposing (ItemColumn)
import Data.Items
import Data.SearchMode
import Data.UiSettings exposing (UiSettings)
import Html exposing (Html, a, div, i, table, tbody, td, text, th, thead, tr)
import Html.Attributes exposing (class, classList)
import Http
import Messages.Comp.BoxQueryView exposing (Texts)
import Page exposing (Page(..))
import Styles
type alias Model =
{ results : ViewResult
, meta : QueryData
}
type ViewResult
= Loading
| Loaded ItemLightList
| Failed Http.Error
type Msg
= ItemsResp (Result Http.Error ItemLightList)
| ReloadData
init : Flags -> QueryData -> ( Model, Cmd Msg )
init flags data =
( { results = Loading
, meta = data
}
, dataCmd flags data
)
reloadData : Msg
reloadData =
ReloadData
--- Update
update : Flags -> Msg -> Model -> ( Model, Cmd Msg, Bool )
update flags msg model =
case msg of
ItemsResp (Ok list) ->
( { model | results = Loaded list }, Cmd.none, False )
ItemsResp (Err err) ->
( { model | results = Failed err }, Cmd.none, False )
ReloadData ->
( model, dataCmd flags model.meta, True )
--- View
view : Texts -> UiSettings -> Model -> Html Msg
view texts settings model =
case model.results of
Loading ->
div [ class "h-24 " ]
[ Comp.Basic.loadingDimmer
{ label = ""
, active = True
}
]
Failed err ->
div
[ class "py-4"
, class Styles.errorMessage
]
[ text texts.errorOccurred
, text ": "
, text (texts.httpError err)
]
Loaded list ->
if list.groups == [] then
viewEmpty texts
else
viewItems texts settings model.meta list
viewItems : Texts -> UiSettings -> QueryData -> ItemLightList -> Html Msg
viewItems texts settings meta list =
let
items =
Data.Items.flatten list
in
table [ class "w-full divide-y divide-y-2 dark:divide-slate-500" ]
(viewItemHead texts meta ++ [ tbody [ class "divide-y divide-dotted dark:divide-slate-500" ] <| List.map (viewItemRow texts settings meta) items ])
viewItemHead : Texts -> QueryData -> List (Html Msg)
viewItemHead texts meta =
let
( col1, cols ) =
getColumns meta
isSecond n =
n == 1
isNotLast n =
n > 1 && n < List.length cols
in
if not meta.showHeaders then
[]
else
[ thead []
[ tr []
(List.map texts.itemColumn.header (col1 :: cols)
|> List.indexedMap
(\index ->
\n ->
th
[ class "text-left text-sm"
, classList
[ ( "hidden sm:table-cell", isSecond index )
, ( "hidden md:table-cell", isNotLast index )
]
]
[ text n ]
)
)
]
]
viewItemRow : Texts -> UiSettings -> QueryData -> ItemLight -> Html Msg
viewItemRow texts settings meta item =
let
( col1, cols ) =
getColumns meta
isSecond n =
n == 0
isNotLast n =
n > 0 && n < (List.length cols - 1)
render col =
Comp.ItemColumnView.renderDiv
texts.templateCtx
settings
col
[ class "flex flex-row break-all flex-wrap space-x-1" ]
item
td1 =
td [ class "py-2 px-1" ]
[ a
[ class Styles.link
, Page.href (ItemDetailPage item.id)
]
[ render col1
]
]
tdRem index col =
td
[ class "py-1 px-1"
, classList
[ ( "hidden sm:table-cell", isSecond index )
, ( "hidden md:table-cell", isNotLast index )
]
]
[ render col
]
in
tr []
(td1 :: List.indexedMap tdRem cols)
viewEmpty : Texts -> Html Msg
viewEmpty texts =
div [ class "flex justify-center items-center h-full" ]
[ div [ class "px-4 py-4 text-center align-middle text-lg" ]
[ i [ class "fa fa-smile font-thin mr-2" ] []
, text texts.noResults
]
]
--- Helpers
getColumns : QueryData -> ( ItemColumn, List ItemColumn )
getColumns meta =
case meta.columns of
x :: xs ->
( x, xs )
[] ->
( IC.Name, [ IC.Correspondent, IC.DateShort ] )
mkQuery : String -> QueryData -> ItemQuery
mkQuery q meta =
{ query = q
, limit = Just meta.limit
, offset = Nothing
, searchMode = Just <| Data.SearchMode.asString Data.SearchMode.Normal
, withDetails = Just meta.details
}
dataCmd : Flags -> QueryData -> Cmd Msg
dataCmd flags data =
case data.query of
SearchQueryString q ->
Api.itemSearch flags (mkQuery q data) ItemsResp
SearchQueryBookmark bmId ->
Api.itemSearchBookmark flags (mkQuery bmId data) ItemsResp