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-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-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-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-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
|
|
|
|
|
|
|
|
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-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" ]
|
|
|
|
|
|
|
|
DocsLazy f ->
|
|
|
|
go (f ())
|
|
|
|
|
|
|
|
DocsList d ->
|
|
|
|
List.concat
|
|
|
|
[ [ Element.text "[" ]
|
|
|
|
, go d
|
|
|
|
, [ Element.text "]" ]
|
|
|
|
]
|
|
|
|
|
|
|
|
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 ")" ]
|
|
|
|
]
|
|
|
|
|
|
|
|
DocsString ->
|
|
|
|
[ Element.text "string" ]
|
|
|
|
|
|
|
|
DocsValue ->
|
|
|
|
[ Element.text "JSON" ]
|
|
|
|
in
|
|
|
|
go
|
|
|
|
>> Element.paragraph
|
|
|
|
[ Font.family [ Font.monospace ]
|
|
|
|
, C.background C.stdPicker.dark.white
|
|
|
|
]
|