mirror of
https://github.com/ash-project/ash_hq.git
synced 2024-09-19 21:03:30 +12:00
WIP: trying to figure out flickering
This commit is contained in:
parent
068a03efa2
commit
c6c05c0fa1
15 changed files with 507 additions and 157 deletions
|
@ -4,7 +4,6 @@
|
|||
@import "tailwindcss/utilities";
|
||||
|
||||
@import "syntax.css";
|
||||
@import "markdown.css";
|
||||
|
||||
.search-hit {
|
||||
color: #fb923c
|
||||
|
|
|
@ -71,10 +71,23 @@ let liveSocket = new LiveSocket("/live", Socket, {
|
|||
}
|
||||
});
|
||||
|
||||
// Show progress bar on live navigation and form submits
|
||||
// Show progress bar on live navigation and form submits. Only displays if still
|
||||
// loading after 120 msec
|
||||
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
|
||||
window.addEventListener("phx:page-loading-start", info => topbar.show())
|
||||
window.addEventListener("phx:page-loading-stop", info => topbar.hide())
|
||||
|
||||
let topBarScheduled = undefined;
|
||||
window.addEventListener("phx:page-loading-start", () => {
|
||||
if(!topBarScheduled) {
|
||||
topBarScheduled = setTimeout(() => topbar.show(), 120);
|
||||
};
|
||||
});
|
||||
window.addEventListener("phx:page-loading-stop", () => {
|
||||
clearTimeout(topBarScheduled);
|
||||
topBarScheduled = undefined;
|
||||
topbar.hide();
|
||||
});
|
||||
|
||||
|
||||
window.addEventListener("js:focus", e => e.target.focus())
|
||||
window.addEventListener("js:noscroll-main", e => {
|
||||
if(e.target.style.display === "none") {
|
||||
|
|
|
@ -2,7 +2,7 @@ const colors = require('tailwindcss/colors')
|
|||
|
||||
module.exports = {
|
||||
mode: "jit",
|
||||
purge: ["./js/**/*.js", "../lib/*_web/**/*.*ex"],
|
||||
content: ["./js/**/*.js", "../lib/*_web/**/*.*ex"],
|
||||
darkMode: "class",
|
||||
theme: {
|
||||
extend: {
|
||||
|
|
|
@ -17,6 +17,7 @@ defmodule AshHq.Docs.Extensions.RenderMarkdown.Changes.RenderMarkdown do
|
|||
)
|
||||
|
||||
{:ok, html_doc, _} ->
|
||||
html_doc = AshHq.Docs.Extensions.RenderMarkdown.Highlighter.highlight(html_doc)
|
||||
Ash.Changeset.force_change_attribute(changeset, opts[:destination], html_doc)
|
||||
end
|
||||
else
|
||||
|
|
55
lib/ash_hq/docs/extensions/render_markdown/highlighter.ex
Normal file
55
lib/ash_hq/docs/extensions/render_markdown/highlighter.ex
Normal file
|
@ -0,0 +1,55 @@
|
|||
defmodule AshHq.Docs.Extensions.RenderMarkdown.Highlighter do
|
||||
@moduledoc false
|
||||
# Copied *directly* from nimble_publisher
|
||||
# https://github.com/dashbitco/nimble_publisher/blob/v0.1.2/lib/nimble_publisher/highlighter.ex
|
||||
|
||||
@doc """
|
||||
Highlights all code block in an already generated HTML document.
|
||||
"""
|
||||
def highlight(html) do
|
||||
Regex.replace(
|
||||
~r/<pre><code(?:\s+class="(\w*)")?>([^<]*)<\/code><\/pre>/,
|
||||
html,
|
||||
&highlight_code_block(&1, &2, &3)
|
||||
)
|
||||
end
|
||||
|
||||
defp highlight_code_block(full_block, lang, code) do
|
||||
case pick_language_and_lexer(lang) do
|
||||
{_language, nil, _opts} -> full_block
|
||||
{language, lexer, opts} -> render_code(language, lexer, opts, code)
|
||||
end
|
||||
end
|
||||
|
||||
defp pick_language_and_lexer(""), do: {"text", nil, []}
|
||||
|
||||
defp pick_language_and_lexer(lang) do
|
||||
case Makeup.Registry.fetch_lexer_by_name(lang) do
|
||||
{:ok, {lexer, opts}} -> {lang, lexer, opts}
|
||||
:error -> {lang, nil, []}
|
||||
end
|
||||
end
|
||||
|
||||
defp render_code(lang, lexer, lexer_opts, code) do
|
||||
highlighted =
|
||||
code
|
||||
|> unescape_html()
|
||||
|> IO.iodata_to_binary()
|
||||
|> Makeup.highlight_inner_html(
|
||||
lexer: lexer,
|
||||
lexer_options: lexer_opts,
|
||||
formatter_options: [highlight_tag: "span"]
|
||||
)
|
||||
|
||||
~s(<pre><code class="makeup #{lang}">#{highlighted}</code></pre>)
|
||||
end
|
||||
|
||||
entities = [{"&", ?&}, {"<", ?<}, {">", ?>}, {""", ?"}, {"'", ?'}]
|
||||
|
||||
for {encoded, decoded} <- entities do
|
||||
defp unescape_html(unquote(encoded) <> rest), do: [unquote(decoded) | unescape_html(rest)]
|
||||
end
|
||||
|
||||
defp unescape_html(<<c, rest::binary>>), do: [c | unescape_html(rest)]
|
||||
defp unescape_html(<<>>), do: []
|
||||
end
|
|
@ -1,6 +1,15 @@
|
|||
defmodule AshHq.Docs.Extension do
|
||||
use AshHq.Resource,
|
||||
data_layer: AshPostgres.DataLayer
|
||||
data_layer: AshPostgres.DataLayer,
|
||||
extensions: [AshHq.Docs.Extensions.Search, AshHq.Docs.Extensions.RenderMarkdown]
|
||||
|
||||
render_markdown do
|
||||
render_attributes doc: :html_doc
|
||||
end
|
||||
|
||||
# search :load_for_search do
|
||||
|
||||
# end
|
||||
|
||||
postgres do
|
||||
table "extensions"
|
||||
|
@ -50,6 +59,13 @@ defmodule AshHq.Docs.Extension do
|
|||
|
||||
attribute :doc, :string do
|
||||
allow_nil? false
|
||||
constraints trim?: false, allow_empty?: true
|
||||
default ""
|
||||
end
|
||||
|
||||
attribute :doc_html, :string do
|
||||
constraints trim?: false, allow_empty?: true
|
||||
writable? false
|
||||
end
|
||||
|
||||
attribute :type, :string do
|
||||
|
|
148
lib/ash_hq_web/components/doc_sidebar.ex
Normal file
148
lib/ash_hq_web/components/doc_sidebar.ex
Normal file
|
@ -0,0 +1,148 @@
|
|||
defmodule AshHqWeb.Components.DocSidebar do
|
||||
use Surface.Component
|
||||
|
||||
alias AshHqWeb.Routes
|
||||
alias Surface.Components.LiveRedirect
|
||||
|
||||
prop class, :css_class, default: ""
|
||||
prop libraries, :list, required: true
|
||||
prop extension, :any, default: nil
|
||||
prop guide, :any, default: nil
|
||||
prop library, :any, default: nil
|
||||
prop library_version, :any, default: nil
|
||||
prop selected_versions, :map, default: %{}
|
||||
prop id, :string, required: true
|
||||
|
||||
def render(assigns) do
|
||||
~F"""
|
||||
<aside id={@id} class={"w-64 h-full block", @class} aria-label="Sidebar">
|
||||
<div class="overflow-y-auto py-4 px-3">
|
||||
<ul class="space-y-2">
|
||||
{#for library <- @libraries}
|
||||
<li>
|
||||
<LiveRedirect
|
||||
to={Routes.library_link(library, selected_version_name(library, @selected_versions))}
|
||||
class={
|
||||
"flex items-center p-2 text-base font-normal text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700",
|
||||
"dark:bg-gray-600": !@extension && @library && library.id == @library.id
|
||||
}
|
||||
>
|
||||
<Heroicons.Outline.CollectionIcon class="w-6 h-6" />
|
||||
<span class="ml-3 mr-2">{library.display_name}</span>
|
||||
<span class="font-light text-gray-500">{selected_version_name(library, @selected_versions)}</span>
|
||||
</LiveRedirect>
|
||||
{#if @library && @library_version && library.id == @library.id}
|
||||
{#if !Enum.empty?(@library_version.guides)}
|
||||
<div class="ml-2 text-gray-500">
|
||||
Guides
|
||||
</div>
|
||||
{/if}
|
||||
{#for guide <- @library_version.guides}
|
||||
<li class="ml-3">
|
||||
<LiveRedirect
|
||||
to={Routes.guide_link(
|
||||
library,
|
||||
selected_version_name(library, @selected_versions),
|
||||
guide.url_safe_name
|
||||
)}
|
||||
class={
|
||||
"flex items-center p-1 text-base font-normal text-gray-900 rounded-lg dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700",
|
||||
"dark:bg-gray-600": @guide && @guide.id == guide.id
|
||||
}
|
||||
>
|
||||
<Heroicons.Outline.BookOpenIcon class="h-4 w-4" />
|
||||
<span class="ml-3 mr-2">{guide.name}</span>
|
||||
</LiveRedirect>
|
||||
</li>
|
||||
{/for}
|
||||
|
||||
{#if !Enum.empty?(@library_version.guides)}
|
||||
<div class="ml-2 text-gray-500">
|
||||
Extensions
|
||||
</div>
|
||||
{/if}
|
||||
{#for extension <- get_extensions(library, @selected_versions)}
|
||||
<li class="ml-3">
|
||||
<LiveRedirect
|
||||
to={Routes.extension_link(library, selected_version_name(library, @selected_versions), extension.name)}
|
||||
class={
|
||||
"flex items-center p-1 text-base font-normal text-gray-900 rounded-lg dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700",
|
||||
"dark:bg-gray-600": @extension && @extension.id == extension.id
|
||||
}
|
||||
>
|
||||
{render_icon(assigns, extension.type)}
|
||||
<span class="ml-3 mr-2">{extension.name}</span>
|
||||
</LiveRedirect>
|
||||
</li>
|
||||
{/for}
|
||||
{/if}
|
||||
</li>
|
||||
{/for}
|
||||
</ul>
|
||||
</div>
|
||||
</aside>
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "Resource") do
|
||||
~F"""
|
||||
<Heroicons.Outline.ServerIcon class="h-4 w-4" />
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "Api") do
|
||||
~F"""
|
||||
<Heroicons.Outline.SwitchHorizontalIcon class="h-4 w-4" />
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "DataLayer") do
|
||||
~F"""
|
||||
<Heroicons.Outline.DatabaseIcon class="h-4 w-4" />
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "Flow") do
|
||||
~F"""
|
||||
<Heroicons.Outline.MapIcon class="h-4 w-4" />
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "Notifier") do
|
||||
~F"""
|
||||
<Heroicons.Outline.MailIcon class="h-4 w-4" />
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "Registry") do
|
||||
~F"""
|
||||
<Heroicons.Outline.ViewListIcon class="h-4 w-4" />
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, _) do
|
||||
~F"""
|
||||
<Heroicons.Outline.PuzzleIcon class="h-4 w-4" />
|
||||
"""
|
||||
end
|
||||
|
||||
defp selected_version_name(library, selected_versions) do
|
||||
case Enum.find(library.versions, &(&1.id == selected_versions[library.id])) do
|
||||
nil ->
|
||||
nil
|
||||
|
||||
version ->
|
||||
version.version
|
||||
end
|
||||
end
|
||||
|
||||
defp get_extensions(library, selected_versions) do
|
||||
case Enum.find(library.versions, &(&1.id == selected_versions[library.id])) do
|
||||
nil ->
|
||||
[]
|
||||
|
||||
version ->
|
||||
version.extensions
|
||||
end
|
||||
end
|
||||
end
|
|
@ -23,7 +23,7 @@ defmodule AshHqWeb.Components.Search do
|
|||
<div
|
||||
id={@id}
|
||||
style="display: none;"
|
||||
class="transition absolute flex justify-center align-middle w-screen h-screen backdrop-blur-sm pb-8 bg-white bg-opacity-10"
|
||||
class="absolute flex justify-center align-middle w-screen h-screen backdrop-blur-sm pb-8 bg-white bg-opacity-10"
|
||||
phx-hook="CmdK"
|
||||
>
|
||||
<div
|
||||
|
@ -126,7 +126,8 @@ defmodule AshHqWeb.Components.Search do
|
|||
"bg-gray-800": @selected_item.id != item.id
|
||||
}
|
||||
>
|
||||
{#if item.__struct__ != AshHq.Docs.LibraryVersion && item.name != List.last(Map.get(results, :path, []))}
|
||||
{#if item.__struct__ != AshHq.Docs.LibraryVersion &&
|
||||
item.name != List.last(Map.get(results, :path, []))}
|
||||
{item.name}
|
||||
{/if}
|
||||
{#if item.__struct__ == AshHq.Docs.LibraryVersion}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
defmodule AshHqWeb.Pages.Docs do
|
||||
use Surface.LiveComponent
|
||||
|
||||
alias AshHqWeb.Routes
|
||||
alias Surface.Components.LiveRedirect
|
||||
alias Phoenix.LiveView.JS
|
||||
alias AshHqWeb.Components.DocSidebar
|
||||
|
||||
prop params, :map, required: true
|
||||
prop change_versions, :event, required: true
|
||||
|
@ -14,112 +14,75 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
data docs, :any
|
||||
data library_version, :any
|
||||
data guide, :any
|
||||
data doc_path, :list, default: []
|
||||
|
||||
@spec render(any) :: Phoenix.LiveView.Rendered.t()
|
||||
def render(assigns) do
|
||||
~F"""
|
||||
<div class="flex flex-row h-full dark:bg-dark-grid justify-center">
|
||||
<aside class="w-64 h-full" aria-label="Sidebar">
|
||||
<div class="overflow-y-auto py-4 px-3">
|
||||
<ul class="space-y-2">
|
||||
{#for library <- @libraries}
|
||||
<li>
|
||||
<LiveRedirect
|
||||
to={Routes.library_link(library, selected_version_name(library, @selected_versions))}
|
||||
class={"flex items-center p-2 text-base font-normal text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700", "dark:bg-gray-600": !@extension && @library && library.id == @library.id}
|
||||
>
|
||||
<Heroicons.Outline.CollectionIcon class="w-6 h-6" />
|
||||
<span class="ml-3 mr-2">{library.display_name}</span>
|
||||
<span class="font-light text-gray-500">{selected_version_name(library, @selected_versions)}</span>
|
||||
</LiveRedirect>
|
||||
{#if @library && @library_version && library.id == @library.id}
|
||||
{#if !Enum.empty?(@library_version.guides)}
|
||||
<div class="ml-2 text-gray-500">
|
||||
Guides
|
||||
<div class="h-full w-full flex flex-col bg-light-grid dark:bg-dark-grid">
|
||||
<div class="md:hidden flex flex-row justify-start space-x-12 mt-2 items-center border-b border-t border-gray-600 py-3 mb-10">
|
||||
<button class="dark:hover:text-gray-600" phx-click={show_sidebar()}>
|
||||
<Heroicons.Outline.MenuIcon class="w-8 h-8 ml-4" />
|
||||
</button>
|
||||
{#if @doc_path && @doc_path != []}
|
||||
<div class="flex flex-row space-x-1 items-center">
|
||||
{#case @doc_path}
|
||||
{#match [item]}
|
||||
<div class="dark:text-white">
|
||||
{item}
|
||||
</div>
|
||||
{#match path}
|
||||
{#for item <- :lists.droplast(path)}
|
||||
<span class="text-gray-500">
|
||||
{item}</span>
|
||||
<Heroicons.Outline.ChevronRightIcon class="w-3 h-3" />
|
||||
{/for}
|
||||
<span class="dark:text-white" />
|
||||
{/case}
|
||||
</div>
|
||||
{/if}
|
||||
{#for guide <- @library_version.guides}
|
||||
<li class="ml-3">
|
||||
<LiveRedirect
|
||||
to={Routes.guide_link(library, selected_version_name(library, @selected_versions), guide.url_safe_name)}
|
||||
class={"flex items-center p-1 text-base font-normal text-gray-900 rounded-lg dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700", "dark:bg-gray-600": @guide && @guide.id == guide.id}
|
||||
>
|
||||
<Heroicons.Outline.BookOpenIcon class="h-4 w-4"/>
|
||||
<span class="ml-3 mr-2">{guide.name}</span>
|
||||
</LiveRedirect>
|
||||
</li>
|
||||
{/for}
|
||||
|
||||
{#if !Enum.empty?(@library_version.guides)}
|
||||
<div class="ml-2 text-gray-500">
|
||||
Extensions
|
||||
</div>
|
||||
{/if}
|
||||
{#for extension <- get_extensions(library, @selected_versions)}
|
||||
<li class="ml-3">
|
||||
<LiveRedirect
|
||||
to={Routes.extension_link(library, selected_version_name(library, @selected_versions), extension.name)}
|
||||
class={"flex items-center p-1 text-base font-normal text-gray-900 rounded-lg dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700", "dark:bg-gray-600": @extension && @extension.id == extension.id}
|
||||
>
|
||||
{render_icon(assigns, extension.type)}
|
||||
<span class="ml-3 mr-2">{extension.name}</span>
|
||||
</LiveRedirect>
|
||||
</li>
|
||||
|
||||
{/for}
|
||||
{/if}
|
||||
</li>
|
||||
{/for}
|
||||
</ul>
|
||||
<div id="mobile-sidebar-container" class="hidden md:hidden relative w-screen h-full backdrop-blur-lg transition">
|
||||
<div>
|
||||
<DocSidebar
|
||||
id="mobile-sidebar"
|
||||
class="absolute left-0 top-0"
|
||||
libraries={@libraries}
|
||||
extension={@extension}
|
||||
guide={@guide}
|
||||
library={@library}
|
||||
library_version={@library_version}
|
||||
selected_versions={@selected_versions}
|
||||
/>
|
||||
</div>
|
||||
</aside>
|
||||
</div>
|
||||
<div class="grow flex flex-row h-full justify-center space-x-12">
|
||||
<DocSidebar
|
||||
id="sidebar"
|
||||
class="hidden md:block"
|
||||
libraries={@libraries}
|
||||
extension={@extension}
|
||||
guide={@guide}
|
||||
library={@library}
|
||||
library_version={@library_version}
|
||||
selected_versions={@selected_versions}
|
||||
/>
|
||||
<div class="grow w-full prose prose-zinc md:prose-lg lg:prose-xl dark:prose-invert">
|
||||
{raw(@docs)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "Resource") do
|
||||
~F"""
|
||||
<Heroicons.Outline.ServerIcon class="h-4 w-4"/>
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "Api") do
|
||||
~F"""
|
||||
<Heroicons.Outline.SwitchHorizontalIcon class="h-4 w-4"/>
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "DataLayer") do
|
||||
~F"""
|
||||
<Heroicons.Outline.DatabaseIcon class="h-4 w-4"/>
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "Flow") do
|
||||
~F"""
|
||||
<Heroicons.Outline.MapIcon class="h-4 w-4"/>
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "Notifier") do
|
||||
~F"""
|
||||
<Heroicons.Outline.MailIcon class="h-4 w-4"/>
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, "Registry") do
|
||||
~F"""
|
||||
<Heroicons.Outline.ViewListIcon class="h-4 w-4"/>
|
||||
"""
|
||||
end
|
||||
|
||||
def render_icon(assigns, _) do
|
||||
~F"""
|
||||
<Heroicons.Outline.PuzzleIcon class="h-4 w-4"/>
|
||||
"""
|
||||
def show_sidebar() do
|
||||
%JS{}
|
||||
|> JS.toggle(
|
||||
to: "#mobile-sidebar-container",
|
||||
in: {"fade-in duration-100 transition", "hidden", "block"},
|
||||
out: {"fade-out duration-100 transition", "block", "hidden"},
|
||||
time: 100
|
||||
)
|
||||
end
|
||||
|
||||
def update(assigns, socket) do
|
||||
|
@ -131,16 +94,6 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
|> assign_docs()}
|
||||
end
|
||||
|
||||
defp selected_version_name(library, selected_versions) do
|
||||
case Enum.find(library.versions, &(&1.id == selected_versions[library.id])) do
|
||||
nil ->
|
||||
nil
|
||||
|
||||
version ->
|
||||
version.version
|
||||
end
|
||||
end
|
||||
|
||||
defp assign_guide(socket) do
|
||||
guide =
|
||||
if socket.assigns[:params]["guide"] && socket.assigns.library_version do
|
||||
|
@ -155,16 +108,25 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
defp assign_docs(socket) do
|
||||
cond do
|
||||
socket.assigns.extension ->
|
||||
assign(socket, :docs, Earmark.as_html!(socket.assigns.extension.doc))
|
||||
assign(socket,
|
||||
docs: Earmark.as_html!(socket.assigns.extension.doc),
|
||||
doc_path: [socket.assigns.library.name, socket.assigns.extension.name]
|
||||
)
|
||||
|
||||
socket.assigns.guide ->
|
||||
assign(socket, :docs, Earmark.as_html!(socket.assigns.guide.text))
|
||||
assign(socket,
|
||||
docs: Earmark.as_html!(socket.assigns.guide.text),
|
||||
doc_path: [socket.assigns.library.name, socket.assigns.guide.name]
|
||||
)
|
||||
|
||||
socket.assigns.library_version ->
|
||||
assign(socket, :docs, Earmark.as_html!(socket.assigns.library_version.doc))
|
||||
assign(socket,
|
||||
docs: Earmark.as_html!(socket.assigns.library_version.doc),
|
||||
doc_path: [socket.assigns.library.name]
|
||||
)
|
||||
|
||||
true ->
|
||||
assign(socket, :docs, "")
|
||||
assign(socket, docs: "", doc_path: [])
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -207,25 +169,6 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
end
|
||||
end
|
||||
|
||||
# defp render_sub_item_nav(assigns, library, path \\ []) do
|
||||
# ~F"""
|
||||
# <ul class="space-y-2">
|
||||
# {#for %{path: ^path, name: name} = dsl <- library.dsls}
|
||||
# <li class="ml-2">
|
||||
# <LiveRedirect
|
||||
# to={Routes.doc_link(dsl)}
|
||||
# class="flex items-center p-2 text-base font-normal text-gray-900 rounded-lg dark:text-white hover:bg-gray-100 dark:hover:bg-gray-700"
|
||||
# >
|
||||
# <Heroicons.Outline.CollectionIcon class="w-6 h-6" />
|
||||
# <span class="ml-3 mr-2">{library.display_name}</span>
|
||||
# <span class="font-light text-gray-500">{selected_version_name(library, @selected_versions)}</span>
|
||||
# </LiveRedirect>
|
||||
# </li>
|
||||
# {/for}
|
||||
# </ul>
|
||||
# """
|
||||
# end
|
||||
|
||||
defp assign_library(socket) do
|
||||
if !socket.assigns[:library] ||
|
||||
socket.assigns.params["library"] != socket.assigns.library.name do
|
||||
|
|
|
@ -26,11 +26,7 @@ defmodule AshHqWeb.AppViewLive do
|
|||
change_versions="change-versions"
|
||||
selected_versions={@selected_versions}
|
||||
/>
|
||||
<button
|
||||
id="search-button"
|
||||
class="hidden"
|
||||
phx-click={AshHqWeb.AppViewLive.toggle_search()}
|
||||
/>
|
||||
<button id="search-button" class="hidden" phx-click={AshHqWeb.AppViewLive.toggle_search()} />
|
||||
<div
|
||||
id="main-container"
|
||||
class="h-full bg-white dark:bg-primary-black dark:text-silver-phoenix overflow-x-hidden"
|
||||
|
@ -43,12 +39,19 @@ defmodule AshHqWeb.AppViewLive do
|
|||
</a>
|
||||
</div>
|
||||
<div class="flex flex-row align-middle items-center space-x-2">
|
||||
<a href="/docs/guides/ash/main/Getting-Started" class="dark:text-gray-400 dark:hover:text-gray-200 hover:text-gray-600">Get Started</a>
|
||||
<a
|
||||
href="/docs/guides/ash/main/Getting-Started"
|
||||
class="dark:text-gray-400 dark:hover:text-gray-200 hover:text-gray-600"
|
||||
>Get Started</a>
|
||||
<div>|</div>
|
||||
<a href="/docs" class="dark:text-gray-400 dark:hover:text-gray-200 hover:text-gray-600">Docs</a>
|
||||
<div>|</div>
|
||||
<a href="https://github.com/ash-project">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6 dark:fill-gray-400 dark:hover:fill-gray-200 hover:fill-gray-600" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="w-6 h-6 dark:fill-gray-400 dark:hover:fill-gray-200 hover:fill-gray-600"
|
||||
viewBox="0 0 24 24"
|
||||
><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" /></svg>
|
||||
</a>
|
||||
<button phx-click="toggle_theme">
|
||||
{#case @configured_theme}
|
||||
|
@ -64,7 +67,13 @@ defmodule AshHqWeb.AppViewLive do
|
|||
{#match :home}
|
||||
<Home id="home" />
|
||||
{#match :docs_dsl}
|
||||
<Docs id="docs" params={@params} change_versions="change-versions" selected_versions={@selected_versions} libraries={@libraries} />
|
||||
<Docs
|
||||
id="docs"
|
||||
params={@params}
|
||||
change_versions="change-versions"
|
||||
selected_versions={@selected_versions}
|
||||
libraries={@libraries}
|
||||
/>
|
||||
{/case}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -189,10 +198,9 @@ defmodule AshHqWeb.AppViewLive do
|
|||
js
|
||||
|> JS.dispatch("js:noscroll-main", to: "#search-box")
|
||||
|> JS.toggle(
|
||||
in: "fade-in duration-100",
|
||||
out: "fade-out duration-100",
|
||||
to: "#search-box",
|
||||
time: 100
|
||||
in: "fade-in transition",
|
||||
out: "fade-out transition",
|
||||
to: "#search-box"
|
||||
)
|
||||
|> JS.dispatch("js:focus", to: "#search-input")
|
||||
end
|
||||
|
@ -201,9 +209,8 @@ defmodule AshHqWeb.AppViewLive do
|
|||
js
|
||||
|> JS.dispatch("js:noscroll-main", to: "#search-box")
|
||||
|> JS.hide(
|
||||
transition: "fade-out duration-100",
|
||||
to: "#search-box",
|
||||
time: 100
|
||||
transition: "fade-out",
|
||||
to: "#search-box"
|
||||
)
|
||||
|> JS.dispatch("js:focus", to: "#search-input")
|
||||
end
|
||||
|
|
7
mix.exs
7
mix.exs
|
@ -42,8 +42,15 @@ defmodule AshHq.MixProject do
|
|||
{:ecto, git: "https://github.com/elixir-ecto/ecto.git", override: true},
|
||||
{:surface, "~> 0.7.3"},
|
||||
{:surface_heroicons, "~> 0.6.0"},
|
||||
# Syntax Highlighting
|
||||
{:makeup, "~> 1.1"},
|
||||
{:makeup_elixir, "~> 0.16.0"},
|
||||
{:makeup_graphql, "~> 0.1.2"},
|
||||
{:makeup_erlang, "~> 0.1.1"},
|
||||
{:makeup_eex, "~> 0.1.1"},
|
||||
{:makeup_js, "~> 0.1.0"},
|
||||
{:makeup_sql, "~> 0.1.0"},
|
||||
# Phoenix/Core dependencies
|
||||
{:phoenix, "~> 1.6.6"},
|
||||
{:phoenix_ecto, "~> 4.4"},
|
||||
{:ecto_sql, "~> 3.6"},
|
||||
|
|
6
mix.lock
6
mix.lock
|
@ -30,7 +30,13 @@
|
|||
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
|
||||
"jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"},
|
||||
"makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
|
||||
"makeup_eex": {:hex, :makeup_eex, "0.1.1", "89352d5da318d97ae27bbcc87201f274504d2b71ede58ca366af6a5fbed9508d", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.16", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_html, "~> 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "d111a0994eaaab09ef1a4b3b313ef806513bb4652152c26c0d7ca2be8402a964"},
|
||||
"makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"},
|
||||
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
|
||||
"makeup_graphql": {:hex, :makeup_graphql, "0.1.2", "81e2939aab6d2b81d39ee5d9e13fae02599e9ca6e1152e0eeed737a98a5f96aa", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "3390ab04ba388d52a94bbe64ef62aa4d7923ceaffac43ec948f58f631440e8fb"},
|
||||
"makeup_html": {:hex, :makeup_html, "0.1.0", "b0228fda985e311d8f0d25bed58f8280826633a38d7448cabdd723e116165bcf", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "0ca44e7dcb8d933e010740324470dd8ec947243b51304bd34b8165ef3281edc2"},
|
||||
"makeup_js": {:hex, :makeup_js, "0.1.0", "ffa8ce9db95d14dcd09045334539d5992d540d63598c592d4805b7674bdd6675", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "3f0c1a5eb52c9737b1679c926574e83bb260ccdedf08b58ee96cca7c685dea75"},
|
||||
"makeup_sql": {:hex, :makeup_sql, "0.1.0", "197a8a0a38e83885f73767530739bb8f990aecf7fd1597d3141608c14f5f233e", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "556e23ff88ad2fb8c44e393467cfba0c4f980cbe90316deaf48a1362f58cd118"},
|
||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||
"mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
|
||||
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
|
||||
|
|
|
@ -5,7 +5,8 @@ defmodule AshHq.Repo.Migrations.AddTsvectorIndices do
|
|||
guides: {:name, :text},
|
||||
library_versions: {:version, :doc},
|
||||
options: {:name, :doc},
|
||||
dsls: {:name, :doc}
|
||||
dsls: {:name, :doc},
|
||||
extensions: {:name, :doc}
|
||||
}
|
||||
|
||||
def change do
|
||||
|
|
23
priv/repo/migrations/20220328204638_migrate_resources9.exs
Normal file
23
priv/repo/migrations/20220328204638_migrate_resources9.exs
Normal file
|
@ -0,0 +1,23 @@
|
|||
defmodule AshHq.Repo.Migrations.MigrateResources9 do
|
||||
@moduledoc """
|
||||
Updates resources based on their most recent snapshots.
|
||||
|
||||
This file was autogenerated with `mix ash_postgres.generate_migrations`
|
||||
"""
|
||||
|
||||
use Ecto.Migration
|
||||
|
||||
def up do
|
||||
alter table(:extensions) do
|
||||
modify :doc, :text, default: ""
|
||||
add :doc_html, :text
|
||||
end
|
||||
end
|
||||
|
||||
def down do
|
||||
alter table(:extensions) do
|
||||
remove :doc_html
|
||||
modify :doc, :text, default: nil
|
||||
end
|
||||
end
|
||||
end
|
130
priv/resource_snapshots/repo/extensions/20220328204638.json
Normal file
130
priv/resource_snapshots/repo/extensions/20220328204638.json
Normal file
|
@ -0,0 +1,130 @@
|
|||
{
|
||||
"attributes": [
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "fragment(\"uuid_generate_v4()\")",
|
||||
"generated?": false,
|
||||
"primary_key?": true,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "id",
|
||||
"type": "uuid"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "name",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "target",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "false",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "default_for_target",
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "\"\"",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "doc",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": true,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "doc_html",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "type",
|
||||
"type": "text"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": null,
|
||||
"size": null,
|
||||
"source": "order",
|
||||
"type": "bigint"
|
||||
},
|
||||
{
|
||||
"allow_nil?": false,
|
||||
"default": "nil",
|
||||
"generated?": false,
|
||||
"primary_key?": false,
|
||||
"references": {
|
||||
"destination_field": "id",
|
||||
"destination_field_default": null,
|
||||
"destination_field_generated": null,
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"name": "extensions_library_version_id_fkey",
|
||||
"on_delete": null,
|
||||
"on_update": null,
|
||||
"table": "library_versions"
|
||||
},
|
||||
"size": null,
|
||||
"source": "library_version_id",
|
||||
"type": "uuid"
|
||||
}
|
||||
],
|
||||
"base_filter": null,
|
||||
"check_constraints": [],
|
||||
"custom_indexes": [],
|
||||
"has_create_action": true,
|
||||
"hash": "322D1B960153C08465157BE952943969D68A7D05D823B1CA076473CC2FF47772",
|
||||
"identities": [
|
||||
{
|
||||
"base_filter": null,
|
||||
"index_name": "extensions_unique_name_by_library_version_index",
|
||||
"keys": [
|
||||
"library_version_id",
|
||||
"name"
|
||||
],
|
||||
"name": "unique_name_by_library_version"
|
||||
}
|
||||
],
|
||||
"multitenancy": {
|
||||
"attribute": null,
|
||||
"global": null,
|
||||
"strategy": null
|
||||
},
|
||||
"repo": "Elixir.AshHq.Repo",
|
||||
"table": "extensions"
|
||||
}
|
Loading…
Reference in a new issue