From bcdb2fc0fee6a50cbb92a7dceb1b8b62011d96af Mon Sep 17 00:00:00 2001
From: Eike Kettner <eike.kettner@posteo.de>
Date: Sun, 22 Nov 2020 22:08:52 +0100
Subject: [PATCH] Show custom field values in item detail header

---
 .../src/main/elm/Comp/CustomFieldInput.elm    |  9 ++-
 .../main/elm/Comp/CustomFieldMultiInput.elm   |  6 +-
 .../src/main/elm/Comp/ItemDetail/View.elm     | 73 ++++++++++++++-----
 modules/webapp/src/main/elm/Data/Icons.elm    | 28 +++++++
 4 files changed, 94 insertions(+), 22 deletions(-)

diff --git a/modules/webapp/src/main/elm/Comp/CustomFieldInput.elm b/modules/webapp/src/main/elm/Comp/CustomFieldInput.elm
index b0ff5137..d9c4fa48 100644
--- a/modules/webapp/src/main/elm/Comp/CustomFieldInput.elm
+++ b/modules/webapp/src/main/elm/Comp/CustomFieldInput.elm
@@ -13,6 +13,7 @@ import Api.Model.CustomField exposing (CustomField)
 import Api.Model.ItemFieldValue exposing (ItemFieldValue)
 import Comp.DatePicker
 import Data.CustomFieldType exposing (CustomFieldType)
+import Data.Icons as Icons
 import Data.Money
 import Date exposing (Date)
 import DatePicker exposing (DatePicker)
@@ -350,7 +351,7 @@ makeInput icon model =
                     ]
                     []
                 , removeButton ""
-                , i [ class (iconOr "pen icon") ] []
+                , i [ class (iconOr <| Icons.customFieldType Data.CustomFieldType.Text) ] []
                 ]
 
         NumberField nm ->
@@ -362,7 +363,7 @@ makeInput icon model =
                     ]
                     []
                 , removeButton ""
-                , i [ class (iconOr "hashtag icon") ] []
+                , i [ class (iconOr <| Icons.customFieldType Data.CustomFieldType.Numeric) ] []
                 ]
 
         MoneyField nm ->
@@ -374,7 +375,7 @@ makeInput icon model =
                     ]
                     []
                 , removeButton ""
-                , i [ class (iconOr "money bill icon") ] []
+                , i [ class (iconOr <| Icons.customFieldType Data.CustomFieldType.Money) ] []
                 ]
 
         BoolField b ->
@@ -397,5 +398,5 @@ makeInput icon model =
             div [ class "ui action left icon input" ]
                 [ Html.map DateMsg (Comp.DatePicker.view v Comp.DatePicker.defaultSettings dp)
                 , removeButton ""
-                , i [ class (iconOr "calendar icon") ] []
+                , i [ class (iconOr <| Icons.customFieldType Data.CustomFieldType.Date) ] []
                 ]
diff --git a/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm b/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm
index e0aadf4e..e443b472 100644
--- a/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm
+++ b/modules/webapp/src/main/elm/Comp/CustomFieldMultiInput.elm
@@ -51,9 +51,13 @@ type alias VisibleField =
 
 visibleFields : Model -> List CustomField
 visibleFields model =
+    let
+        labelThenName cv =
+            Maybe.withDefault cv.name cv.label
+    in
     Dict.toList model.visibleFields
         |> List.map (Tuple.second >> .field)
-        |> List.sortBy .name
+        |> List.sortBy labelThenName
 
 
 currentOptions : List CustomField -> Dict String VisibleField -> List CustomField
diff --git a/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm b/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm
index d819a368..d5dadbf1 100644
--- a/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm
+++ b/modules/webapp/src/main/elm/Comp/ItemDetail/View.elm
@@ -17,6 +17,7 @@ import Comp.LinkTarget
 import Comp.MarkdownInput
 import Comp.SentMails
 import Comp.YesNoDimmer
+import Data.CustomFieldType
 import Data.Direction
 import Data.Fields
 import Data.Icons as Icons
@@ -599,34 +600,72 @@ renderItemInfo settings model =
                     ]
                 ]
             ]
-            :: renderTags settings model
+            :: renderTagsAndFields settings model
         )
 
 
