defmodule AshHqWeb.Pages.Docs do use Surface.LiveComponent alias Phoenix.LiveView.JS alias AshHqWeb.Components.{CalloutText, DocSidebar, RightNav, Tag} alias AshHqWeb.Routes require Logger prop(params, :map, required: true) prop(change_versions, :event, required: true) prop(selected_versions, :map, required: true) prop(libraries, :list, default: []) prop(uri, :string) prop(sidebar_state, :map, required: true) prop(collapse_sidebar, :event, required: true) prop(expand_sidebar, :event, required: true) data(library, :any) data(extension, :any) data(docs, :any) data(library_version, :any) data(guide, :any) data(doc_path, :list, default: []) data(dsls, :list, default: []) data(dsl, :any) data(options, :list, default: []) data(module, :any) @spec render(any) :: Phoenix.LiveView.Rendered.t() def render(assigns) do ~F"""
Name | Type | Doc | Links |
---|---|---|---|
{option.type} | {raw(render_replacements(assigns, AshHq.Docs.Extensions.RenderMarkdown.render!(option, :doc)))} | {raw(Enum.map_join(List.flatten(Map.values(option.links || %{})), ", ", &render_links("{{link:#{&1}}}", assigns)))} |
Name | Type | Doc | Links | |
---|---|---|---|---|
{option.type} | {render_tags(assigns, option)} | {raw(render_replacements(assigns, AshHq.Docs.Extensions.RenderMarkdown.render!(option, :doc)))} | {raw(Enum.map_join(List.flatten(Map.values(option.links || %{})), ", ", &render_links("{{link:#{&1}}}", assigns)))} |
{#for head <- function.heads}
{head}
{/for}
{raw(render_replacements(assigns, AshHq.Docs.Extensions.RenderMarkdown.render!(function, :doc)))}
){{link:.*}}(?!<\/code>)/, fn text ->
try do
"{{link:" <> rest = String.trim_trailing(text, "}}")
[library, type, item] = String.split(rest, ":")
render_link(assigns, library, type, item, text)
rescue
e ->
Logger.error("Invalid link #{inspect(e)}")
text
end
end)
end
defp render_link(assigns, library, type, item, source) do
library =
Enum.find(assigns[:libraries], &(&1.name == library)) ||
raise "No such library in link: #{source}"
selected_versions = assigns[:selected_versions]
version =
if selected_versions[library.id] == "latest" do
Enum.find(library.versions, &String.contains?(&1.version, ".")) ||
Enum.at(library.versions, 0)
else
case Enum.find(library.versions, &(&1.id == selected_versions[library.id])) do
nil ->
nil
version ->
version
end
end
if is_nil(version) do
raise "no version for library"
else
case type do
"guide" ->
guide =
Enum.find(version.guides, &(&1.name == item)) ||
raise "No such guide in link: #{source}"
"""
#{item}
"""
"dsl" ->
name =
item
|> String.split("/")
|> Enum.join(".")
"""
#{name}
"""
"module" ->
"""
#{item}
"""
"extension" ->
"""
#{item}
"""
type ->
raise "unimplemented link type #{inspect(type)} in #{source}"
end
end
end
defp assign_extension(socket) do
if socket.assigns.library_version && socket.assigns[:params]["extension"] do
extensions = socket.assigns.library_version.extensions
assign(socket,
extension:
Enum.find(extensions, fn extension ->
Routes.sanitize_name(extension.name) == socket.assigns[:params]["extension"]
end)
)
else
assign(socket, :extension, nil)
end
end
def mount(socket) do
{:ok, socket}
end
defp assign_library(socket) do
if !socket.assigns[:library] ||
socket.assigns.params["library"] != Routes.sanitize_name(socket.assigns.library.name) do
case Enum.find(
socket.assigns.libraries,
&(Routes.sanitize_name(&1.name) == socket.assigns.params["library"])
) do
nil ->
assign(socket, library: nil, library_version: nil)
library ->
socket =
if socket.assigns[:params]["version"] do
library_version =
case socket.assigns[:params]["version"] do
"latest" ->
Enum.find(library.versions, &String.contains?(&1.version, ".")) ||
Enum.at(library.versions, 0)
version ->
Enum.find(
library.versions,
&(Routes.sanitize_name(&1.version) == version)
)
end
if library_version do
new_selected_versions =
Map.put(socket.assigns.selected_versions, library.id, library_version.id)
assign(
socket,
selected_versions: new_selected_versions,
library_version: library_version
)
|> push_event("selected-versions", new_selected_versions)
else
assign(socket, :library_version, nil)
end
else
assign(socket, :library_version, nil)
end
assign(socket, :library, library)
end
else
socket
end
end
end