elm-matrix-sdk-beta/dev/DocsDisplay.elm

425 lines
12 KiB
Elm
Raw Permalink Normal View History

2024-01-23 12:41:19 +00:00
module DocsDisplay exposing (..)
2024-01-23 17:45:19 +00:00
import Colors as C
2024-01-23 12:41:19 +00:00
import Element exposing (Element)
2024-01-23 17:45:19 +00:00
import Element.Border as Border
import Element.Events as Events
2024-01-23 12:41:19 +00:00
import Element.Font as Font
2024-01-23 17:45:19 +00:00
import Element.Region as Region
import Html.Attributes
import Internal.Tools.Json as Json exposing (Docs(..))
2024-01-23 12:41:19 +00:00
import Widget.Material.Typography as Typography
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
type alias DObject =
{ name : String
, description : List String
, keys :
List
{ field : String
, description : List String
, required : Json.RequiredField
, content : Docs
}
}
2024-01-23 17:45:19 +00:00
render : Docs -> Element String
render docs =
2024-01-23 12:41:19 +00:00
docs
|> findObjects
|> List.map
(\dobject ->
2024-01-23 17:45:19 +00:00
Element.column
[ Element.width Element.fill
, Element.spacing 12
]
[ Element.el
(List.append
[ Region.heading 3
, Element.htmlAttribute <| Html.Attributes.id dobject.name
]
Typography.h3
)
(Element.text dobject.name)
2024-01-23 12:41:19 +00:00
, dobject.description
|> List.map (Element.text >> List.singleton >> Element.paragraph [])
|> Element.column []
2024-01-23 17:45:19 +00:00
, toTable dobject
2024-01-23 12:41:19 +00:00
]
)
|> List.append
[ Element.paragraph []
[ Element.text "This coder decodes to "
2024-01-23 17:45:19 +00:00
, toString docs
2024-01-23 12:41:19 +00:00
]
2024-01-23 17:45:19 +00:00
, showFunctions (getFunctions docs)
]
|> Element.column
[ Element.spacing 20
, Element.width Element.fill
2024-01-23 12:41:19 +00:00
]
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
findObjects : Docs -> List DObject
findObjects docs =
bfs [ docs ] []
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
bfs : List Docs -> List DObject -> List DObject
bfs queue acc =
case queue of
[] ->
acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
head :: tail ->
case head of
DocsBool ->
bfs tail acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsDict d ->
bfs (d :: tail) acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsFloat ->
bfs tail acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsInt ->
bfs tail acc
2024-04-10 06:00:21 +00:00
DocsIntDict d ->
bfs (d :: tail) acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsLazy f ->
bfs (f () :: tail) acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsList d ->
bfs (d :: tail) acc
2024-04-10 06:00:21 +00:00
DocsListWithOne d ->
bfs (d :: tail) acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsMap { content } ->
bfs (content :: tail) acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsObject dobject ->
if List.any (\item -> item.name == dobject.name) acc then
bfs tail acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
else
bfs
(List.append tail (List.map .content dobject.keys))
(List.append acc [ dobject ])
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsOptional d ->
bfs (d :: tail) acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsRiskyMap { content } ->
bfs (content :: tail) acc
2024-04-10 06:00:21 +00:00
DocsSet d ->
bfs (d :: tail) acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsString ->
bfs tail acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsValue ->
bfs tail acc
2024-01-23 17:45:19 +00:00
toTable : DObject -> Element String
toTable dobject =
let
toCell : Element String -> Int -> Element String
toCell content i =
Element.el
[ if (i |> modBy 2) == 0 then
C.background C.stdPicker.light.white
else
C.background C.stdPicker.medium.white
, Element.padding 3
]
content
header : String -> Element msg
header t =
t
|> Element.text
|> Element.el
[ Element.height Element.fill
, Element.width Element.fill
, Font.bold
]
in
Element.indexedTable
[ C.background <| C.stdPicker.light.white ]
{ data = dobject.keys
2024-01-23 12:41:19 +00:00
, columns =
2024-01-23 17:45:19 +00:00
[ { header = header "Field"
, width = Element.fillPortion 1
, view = \i item -> toCell (Element.text item.field) i
}
, { header = header "Type"
, width = Element.fillPortion 1
, view = \i item -> toCell (toString item.content) i
}
, { header = header "Description"
, width = Element.fillPortion 3
, view = \i item -> showDescription i item
}
2024-01-23 12:41:19 +00:00
]
}
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
{-| Show the description of a field in a table column.
-}
2024-01-23 17:45:19 +00:00
showDescription : Int -> { a | content : Docs, description : List String, required : Json.RequiredField } -> Element msg
showDescription i { content, description, required } =
Element.column
[ if (i |> modBy 2) == 0 then
C.background C.stdPicker.light.white
else
C.background C.stdPicker.medium.white
, Element.padding 3
]
-- Field description
[ case description of
[] ->
Element.paragraph []
[ Element.el [ Font.bold ] <| Element.text "WARNING: "
, Element.text "This field has no documentation yet!"
2024-01-23 12:41:19 +00:00
]
2024-01-23 17:45:19 +00:00
head :: tail ->
Element.column [ Element.width Element.fill ]
(List.append
[ Element.paragraph []
[ Element.el [ Font.bold ] <|
Element.text
(case required of
Json.RequiredField ->
"Required: "
_ ->
""
)
, Element.text head
2024-01-23 12:41:19 +00:00
]
]
2024-01-23 17:45:19 +00:00
(List.map
(Element.text
>> List.singleton
>> Element.paragraph []
)
tail
)
2024-01-23 12:41:19 +00:00
)
2024-01-23 17:45:19 +00:00
-- Additional function descriptions
, showFunctions (getFunctions content)
]
showFunctions : List { name : String, description : List String } -> Element msg
showFunctions functions =
functions
|> List.indexedMap
(\i f ->
let
name : C.AllNames C.Color -> C.Color
name =
case modBy 5 i of
0 ->
.primary
1 ->
.secondary
2 ->
.tertiary
3 ->
.quaternary
_ ->
.extra
in
Element.column
[ Border.rounded 15
, C.background (name <| C.stdPicker.light)
, C.border <| name <| C.stdPicker.dark
, Border.width 2
, Element.padding 5
]
((f.name
|> (++) "Function "
|> Element.text
|> Element.el [ Font.bold ]
)
:: List.map
(Element.text
>> List.singleton
>> Element.paragraph []
)
f.description
)
)
|> Element.column
[ Element.padding 5
, Element.spacing 5
, Element.width Element.fill
]
{-| Gather all the untranslatable functions that are hidden in the coders
2024-01-23 12:41:19 +00:00
-}
2024-01-23 17:45:19 +00:00
getFunctions : Docs -> List { name : String, description : List String }
getFunctions docs =
getFunctionBFS docs []
getFunctionBFS : Docs -> List { name : String, description : List String } -> List { name : String, description : List String }
getFunctionBFS docs acc =
2024-01-23 12:41:19 +00:00
case docs of
DocsBool ->
2024-01-23 17:45:19 +00:00
acc
2024-01-23 12:41:19 +00:00
DocsDict d ->
2024-01-23 17:45:19 +00:00
getFunctionBFS d acc
2024-01-23 12:41:19 +00:00
DocsFloat ->
2024-01-23 17:45:19 +00:00
acc
2024-01-23 12:41:19 +00:00
DocsInt ->
2024-01-23 17:45:19 +00:00
acc
2024-04-10 06:00:21 +00:00
DocsIntDict d ->
getFunctionBFS d acc
2024-01-23 17:45:19 +00:00
2024-01-23 12:41:19 +00:00
DocsLazy f ->
2024-01-23 17:45:19 +00:00
getFunctionBFS (f ()) acc
2024-01-23 12:41:19 +00:00
DocsList d ->
2024-01-23 17:45:19 +00:00
getFunctionBFS d acc
2024-04-10 06:00:21 +00:00
DocsListWithOne d ->
getFunctionBFS d acc
2024-01-23 17:45:19 +00:00
DocsMap { name, description, content } ->
getFunctionBFS
content
(List.append acc [ { name = name, description = description } ])
DocsObject _ ->
acc
2024-01-23 12:41:19 +00:00
DocsOptional d ->
2024-01-23 17:45:19 +00:00
getFunctionBFS d acc
DocsRiskyMap { name, description, content } ->
getFunctionBFS
content
(List.append acc [ { name = name, description = description } ])
2024-04-10 06:00:21 +00:00
DocsSet d ->
getFunctionBFS d acc
2024-01-23 12:41:19 +00:00
DocsString ->
2024-01-23 17:45:19 +00:00
acc
2024-01-23 12:41:19 +00:00
DocsValue ->
2024-01-23 17:45:19 +00:00
acc
{-| Write JSON type as a string.
-}
toString : Docs -> Element String
toString =
let
go : Docs -> List (Element String)
go docs =
case docs of
DocsBool ->
[ Element.text "bool" ]
DocsDict d ->
List.concat
[ [ Element.text "{string:" ]
, go d
, [ Element.text "}" ]
]
DocsFloat ->
[ Element.text "float" ]
DocsInt ->
[ Element.text "int" ]
2024-04-10 06:00:21 +00:00
DocsIntDict d ->
List.concat
[ [ Element.text "{int:" ]
, go d
, [ Element.text "}" ]
]
2024-01-23 17:45:19 +00:00
DocsLazy f ->
go (f ())
DocsList d ->
List.concat
[ [ Element.text "[" ]
, go d
, [ Element.text "]" ]
]
2024-04-10 06:00:21 +00:00
DocsListWithOne d ->
List.concat
[ [ Element.text "[" ]
, go d
, [ Element.text "]" ]
]
2024-01-23 17:45:19 +00:00
DocsMap { name, content } ->
List.concat
[ [ Element.text name, Element.text "(" ]
, go content
, [ Element.text ")" ]
]
DocsObject { name } ->
name
|> Element.text
|> Element.el
[ Events.onClick name ]
|> List.singleton
DocsOptional d ->
go d
DocsRiskyMap { name, content } ->
List.concat
[ [ Element.text name, Element.text "(" ]
, go content
, [ Element.text ")" ]
]
2024-04-10 06:00:21 +00:00
DocsSet content ->
List.concat
[ [ Element.text "set(" ]
, go content
, [ Element.text ")" ]
]
2024-01-23 17:45:19 +00:00
DocsString ->
[ Element.text "string" ]
DocsValue ->
[ Element.text "JSON" ]
in
go
>> Element.paragraph
[ Font.family [ Font.monospace ]
, C.background C.stdPicker.dark.white
]