+renderTagsAndFields : UiSettings -> Model -> List (Html Msg)
+renderTagsAndFields settings model =
+    [ div [ class "ui fluid right aligned container" ]
+        (renderTags settings model ++ renderCustomValues settings model)
+    ]
+
+
 renderTags : UiSettings -> Model -> List (Html Msg)
 renderTags settings model =
-    if Data.UiSettings.fieldHidden settings Data.Fields.Tag then
+    let
+        tagView t =
+            Comp.LinkTarget.makeTagLink
+                (IdName t.id t.name)
+                [ ( "ui tag label", True )
+                , ( Data.UiSettings.tagColorString t settings, True )
+                ]
+                SetLinkTarget
+    in
+    if Data.UiSettings.fieldHidden settings Data.Fields.Tag || model.item.tags == [] then
         []
 
     else
-        case model.item.tags of
-            [] ->
-                []
+        List.map tagView model.item.tags
 
-            _ ->
-                [ div [ class "ui right aligned fluid container" ] <|
-                    List.map
-                        (\t ->
-                            Comp.LinkTarget.makeTagLink
-                                (IdName t.id t.name)
-                                [ ( "ui tag label", True )
-                                , ( Data.UiSettings.tagColorString t settings, True )
-                                ]
-                                SetLinkTarget
-                        )
-                        model.item.tags
+
+renderCustomValues : UiSettings -> Model -> List (Html Msg)
+renderCustomValues settings model =
+    let
+        cfIcon cv =
+            Data.CustomFieldType.fromString cv.ftype
+                |> Maybe.map (Icons.customFieldTypeIcon "")
+                |> Maybe.withDefault (i [ class "question circle outline icon" ] [])
+
+        renderBool cv =
+            if cv.value == "true" then
+                i [ class "check icon" ] []
+
+            else
+                i [ class "minus icon" ] []
+
+        fieldView cv =
+            div [ class "ui secondary basic label" ]
+                [ cfIcon cv
+                , Maybe.withDefault cv.name cv.label |> text
+                , div [ class "detail" ]
+                    [ if Data.CustomFieldType.fromString cv.ftype == Just Data.CustomFieldType.Boolean then
+                        renderBool cv
+
+                      else
+                        text cv.value
+                    ]
                 ]
 
+        labelThenName cv =
+            Maybe.withDefault cv.name cv.label
+    in
+    if Data.UiSettings.fieldHidden settings Data.Fields.CustomFields || model.item.customfields == [] then
+        []
+
+    else
+        List.map fieldView (List.sortBy labelThenName model.item.customfields)
+
 
 renderEditMenu : UiSettings -> Model -> List (Html Msg)
 renderEditMenu settings model =
diff --git a/modules/webapp/src/main/elm/Data/Icons.elm b/modules/webapp/src/main/elm/Data/Icons.elm
index 375f11ef..cc5b364f 100644
--- a/modules/webapp/src/main/elm/Data/Icons.elm
+++ b/modules/webapp/src/main/elm/Data/Icons.elm
@@ -7,6 +7,8 @@ module Data.Icons exposing
     , correspondentIcon
     , customField
     , customFieldIcon
+    , customFieldType
+    , customFieldTypeIcon
     , date
     , dateIcon
     , direction
@@ -32,10 +34,36 @@ module Data.Icons exposing
     , tagsIcon
     )
 
+import Data.CustomFieldType exposing (CustomFieldType)
 import Html exposing (Html, i)
 import Html.Attributes exposing (class)
 
 
+customFieldType : CustomFieldType -> String
+customFieldType ftype =
+    case ftype of
+        Data.CustomFieldType.Text ->
+            "pen icon"
+
+        Data.CustomFieldType.Numeric ->
+            "hashtag icon"
+
+        Data.CustomFieldType.Date ->
+            "calendar icon"
+
+        Data.CustomFieldType.Boolean ->
+            "question icon"
+
+        Data.CustomFieldType.Money ->
+            "money bill icon"
+
+
+customFieldTypeIcon : String -> CustomFieldType -> Html msg
+customFieldTypeIcon classes ftype =
+    i [ class (customFieldType ftype ++ " " ++ classes) ]
+        []
+
+
 customField : String
 customField =
     "highlighter icon"