mirror of
https://github.com/ash-project/ash_hq.git
synced 2024-09-19 21:03:30 +12:00
improvement: don't load data, don't check library versions
This commit is contained in:
parent
3bf97311a5
commit
20f1e277da
13 changed files with 79 additions and 975 deletions
|
@ -270,16 +270,6 @@ window.addEventListener("phx:js:scroll-to", (e) => {
|
|||
});
|
||||
});
|
||||
|
||||
window.addEventListener("phx:selected-versions", (e) => {
|
||||
if (cookiesAreAllowed()) {
|
||||
const cookie = Object.keys(e.detail)
|
||||
.map((key) => `${key}:${e.detail[key]}`)
|
||||
.join(",");
|
||||
|
||||
setCookie("selected_versions", cookie)
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("phx:selected-types", (e) => {
|
||||
if (cookiesAreAllowed()) {
|
||||
const cookie = e.detail.types.join(",");
|
||||
|
@ -305,12 +295,6 @@ window.addEventListener("keydown", (event) => {
|
|||
}
|
||||
});
|
||||
|
||||
window.addEventListener("phx:catalogue-call-to-action-dismissed", (event) => {
|
||||
if (cookiesAreAllowed()) {
|
||||
setCookie("catalogue_call_to_action_dismissed", "true")
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("phx:click-on-item", (event) => {
|
||||
document.getElementById(event.detail.id).click();
|
||||
document.getElementById("close-search").click();
|
||||
|
|
|
@ -328,24 +328,7 @@ defmodule AshHq.Docs.Extensions.Search.Transformers.AddSearchStructure do
|
|||
)
|
||||
|
||||
{arguments, filter} =
|
||||
if Ash.Resource.Info.attribute(dsl_state, :library_version_id) do
|
||||
{[
|
||||
Transformer.build_entity!(
|
||||
Ash.Resource.Dsl,
|
||||
[:actions, :read],
|
||||
:argument,
|
||||
type: {:array, :uuid},
|
||||
name: :library_versions
|
||||
),
|
||||
query_argument
|
||||
],
|
||||
Ash.Query.expr(
|
||||
matches(query: arg(:query)) and
|
||||
^ref(config.library_version_attribute) in ^arg(:library_versions)
|
||||
)}
|
||||
else
|
||||
{[query_argument], Ash.Query.expr(matches(query: arg(:query)))}
|
||||
end
|
||||
|
||||
Transformer.add_entity(
|
||||
dsl_state,
|
||||
|
@ -365,7 +348,7 @@ defmodule AshHq.Docs.Extensions.Search.Transformers.AddSearchStructure do
|
|||
[:code_interface],
|
||||
Transformer.build_entity!(Ash.Resource.Dsl, [:code_interface], :define,
|
||||
name: :search,
|
||||
args: [:query, :library_versions]
|
||||
args: [:query]
|
||||
)
|
||||
)
|
||||
end
|
||||
|
|
|
@ -26,10 +26,6 @@ defmodule AshHq.Docs.Search do
|
|||
constraints trim?: false, allow_empty?: true
|
||||
end
|
||||
|
||||
argument :library_versions, {:array, :uuid} do
|
||||
allow_nil? false
|
||||
end
|
||||
|
||||
argument :types, {:array, :string}
|
||||
|
||||
returns :build_results
|
||||
|
@ -49,7 +45,6 @@ defmodule AshHq.Docs.Search do
|
|||
|
||||
read :search, element(:search_results), :search do
|
||||
input %{
|
||||
library_versions: arg(:library_versions),
|
||||
query: arg(:query)
|
||||
}
|
||||
end
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
defmodule AshHqWeb.Components.Catalogue do
|
||||
@moduledoc "Renders the catalogue of available packages"
|
||||
use Surface.Component
|
||||
|
||||
alias Surface.Components.Form
|
||||
alias Surface.Components.Form.Select
|
||||
|
||||
prop(id, :string, required: true)
|
||||
prop(libraries, :list, required: true)
|
||||
prop(selected_versions, :map, required: true)
|
||||
prop(change_versions, :event, required: true)
|
||||
prop(toggle, :any)
|
||||
prop(show_catalogue_call_to_action, :boolean, default: false)
|
||||
|
||||
def render(assigns) do
|
||||
~F"""
|
||||
<div id={@id} class="w-full h-full overflow-y-auto p-6">
|
||||
<div class="w-full flex justify-between">
|
||||
<p class="text-xl font-bold">Select Ash libraries</p>
|
||||
{#if @toggle}
|
||||
<button id="close-search-versions" phx-click={@toggle} class="">
|
||||
<Heroicons.Solid.XIcon class="h-6 w-6" />
|
||||
</button>
|
||||
{/if}
|
||||
</div>
|
||||
<div
|
||||
:if={@show_catalogue_call_to_action}
|
||||
class="text-sm my-2 text-base-light-700 dark:text-base-dark-50"
|
||||
>
|
||||
<Heroicons.Outline.ExclamationCircleIcon class="h-4 w-4 inline-block mb-0.5" />
|
||||
You can see this screen at any time by pressing <Heroicons.Solid.PlusIcon class="h-4 w-4 inline-block mb-0.5" /> next to the list of included packages in the sidebar
|
||||
</div>
|
||||
<Form for={:selected_versions} change={@change_versions} class="lg:grid lg:grid-cols-2">
|
||||
{#for library <- Enum.sort_by(@libraries, & &1.order)}
|
||||
<div class="py-6 lg:p-6 lg:even:pl-0 lg:odd:pr-0 flex-grow border-b border-base-light-300 dark:border-base-dark-600">
|
||||
<div class="flex justify-between items-center mb-1">
|
||||
<div class={[
|
||||
"font-bold text-lg",
|
||||
"text-primary-light-600 dark:text-primary-dark-400": value(@selected_versions, library.id),
|
||||
"text-base-light-500 dark:text-base-dark-300": !value(@selected_versions, library.id)
|
||||
]}>{library.display_name}</div>
|
||||
<Select
|
||||
class="rounded-lg text-black dark:bg-base-dark-700 dark:text-white dark:border-0"
|
||||
name={"versions[#{library.id}]"}
|
||||
id={"#{@id}-selected_versions-#{library.id}"}
|
||||
selected={value(@selected_versions, library.id)}
|
||||
options={[{"hidden", nil}] ++ formatted_versions(library.versions)}
|
||||
/>
|
||||
</div>
|
||||
{library.description}
|
||||
</div>
|
||||
{/for}
|
||||
</Form>
|
||||
|
||||
<p class="mt-6">... and more coming soon! <img class="h-6 w-6 inline-block" src="/images/ash-logo.png"></p>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
defp formatted_versions(versions) do
|
||||
versions
|
||||
|> Enum.sort(&(Version.compare(&1.version, &2.version) != :lt))
|
||||
|> Enum.map(fn version ->
|
||||
{version.version, version.id}
|
||||
end)
|
||||
|> case do
|
||||
[{latest, _} | rest] ->
|
||||
[{"#{latest} (latest)", "latest"} | rest]
|
||||
|
||||
other ->
|
||||
other
|
||||
end
|
||||
end
|
||||
|
||||
defp value(selected_versions, library_id) do
|
||||
case selected_versions[library_id] do
|
||||
nil -> nil
|
||||
"" -> nil
|
||||
value -> value
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,35 +0,0 @@
|
|||
defmodule AshHqWeb.Components.CatalogueModal do
|
||||
@moduledoc "The library catalogue modal"
|
||||
use Surface.Component
|
||||
|
||||
alias AshHqWeb.Components.Catalogue
|
||||
|
||||
prop(id, :string, required: true)
|
||||
prop(libraries, :list, required: true)
|
||||
prop(selected_versions, :map, required: true)
|
||||
prop(change_versions, :event, required: true)
|
||||
prop(show_catalogue_call_to_action, :boolean)
|
||||
|
||||
def render(assigns) do
|
||||
~F"""
|
||||
<div
|
||||
id={@id}
|
||||
style="display: none;"
|
||||
class="fixed flex justify-center align-middle w-screen h-full backdrop-blur-sm bg-white bg-opacity-10 z-50"
|
||||
>
|
||||
<div
|
||||
:on-click-away={AshHqWeb.AppViewLive.toggle_catalogue()}
|
||||
class="dark:text-white absolute rounded-xl left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2 w-3/4 max-w-[1200px] h-3/4 bg-white dark:bg-base-dark-850 border-2 dark:border-base-dark-900"
|
||||
>
|
||||
<Catalogue
|
||||
id={"#{@id}-contents"}
|
||||
libraries={@libraries}
|
||||
selected_versions={@selected_versions}
|
||||
change_versions={@change_versions}
|
||||
show_catalogue_call_to_action={@show_catalogue_call_to_action}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
end
|
|
@ -10,7 +10,6 @@ defmodule AshHqWeb.Components.DocSidebar do
|
|||
|
||||
prop libraries, :any
|
||||
prop remove_version, :any
|
||||
prop selected_versions, :any
|
||||
prop class, :any
|
||||
prop sidebar_data, :any, default: []
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ defmodule AshHqWeb.Components.Docs.Functions do
|
|||
prop(library, :any, required: true)
|
||||
prop(library_version, :any, required: true)
|
||||
prop(libraries, :list, required: true)
|
||||
prop(selected_versions, :map, required: true)
|
||||
|
||||
def render(assigns) do
|
||||
~F"""
|
||||
|
|
|
@ -4,7 +4,7 @@ defmodule AshHqWeb.Components.Search do
|
|||
|
||||
require Ash.Query
|
||||
|
||||
alias AshHqWeb.Components.{Catalogue, Icon}
|
||||
alias AshHqWeb.Components.Icon
|
||||
alias AshHqWeb.DocRoutes
|
||||
alias Phoenix.LiveView.JS
|
||||
alias Surface.Components.{Form, LivePatch}
|
||||
|
@ -12,7 +12,6 @@ defmodule AshHqWeb.Components.Search do
|
|||
|
||||
prop(close, :event, required: true)
|
||||
prop(libraries, :list, required: true)
|
||||
prop(selected_versions, :map, required: true)
|
||||
prop(selected_types, :list, required: true)
|
||||
prop(change_types, :event, required: true)
|
||||
prop(change_versions, :event, required: true)
|
||||
|
@ -37,15 +36,6 @@ defmodule AshHqWeb.Components.Search do
|
|||
:on-window-keydown="select-previous"
|
||||
phx-key="ArrowUp"
|
||||
>
|
||||
<div class="h-full w-full" id="search-versions" style="display: none;">
|
||||
<Catalogue
|
||||
id="search-versions-contents"
|
||||
toggle={toggle_libraries()}
|
||||
libraries={@libraries}
|
||||
selected_versions={@selected_versions}
|
||||
change_versions={@change_versions}
|
||||
/>
|
||||
</div>
|
||||
<div id="search-body" class="h-full" :on-window-keydown="select-next" phx-key="ArrowDown">
|
||||
<div class="p-6 h-full grid gap-6 grid-rows-[max-content_auto_max-content]">
|
||||
<button
|
||||
|
@ -109,7 +99,7 @@ defmodule AshHqWeb.Components.Search do
|
|||
{#if item.__struct__ != AshHq.Docs.Guide}
|
||||
<a
|
||||
class="block w-full text-left border-base-light-300 dark:border-base-dark-600"
|
||||
href={DocRoutes.doc_link(item, @selected_versions)}
|
||||
href={DocRoutes.doc_link(item)}
|
||||
id={"result-#{item.id}"}
|
||||
phx-click={@close}
|
||||
>
|
||||
|
@ -145,7 +135,7 @@ defmodule AshHqWeb.Components.Search do
|
|||
{#if item.__struct__ == AshHq.Docs.Guide}
|
||||
<LivePatch
|
||||
class="block w-full text-left border-base-light-300 dark:border-base-dark-600"
|
||||
to={DocRoutes.doc_link(item, @selected_versions)}
|
||||
to={DocRoutes.doc_link(item)}
|
||||
opts={id: "result-#{item.id}", "phx-click": @close}
|
||||
>
|
||||
<div class={
|
||||
|
@ -287,34 +277,12 @@ defmodule AshHqWeb.Components.Search do
|
|||
end
|
||||
|
||||
defp search(socket) do
|
||||
if socket.assigns[:search] in [nil, ""] || socket.assigns[:selected_versions] in [nil, %{}] ||
|
||||
socket.assigns[:selected_types] == [] do
|
||||
assign(socket, results: %{}, item_list: [])
|
||||
if socket.assigns.search in [nil, ""] do
|
||||
socket
|
||||
else
|
||||
versions =
|
||||
Enum.map(socket.assigns.selected_versions, fn
|
||||
{library_id, "latest"} ->
|
||||
Enum.find_value(socket.assigns.libraries, fn library ->
|
||||
if library.id == library_id do
|
||||
case AshHqWeb.Helpers.latest_version(library) do
|
||||
nil ->
|
||||
nil
|
||||
|
||||
version ->
|
||||
version.id
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
{_, version_id} ->
|
||||
version_id
|
||||
end)
|
||||
|> Enum.reject(&(&1 == "" || is_nil(&1)))
|
||||
|
||||
%{result: item_list} =
|
||||
AshHq.Docs.Search.run!(
|
||||
socket.assigns.search,
|
||||
versions,
|
||||
%{types: socket.assigns[:selected_types]}
|
||||
)
|
||||
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
defmodule AshHqWeb.Components.VersionPills do
|
||||
@moduledoc "Renders pills for selected versions"
|
||||
use Surface.LiveComponent
|
||||
|
||||
prop selected_versions, :map, default: %{}
|
||||
prop libraries, :list, default: []
|
||||
prop add_version, :event
|
||||
prop remove_version, :event
|
||||
prop change_version, :event
|
||||
prop editable, :boolean, default: true
|
||||
prop toggle, :event
|
||||
|
||||
data adding_version, :boolean, default: false
|
||||
|
||||
def render(assigns) do
|
||||
~F"""
|
||||
<div class="flex flex-row flex-wrap align-center items-center ml-2 justify-start gap-2 flex-grow">
|
||||
{#for library <- @libraries}
|
||||
{#if @selected_versions[library.id] not in [nil, ""]}
|
||||
<div class="flex flex-row flex-wrap contents-center items-center ml-1 px-2 py-1 bg-primary-light-500 dark:bg-primary-dark-300 hover:bg-primary-light-600 hover:dark:bg-primary-dark-400 text-black text-xs font-medium rounded-full">
|
||||
{library.name}{#if selected_version(library, @selected_versions[library.id]) != "latest"}
|
||||
| {selected_version(library, @selected_versions[library.id])}
|
||||
{/if}
|
||||
{#if @editable}
|
||||
<button
|
||||
:on-click={@remove_version}
|
||||
phx-value-library={library.id}
|
||||
class="flex items-center w-6 h-6"
|
||||
><Heroicons.Outline.XIcon class="h-4 w-4 ml-1" /></button>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
{/for}
|
||||
{#if @editable}
|
||||
{#if @toggle}
|
||||
<button :on-click={@toggle}>
|
||||
<Heroicons.Solid.PlusIcon class="h-4 w-4" />
|
||||
</button>
|
||||
{#else}
|
||||
<button phx-click={AshHqWeb.AppViewLive.toggle_catalogue()}>
|
||||
<Heroicons.Solid.PlusIcon class="h-4 w-4" />
|
||||
</button>
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def update(assigns, socket) do
|
||||
case assigns[:action] do
|
||||
:close_add_version ->
|
||||
{:ok, assign(socket, :adding_version, false)}
|
||||
|
||||
_ ->
|
||||
{:ok, assign(socket, assigns)}
|
||||
end
|
||||
end
|
||||
|
||||
defp selected_version(library, selected_version) do
|
||||
if selected_version == "latest" do
|
||||
"latest"
|
||||
else
|
||||
Enum.find(library.versions, &(&1.id == selected_version)).version
|
||||
end
|
||||
end
|
||||
|
||||
def handle_event("add-version", _, socket) do
|
||||
{:noreply, assign(socket, :adding_version, true)}
|
||||
end
|
||||
end
|
|
@ -1,86 +1,61 @@
|
|||
defmodule AshHqWeb.DocRoutes do
|
||||
@moduledoc "Helpers for routing to results of searches"
|
||||
|
||||
def doc_link(entity, selected_versions \\ %{})
|
||||
|
||||
def doc_link(%AshHq.Docs.Library{name: name}, _selected_version) do
|
||||
def doc_link(%AshHq.Docs.Library{name: name}) do
|
||||
"https://hexdocs.pm/#{name}"
|
||||
end
|
||||
|
||||
def doc_link(
|
||||
%AshHq.Docs.MixTask{
|
||||
def doc_link(%AshHq.Docs.MixTask{
|
||||
library_name: library_name,
|
||||
module_name: module_name
|
||||
},
|
||||
_selected_versions
|
||||
) do
|
||||
}) do
|
||||
"https://hexdocs.pm/#{library_name}/#{module_name}.html"
|
||||
end
|
||||
|
||||
def doc_link(
|
||||
%AshHq.Docs.Module{
|
||||
def doc_link(%AshHq.Docs.Module{
|
||||
library_name: library_name,
|
||||
name: name
|
||||
},
|
||||
_selected_versions
|
||||
) do
|
||||
}) do
|
||||
"https://hexdocs.pm/#{library_name}/#{name}.html"
|
||||
end
|
||||
|
||||
def doc_link(
|
||||
%AshHq.Docs.Function{
|
||||
def doc_link(%AshHq.Docs.Function{
|
||||
name: name,
|
||||
arity: arity,
|
||||
module_name: module_name,
|
||||
library_name: library_name
|
||||
},
|
||||
_selected_versions
|
||||
) do
|
||||
}) do
|
||||
"https://hexdocs.pm/#{library_name}/#{module_name}.html##{name}/#{arity}"
|
||||
end
|
||||
|
||||
def doc_link(
|
||||
%AshHq.Docs.Guide{
|
||||
def doc_link(%AshHq.Docs.Guide{
|
||||
route: route,
|
||||
library_version: %{
|
||||
library_name: library_name,
|
||||
version: version,
|
||||
library_id: library_id
|
||||
}
|
||||
},
|
||||
selected_versions
|
||||
) do
|
||||
"/docs/guides/#{library_name}/#{version(version, library_id, selected_versions)}/#{route}"
|
||||
}) do
|
||||
"/docs/guides/#{library_name}/latest/#{route}"
|
||||
end
|
||||
|
||||
def doc_link(%AshHq.Docs.LibraryVersion{}, _selected_versions) do
|
||||
def doc_link(%AshHq.Docs.LibraryVersion{}) do
|
||||
raise "Shouldn't be called anymore"
|
||||
end
|
||||
|
||||
def doc_link(
|
||||
%AshHq.Docs.Extension{
|
||||
def doc_link(%AshHq.Docs.Extension{
|
||||
library_version: %{
|
||||
library_name: library_name
|
||||
},
|
||||
module: module
|
||||
},
|
||||
_selected_versions
|
||||
) do
|
||||
}) do
|
||||
"https://hexdocs.pm/#{library_name}/#{module}.html"
|
||||
end
|
||||
|
||||
def doc_link(item, _selected_versions) do
|
||||
def doc_link(item) do
|
||||
"https://hexdocs.pm/#{item.library_name}/dsl-#{sanitize_name(String.trim_trailing(item.extension_module, ".Dsl"))}.html##{String.replace(item.sanitized_path, "/", "-")}"
|
||||
end
|
||||
|
||||
defp version(version_name, library_id, selected_versions) do
|
||||
if selected_versions[library_id] == "latest" do
|
||||
"latest"
|
||||
else
|
||||
version_name
|
||||
end
|
||||
end
|
||||
|
||||
def sanitize_name(name, allow_forward_slash? \\ false) do
|
||||
if allow_forward_slash? do
|
||||
String.downcase(String.replace(to_string(name), ~r/[^A-Za-z0-9\/_]/, "-"))
|
||||
|
|
|
@ -14,14 +14,12 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
require Ash.Query
|
||||
|
||||
prop(change_versions, :event, required: true)
|
||||
prop(selected_versions, :map, required: true)
|
||||
prop(libraries, :list, default: [])
|
||||
prop(uri, :string)
|
||||
prop(remove_version, :event)
|
||||
prop(add_version, :event)
|
||||
prop(change_version, :event)
|
||||
prop(params, :map, required: true)
|
||||
prop(show_catalogue_call_to_action, :boolean)
|
||||
|
||||
data(library, :any)
|
||||
data(docs, :any)
|
||||
|
@ -37,8 +35,6 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
data(title, :string)
|
||||
data(sidebar_data, :any)
|
||||
data(not_found, :boolean, default: false)
|
||||
data(dsl_target_extensions, :list)
|
||||
data(dsl_target, :string)
|
||||
|
||||
@spec render(any) :: Phoenix.LiveView.Rendered.t()
|
||||
def render(assigns) do
|
||||
|
@ -68,7 +64,6 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
class="max-w-sm p-2 pr-4"
|
||||
libraries={@libraries}
|
||||
remove_version={@remove_version}
|
||||
selected_versions={@selected_versions}
|
||||
sidebar_data={@sidebar_data}
|
||||
/>
|
||||
</div>
|
||||
|
@ -80,7 +75,6 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
class="hidden xl:block w-80"
|
||||
libraries={@libraries}
|
||||
remove_version={@remove_version}
|
||||
selected_versions={@selected_versions}
|
||||
sidebar_data={@sidebar_data}
|
||||
/>
|
||||
</div>
|
||||
|
@ -96,26 +90,12 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
<div
|
||||
id="docs-window"
|
||||
:if={!@not_found}
|
||||
class={classes([
|
||||
"w-full shrink max-w-6xl bg-white dark:bg-base-dark-850 md:pr-8 md:mt-4 px-4 md:px-auto mx-auto overflow-x-auto overflow-y-hidden",
|
||||
"prose prose-td:pl-0 dark:prose-invert": !@dsl_target
|
||||
])}
|
||||
class={classes([ "w-full shrink max-w-6xl bg-white dark:bg-base-dark-850 md:pr-8 md:mt-4 px-4 md:px-auto mx-auto overflow-x-auto overflow-y-hidden prose prose-td:pl-0 dark:prose-invert" ])}
|
||||
>
|
||||
<div
|
||||
id="module-docs"
|
||||
class="w-full nav-anchor text-black dark:text-white relative py-4 md:py-auto"
|
||||
>
|
||||
<.catalogue_call_to_action :if={@show_catalogue_call_to_action} />
|
||||
{#if @module}
|
||||
<h1>{@module.name} <SourceLink module_or_function={@module} library={@library} library_version={@library_version} /></h1>
|
||||
{/if}
|
||||
{#if @mix_task}
|
||||
<h1>{@mix_task.name} <SourceLink
|
||||
module_or_function={@mix_task}
|
||||
library={@library}
|
||||
library_version={@library_version}
|
||||
/></h1>
|
||||
{/if}
|
||||
<div class="flex flex-col float-right">
|
||||
<.github_guide_link
|
||||
:if={@guide}
|
||||
|
@ -133,62 +113,7 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
{#if @docs}
|
||||
<.docs doc_path={@doc_path} docs={@docs} />
|
||||
{/if}
|
||||
{#if @dsl_target_extensions}
|
||||
{#for extension <- @dsl_target_extensions}
|
||||
<div class="prose dark:prose-invert mb-8">
|
||||
<h1>
|
||||
{#if extension.default_for_target}
|
||||
{extension.target}
|
||||
{#else}
|
||||
{extension.module}
|
||||
{/if}
|
||||
</h1>
|
||||
{raw(extension.doc_html)}
|
||||
</div>
|
||||
{#for dsl <- extension.dsls |> Enum.filter(&(&1.path == []))}
|
||||
{render_dsl(assigns, extension, dsl)}
|
||||
{/for}
|
||||
{/for}
|
||||
{/if}
|
||||
</div>
|
||||
{#if @module}
|
||||
<Functions
|
||||
header="Types"
|
||||
type={:type}
|
||||
functions={@module.functions}
|
||||
library={@library}
|
||||
library_version={@library_version}
|
||||
libraries={@libraries}
|
||||
selected_versions={@selected_versions}
|
||||
/>
|
||||
<Functions
|
||||
header="Callbacks"
|
||||
type={:callback}
|
||||
functions={@module.functions}
|
||||
library={@library}
|
||||
library_version={@library_version}
|
||||
libraries={@libraries}
|
||||
selected_versions={@selected_versions}
|
||||
/>
|
||||
<Functions
|
||||
header="Functions"
|
||||
type={:function}
|
||||
functions={@module.functions}
|
||||
library={@library}
|
||||
library_version={@library_version}
|
||||
libraries={@libraries}
|
||||
selected_versions={@selected_versions}
|
||||
/>
|
||||
<Functions
|
||||
header="Macros"
|
||||
type={:macro}
|
||||
functions={@module.functions}
|
||||
library={@library}
|
||||
library_version={@library_version}
|
||||
libraries={@libraries}
|
||||
selected_versions={@selected_versions}
|
||||
/>
|
||||
{/if}
|
||||
|
||||
<footer class="p-2 sm:justify-center">
|
||||
<div class="md:flex md:justify-around items-center">
|
||||
|
@ -201,138 +126,13 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
{#if @module}
|
||||
<div class="sidebar-container hidden lg:block lg:w-72 sticky top-36 xl:top-20 shrink-0 overflow-y-auto overflow-x-hidden dark:bg-base-dark-850 bg-opacity-70 mt-4">
|
||||
<ModuleRightNav functions={@module.functions} module={@module.name} />
|
||||
</div>
|
||||
{#else}
|
||||
{#if @dsl_target}
|
||||
<div class="sidebar-container hidden lg:block lg:w-72 sticky top-36 xl:top-20 shrink-0 overflow-y-auto overflow-x-hidden dark:bg-base-dark-850 bg-opacity-70 mt-4">
|
||||
<DslRightNav dsls={Enum.flat_map(@dsl_target_extensions, & &1.dsls)} dsl_target={@dsl_target} />
|
||||
</div>
|
||||
{#else}
|
||||
<!-- empty div to preserve flex row spacing -->
|
||||
<div />
|
||||
{/if}
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def render_dsl(assigns, extension, dsl) do
|
||||
options =
|
||||
Enum.filter(
|
||||
extension.options,
|
||||
&(&1.path == dsl.path ++ [dsl.name])
|
||||
)
|
||||
|> Enum.split_with(& &1.argument_index)
|
||||
|> then(fn {args, not_args} ->
|
||||
Enum.sort_by(args, & &1.argument_index) ++ not_args
|
||||
end)
|
||||
|
||||
arguments =
|
||||
options
|
||||
|> Enum.filter(& &1.argument_index)
|
||||
|> Enum.sort_by(& &1.argument_index)
|
||||
|
||||
arg_count = Enum.count(arguments)
|
||||
|
||||
~F"""
|
||||
<div class={classes(["mb-12 mt-4"])}>
|
||||
<div class="flex flex-col">
|
||||
<div class="w-full">
|
||||
<div class="text-2xl font-bold nav-anchor" id={String.replace(dsl.sanitized_path, "/", "-")}>
|
||||
<div class="flex flex-row items-center bg-opacity-50 py-1 bg-base-light-200 dark:bg-base-dark-750 w-full border-l-2 border-primary-light-400 dark:border-primary-dark-400 pl-2">
|
||||
<div class="flex flex-row items-center justify-between w-full pr-2">
|
||||
<div class="text-lg w-full font-semibold">
|
||||
{dsl.name}
|
||||
{#for {arg, i} <- Enum.with_index(arguments)}
|
||||
<LivePatch
|
||||
class={"after:content-[',']": i != arg_count - 1}
|
||||
to={"##{String.replace(arg.sanitized_path, "/", "-")}-#{DocRoutes.sanitize_name(arg.name)}"}
|
||||
>
|
||||
<span class="italic text-primary-light-600 dark:text-primary-dark-400 hover:dark:text-primary-dark-500 hover:text-primary-light-700">
|
||||
{arg.name}</span>{#if arg.name in dsl.optional_args}
|
||||
\\ {Map.get(dsl.arg_defaults, arg.name, "nil")}
|
||||
{/if}</LivePatch>
|
||||
{/for}
|
||||
</div>
|
||||
<a href={"##{String.replace(dsl.sanitized_path, "/", "-")}"}>
|
||||
<Heroicons.Outline.LinkIcon class="h-3 w-3 mr-2" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{#if dsl.requires_extension}
|
||||
<div class="w-full pt-4">
|
||||
Requires Extension: <span class="text-primary-light-600">{dsl.requires_extension}</span>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="prose dark:prose-invert my-4">
|
||||
{raw(dsl.doc_html)}
|
||||
</div>
|
||||
</div>
|
||||
{#if !Enum.empty?(options)}
|
||||
{#case modules_in_scope(dsl, extension, @libraries, @selected_versions)}
|
||||
{#match []}
|
||||
{#match imports}
|
||||
<div class="mt-2 mb-6">
|
||||
<div>Imported Modules:</div>
|
||||
<ul>
|
||||
{#for mod <- imports}
|
||||
<li class="list-disc">
|
||||
<LivePatch to={DocRoutes.doc_link(mod, @selected_versions)}>
|
||||
<span class="text-primary-light-600 dark:text-primary-dark-400 hover:dark:text-primary-dark-500 hover:text-primary-light-700">
|
||||
{mod.name}
|
||||
</span>
|
||||
</LivePatch>
|
||||
</li>
|
||||
{/for}
|
||||
</ul>
|
||||
</div>
|
||||
{/case}
|
||||
{/if}
|
||||
</div>
|
||||
<div
|
||||
:if={!Enum.empty?(options)}
|
||||
class="grid grid-cols-[min-content_auto] w-full border-b border-gray-300 dark:border-gray-600 pb-2 mb-12"
|
||||
>
|
||||
{#for option <- options}
|
||||
<div
|
||||
class="flex flex-col border-t border-gray-300 dark:border-gray-600 py-3 nav-anchor pr-4"
|
||||
id={"#{String.replace(option.sanitized_path, "/", "-")}-#{DocRoutes.sanitize_name(option.name)}"}
|
||||
>
|
||||
<div class="flex flex-row align-middle leading-7">
|
||||
<LivePatch
|
||||
to={"##{String.replace(option.sanitized_path, "/", "-")}-#{DocRoutes.sanitize_name(option.name)}"}
|
||||
class="text-primary-light-600 dark:text-primary-dark-400 hover:dark:text-primary-dark-500 hover:text-primary-light-700 pr-2"
|
||||
>
|
||||
{option.name}
|
||||
</LivePatch>
|
||||
{render_tags(assigns, dsl, option)}
|
||||
</div>
|
||||
<span class="break-keep text-sm">
|
||||
{option.type}
|
||||
</span>
|
||||
</div>
|
||||
<div class="prose dark:prose-invert border-t border-gray-300 dark:border-gray-600 py-3">
|
||||
{raw(option.doc_html)}
|
||||
</div>
|
||||
{/for}
|
||||
</div>
|
||||
{#case child_dsls(extension, dsl)}
|
||||
{#match []}
|
||||
{#match children}
|
||||
{#for child <- children}
|
||||
{render_dsl(assigns, extension, child)}
|
||||
{/for}
|
||||
{/case}
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def github_guide_link(assigns) do
|
||||
~F"""
|
||||
<a
|
||||
|
@ -388,28 +188,8 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
"""
|
||||
end
|
||||
|
||||
def catalogue_call_to_action(assigns) do
|
||||
~F"""
|
||||
<div
|
||||
class="bg-blue-500 text-white px-4 py-2 mb-8 cursor-pointer flex justify-between items-center"
|
||||
id="catalogue-call-to-action"
|
||||
:on-click={AshHqWeb.AppViewLive.toggle_catalogue()}
|
||||
>
|
||||
<span>View the full range of Ash libraries for authentication, soft deletion, GraphQL and more</span>
|
||||
<button
|
||||
id="dismiss-catalogue"
|
||||
class="h-6 w-6 cursor-pointer"
|
||||
:on-click="dismiss_catalogue_call_to_action"
|
||||
>
|
||||
<Heroicons.Outline.XIcon class="h-6 w-6" />
|
||||
</button>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
def update(assigns, socket) do
|
||||
if socket.assigns[:loaded_once?] &&
|
||||
assigns[:selected_versions] == socket.assigns[:selected_versions] do
|
||||
if socket.assigns[:loaded_once?] do
|
||||
{:ok, socket |> assign(Map.delete(assigns, :libraries)) |> load_docs()}
|
||||
else
|
||||
{:ok,
|
||||
|
@ -422,49 +202,6 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
end
|
||||
end
|
||||
|
||||
defp modules_in_scope(nil, _, _, _), do: []
|
||||
defp modules_in_scope(_, nil, _, _), do: []
|
||||
|
||||
defp modules_in_scope(dsl, %{dsls: dsls}, libraries, selected_versions) do
|
||||
dsl_path = dsl.path ++ [dsl.name]
|
||||
|
||||
dsls
|
||||
|> Enum.filter(fn potential_parent ->
|
||||
List.starts_with?(dsl_path, potential_parent.path ++ [potential_parent.name])
|
||||
end)
|
||||
|> Enum.flat_map(fn dsl ->
|
||||
dsl.imports || []
|
||||
end)
|
||||
|> Enum.flat_map(fn mod_name ->
|
||||
case find_module(libraries, selected_versions, mod_name) do
|
||||
nil ->
|
||||
Logger.warning("No such module found called #{inspect(mod_name)}")
|
||||
[]
|
||||
|
||||
module ->
|
||||
[module]
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp find_module(libraries, selected_versions, mod_name) do
|
||||
Enum.find_value(libraries, fn library ->
|
||||
version = selected_version(library, selected_versions[library.id])
|
||||
|
||||
if version do
|
||||
Enum.find(version.modules, &(&1.name == mod_name))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp selected_version(library, selected_version) do
|
||||
if selected_version == "latest" do
|
||||
latest_version(library)
|
||||
else
|
||||
Enum.find(library.versions, &(&1.id == selected_version))
|
||||
end
|
||||
end
|
||||
|
||||
defp child_dsls(_, nil), do: []
|
||||
defp child_dsls(nil, _), do: []
|
||||
|
||||
|
@ -534,62 +271,8 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
|> Ash.Query.new()
|
||||
|> load_for_search()
|
||||
|
||||
modules_query =
|
||||
AshHq.Docs.Module
|
||||
|> Ash.Query.sort(order: :asc)
|
||||
|> load_for_search()
|
||||
|
||||
mix_tasks_query =
|
||||
AshHq.Docs.MixTask
|
||||
|> Ash.Query.sort(order: :asc)
|
||||
|> load_for_search()
|
||||
|
||||
extensions_query =
|
||||
AshHq.Docs.Extension
|
||||
|> Ash.Query.sort(order: :asc)
|
||||
|> load_for_search()
|
||||
|
||||
new_libraries =
|
||||
socket.assigns.libraries
|
||||
|> Enum.flat_map(fn library ->
|
||||
latest_version = AshHqWeb.Helpers.latest_version(library)
|
||||
|
||||
Enum.filter(library.versions, fn version ->
|
||||
(latest_version && version.id == latest_version.id) ||
|
||||
version.id == socket.assigns[:selected_versions][library.id] ||
|
||||
(socket.assigns[:library_version] &&
|
||||
socket.assigns[:library_version].id == version.id) ||
|
||||
(socket.assigns.params["version"] &&
|
||||
socket.assigns.params["version"] ==
|
||||
version.version)
|
||||
end)
|
||||
end)
|
||||
|> AshHq.Docs.load!(
|
||||
[
|
||||
extensions: extensions_query,
|
||||
guides: guides_query,
|
||||
modules: modules_query,
|
||||
mix_tasks: mix_tasks_query
|
||||
],
|
||||
lazy?: true
|
||||
)
|
||||
|> Enum.reduce(socket.assigns.libraries, fn library_version, libraries ->
|
||||
Enum.map(libraries, fn library ->
|
||||
if library.id == library_version.library_id do
|
||||
Map.update!(library, :versions, fn versions ->
|
||||
Enum.map(versions, fn current_version ->
|
||||
if current_version.id == library_version.id do
|
||||
library_version
|
||||
else
|
||||
current_version
|
||||
end
|
||||
end)
|
||||
end)
|
||||
else
|
||||
library
|
||||
end
|
||||
end)
|
||||
end)
|
||||
AshHq.Docs.load!(socket.assigns.libraries, versions: [guides: guides_query])
|
||||
|
||||
assign(socket, :libraries, new_libraries)
|
||||
end
|
||||
|
@ -597,64 +280,16 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
def load_docs(socket) do
|
||||
socket
|
||||
|> assign_library()
|
||||
|> assign_dsl_target()
|
||||
|> assign_guide()
|
||||
|> assign_module()
|
||||
|> assign_mix_task()
|
||||
|> assign_fallback_guide()
|
||||
|> assign_docs()
|
||||
end
|
||||
|
||||
defp assign_dsl_target(socket) do
|
||||
if socket.assigns[:params]["dsl_target"] do
|
||||
extensions =
|
||||
socket.assigns.libraries
|
||||
|> Enum.map(fn library ->
|
||||
selected_version(library, socket.assigns.selected_versions[library.id])
|
||||
end)
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|> Enum.flat_map(& &1.extensions)
|
||||
|> Enum.filter(fn extension ->
|
||||
AshHqWeb.DocRoutes.sanitize_name(extension.target) ==
|
||||
socket.assigns[:params]["dsl_target"]
|
||||
end)
|
||||
|
||||
dsls_query =
|
||||
AshHq.Docs.Dsl
|
||||
|> Ash.Query.sort(order: :asc)
|
||||
|> load_for_search()
|
||||
|> Ash.Query.load([:doc_html, :path])
|
||||
|
||||
options_query =
|
||||
AshHq.Docs.Option
|
||||
|> Ash.Query.sort(order: :asc)
|
||||
|> load_for_search()
|
||||
|> Ash.Query.load([:doc_html, :path])
|
||||
|
||||
extensions = AshHq.Docs.load!(extensions, dsls: dsls_query, options: options_query)
|
||||
|
||||
target_name =
|
||||
case Enum.at(extensions, 0) do
|
||||
%{target: target} -> target
|
||||
_ -> nil
|
||||
end
|
||||
|
||||
assign(socket,
|
||||
dsl_target_extensions: extensions,
|
||||
dsl_target: target_name,
|
||||
not_found: Enum.empty?(extensions)
|
||||
)
|
||||
else
|
||||
assign(socket, dsl_target_extensions: nil, dsl_target: nil)
|
||||
end
|
||||
end
|
||||
|
||||
defp assign_sidebar_content(socket) do
|
||||
sidebar_data =
|
||||
guides_by_category_and_library(
|
||||
socket.assigns[:libraries],
|
||||
socket.assigns[:library_version],
|
||||
socket.assigns[:selected_versions],
|
||||
socket.assigns[:guide]
|
||||
)
|
||||
|
||||
|
@ -663,9 +298,11 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
|
||||
@start_guides ["Tutorials", "Topics", "How To", "Misc"]
|
||||
|
||||
defp guides_by_category_and_library(libraries, library_version, selected_versions, active_guide) do
|
||||
defp guides_by_category_and_library(libraries, library_version, active_guide) do
|
||||
libraries
|
||||
|> Enum.map(&{&1, selected_version(&1, library_version, selected_versions)})
|
||||
|> Enum.map(fn library ->
|
||||
{library, Enum.at(library.versions, 0)}
|
||||
end)
|
||||
|> Enum.filter(fn {_library, version} -> version != nil end)
|
||||
|> Enum.sort_by(fn {library, _version} -> library.order end)
|
||||
|> Enum.flat_map(fn {library, %{guides: guides}} ->
|
||||
|
@ -675,7 +312,7 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
%{
|
||||
id: guide.id,
|
||||
name: guide.name,
|
||||
to: DocRoutes.doc_link(guide, selected_versions),
|
||||
to: DocRoutes.doc_link(guide),
|
||||
active?: active_guide && active_guide.id == guide.id
|
||||
}
|
||||
end)
|
||||
|
@ -685,22 +322,6 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
|> partially_alphabetically_sort(@start_guides, [])
|
||||
end
|
||||
|
||||
defp selected_version(library, library_version, selected_versions) do
|
||||
selected_version = selected_versions[library.id]
|
||||
|
||||
if library_version && library_version.library_id == library.id do
|
||||
library_version
|
||||
else
|
||||
if selected_version == "latest" do
|
||||
AshHqWeb.Helpers.latest_version(library)
|
||||
else
|
||||
if selected_version not in [nil, ""] do
|
||||
Enum.find(library.versions, &(&1.id == selected_version))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
defp partially_alphabetically_sort(keyed_list, first, last) do
|
||||
{first_items, rest} =
|
||||
Enum.split_with(keyed_list, fn {key, _} ->
|
||||
|
@ -806,51 +427,10 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
)
|
||||
|
||||
library ->
|
||||
socket =
|
||||
if socket.assigns[:params]["version"] do
|
||||
library_version =
|
||||
case socket.assigns[:params]["version"] do
|
||||
"latest" ->
|
||||
AshHqWeb.Helpers.latest_version(library)
|
||||
|
||||
version ->
|
||||
Enum.find(
|
||||
library.versions,
|
||||
&(&1.version == version)
|
||||
)
|
||||
end
|
||||
|
||||
if is_nil(library_version) do
|
||||
assign(socket,
|
||||
not_found: true,
|
||||
library_version: AshHqWeb.Helpers.latest_version(library)
|
||||
)
|
||||
else
|
||||
socket =
|
||||
assign(
|
||||
socket,
|
||||
library_version: library_version
|
||||
)
|
||||
|
||||
if socket.assigns.params["version"] != "latest" &&
|
||||
(!socket.assigns[:library] ||
|
||||
socket.assigns.params["library"] !=
|
||||
socket.assigns.library.name) do
|
||||
new_selected_versions =
|
||||
Map.put(socket.assigns.selected_versions, library.id, library_version.id)
|
||||
|
||||
socket
|
||||
|> assign(selected_versions: new_selected_versions)
|
||||
|> push_event("selected-versions", new_selected_versions)
|
||||
else
|
||||
socket
|
||||
end
|
||||
end
|
||||
else
|
||||
assign(socket, :library_version, nil)
|
||||
end
|
||||
|> assign(:library, library)
|
||||
|> assign(:library_version, AshHqWeb.Helpers.latest_version(library))
|
||||
|
||||
assign(socket, :library, library)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -878,95 +458,8 @@ defmodule AshHqWeb.Pages.Docs do
|
|||
DocRoutes.sanitize_name(guide.name) == DocRoutes.sanitize_name(guide_name)
|
||||
end
|
||||
|
||||
defp assign_module(socket) do
|
||||
if socket.assigns.library && socket.assigns.library_version &&
|
||||
socket.assigns[:params]["module"] do
|
||||
module =
|
||||
Enum.find(
|
||||
socket.assigns.library_version.modules,
|
||||
&(&1.sanitized_name == socket.assigns[:params]["module"])
|
||||
)
|
||||
|
||||
if is_nil(module) do
|
||||
assign(socket, module: nil, not_found: true)
|
||||
else
|
||||
functions_query =
|
||||
AshHq.Docs.Function
|
||||
|> Ash.Query.sort(name: :asc, arity: :asc)
|
||||
|> load_for_search()
|
||||
|> Ash.Query.load(:doc_html)
|
||||
|
||||
assign(socket,
|
||||
module: AshHq.Docs.load!(module, [functions: functions_query], lazy?: true)
|
||||
)
|
||||
end
|
||||
else
|
||||
assign(socket, :module, nil)
|
||||
end
|
||||
end
|
||||
|
||||
defp assign_mix_task(socket) do
|
||||
if socket.assigns.library && socket.assigns.library_version &&
|
||||
socket.assigns[:params]["mix_task"] do
|
||||
mix_task =
|
||||
Enum.find(
|
||||
socket.assigns.library_version.mix_tasks,
|
||||
&(&1.sanitized_name == socket.assigns[:params]["mix_task"])
|
||||
)
|
||||
|
||||
if mix_task do
|
||||
assign(socket,
|
||||
mix_task: mix_task
|
||||
)
|
||||
else
|
||||
assign(socket, mix_task: nil, not_found: true)
|
||||
end
|
||||
else
|
||||
assign(socket, :mix_task, nil)
|
||||
end
|
||||
end
|
||||
|
||||
defp assign_docs(socket) do
|
||||
cond do
|
||||
socket.assigns.dsl_target_extensions ->
|
||||
target_name = socket.assigns.dsl_target
|
||||
|
||||
title =
|
||||
if target_name do
|
||||
"DSL Docs"
|
||||
else
|
||||
target_name
|
||||
end
|
||||
|
||||
send(self(), {:page_title, title})
|
||||
|
||||
assign(socket,
|
||||
docs: nil,
|
||||
title: target_name,
|
||||
description: "View the documentation for #{target_name} on Ash HQ.",
|
||||
doc_path: [target_name]
|
||||
)
|
||||
|
||||
socket.assigns.module ->
|
||||
send(self(), {:page_title, socket.assigns.module.name})
|
||||
|
||||
assign(socket,
|
||||
docs: socket.assigns.module |> reselect_and_get!(:doc_html),
|
||||
title: "Module: #{socket.assigns.module.name}",
|
||||
description: "View the documentation for #{socket.assigns.module.name} on Ash HQ.",
|
||||
doc_path: [socket.assigns.library.name, socket.assigns.module.name]
|
||||
)
|
||||
|
||||
socket.assigns.mix_task ->
|
||||
send(self(), {:page_title, socket.assigns.mix_task.name})
|
||||
|
||||
assign(socket,
|
||||
docs: socket.assigns.mix_task |> reselect_and_get!(:doc_html),
|
||||
title: "Mix Task: #{socket.assigns.mix_task.name}",
|
||||
description: "View the documentation for #{socket.assigns.mix_task.name} on Ash HQ.",
|
||||
doc_path: [socket.assigns.library.name, socket.assigns.mix_task.name]
|
||||
)
|
||||
|
||||
socket.assigns.guide ->
|
||||
send(self(), {:page_title, socket.assigns.guide.name})
|
||||
|
||||
|
|
|
@ -4,9 +4,7 @@ defmodule AshHqWeb.SessionPlug do
|
|||
|
||||
@cookies_to_replicate [
|
||||
"theme",
|
||||
"selected_versions",
|
||||
"selected_types",
|
||||
"catalogue_call_to_action_dismissed"
|
||||
"selected_types"
|
||||
]
|
||||
|
||||
def init(_), do: []
|
||||
|
|
|
@ -13,7 +13,6 @@ defmodule AshHqWeb.AppViewLive do
|
|||
import AshHqWeb.Tails
|
||||
|
||||
data(configured_theme, :string, default: :system)
|
||||
data(selected_versions, :map, default: %{})
|
||||
data(libraries, :list, default: [])
|
||||
data(selected_types, :map, default: %{})
|
||||
data(current_user, :map)
|
||||
|
@ -71,17 +70,9 @@ defmodule AshHqWeb.AppViewLive do
|
|||
libraries={@libraries}
|
||||
selected_types={@selected_types}
|
||||
change_types="change-types"
|
||||
selected_versions={@selected_versions}
|
||||
change_versions="change-versions"
|
||||
remove_version="remove_version"
|
||||
/>
|
||||
<CatalogueModal
|
||||
id="catalogue-box"
|
||||
libraries={@libraries}
|
||||
selected_versions={@selected_versions}
|
||||
change_versions="change-versions"
|
||||
show_catalogue_call_to_action={@show_catalogue_call_to_action}
|
||||
/>
|
||||
<button id="search-button" class="hidden" phx-click={AshHqWeb.AppViewLive.toggle_search()} />
|
||||
<div
|
||||
id="main-container"
|
||||
|
@ -114,9 +105,7 @@ defmodule AshHqWeb.AppViewLive do
|
|||
params={@params}
|
||||
remove_version="remove_version"
|
||||
change_versions="change-versions"
|
||||
selected_versions={@selected_versions}
|
||||
libraries={@libraries}
|
||||
show_catalogue_call_to_action={@show_catalogue_call_to_action}
|
||||
/>
|
||||
{#match :user_settings}
|
||||
<UserSettings id="user_settings" current_user={@current_user} />
|
||||
|
@ -197,34 +186,6 @@ defmodule AshHqWeb.AppViewLive do
|
|||
{:noreply, assign(socket, :page_title, "Ash Framework - #{title}")}
|
||||
end
|
||||
|
||||
def handle_event("dismiss_catalogue_call_to_action", _, socket) do
|
||||
{:noreply,
|
||||
socket
|
||||
|> assign(:show_catalogue_call_to_action, false)
|
||||
|> push_event("catalogue-call-to-action-dismissed", %{})}
|
||||
end
|
||||
|
||||
def handle_event("remove_version", %{"library" => library}, socket) do
|
||||
new_selected_versions = Map.put(socket.assigns.selected_versions, library, "")
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> set_selected_library_versions(new_selected_versions)}
|
||||
end
|
||||
|
||||
def handle_event("add_version", %{"library" => library}, socket) do
|
||||
new_selected_versions = Map.put(socket.assigns.selected_versions, library, "latest")
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> set_selected_library_versions(new_selected_versions)}
|
||||
end
|
||||
|
||||
def handle_event("change-versions", %{"versions" => versions}, socket) do
|
||||
{:noreply,
|
||||
socket
|
||||
|> set_selected_library_versions(versions)}
|
||||
end
|
||||
|
||||
def handle_event("change-types", %{"types" => types}, socket) do
|
||||
types =
|
||||
|
@ -275,24 +236,6 @@ defmodule AshHqWeb.AppViewLive do
|
|||
socket = Context.put(socket, platform: socket.assigns.platform)
|
||||
configured_theme = session["theme"] || "system"
|
||||
|
||||
configured_library_versions =
|
||||
case session["selected_versions"] do
|
||||
nil ->
|
||||
%{}
|
||||
|
||||
"" ->
|
||||
%{}
|
||||
|
||||
value ->
|
||||
value
|
||||
|> String.split(",")
|
||||
|> Map.new(fn str ->
|
||||
str
|
||||
|> String.split(":")
|
||||
|> List.to_tuple()
|
||||
end)
|
||||
end
|
||||
|
||||
all_types = AshHq.Docs.Extensions.Search.Types.types()
|
||||
|
||||
selected_types =
|
||||
|
@ -312,37 +255,17 @@ defmodule AshHqWeb.AppViewLive do
|
|||
|
||||
libraries = AshHq.Docs.Library.read!(load: [versions: versions_query])
|
||||
|
||||
selected_versions =
|
||||
Enum.reduce(libraries, configured_library_versions, fn library, acc ->
|
||||
Map.put_new(acc, library.id, "latest")
|
||||
end)
|
||||
|
||||
{:ok,
|
||||
socket
|
||||
|> assign(
|
||||
:show_catalogue_call_to_action,
|
||||
session["catalogue_call_to_action_dismissed"] != "true"
|
||||
)
|
||||
|> assign(:libraries, libraries)
|
||||
|> assign(
|
||||
:selected_versions,
|
||||
selected_versions
|
||||
)
|
||||
|> assign(
|
||||
:selected_types,
|
||||
selected_types
|
||||
)
|
||||
|> assign(configured_theme: configured_theme)
|
||||
|> set_selected_library_versions(selected_versions)
|
||||
|> push_event("selected_types", %{types: selected_types})}
|
||||
end
|
||||
|
||||
defp set_selected_library_versions(socket, library_versions) do
|
||||
socket
|
||||
|> assign(:selected_versions, library_versions)
|
||||
|> push_event("selected-versions", library_versions)
|
||||
end
|
||||
|
||||
def toggle_search(js \\ %JS{}) do
|
||||
js
|
||||
|> JS.toggle(
|
||||
|
@ -361,24 +284,6 @@ defmodule AshHqWeb.AppViewLive do
|
|||
|> JS.dispatch("js:focus", to: "#search-input")
|
||||
end
|
||||
|
||||
def toggle_catalogue(js \\ %JS{}) do
|
||||
js
|
||||
|> JS.toggle(
|
||||
to: "#catalogue-box",
|
||||
in: {
|
||||
"transition ease-in duration-100",
|
||||
"opacity-0",
|
||||
"opacity-100"
|
||||
},
|
||||
out: {
|
||||
"transition ease-out duration-75",
|
||||
"opacity-100",
|
||||
"opacity-0"
|
||||
}
|
||||
)
|
||||
|> JS.dispatch("phx:js:scroll-to", detail: %{id: "catalogue-box"})
|
||||
end
|
||||
|
||||
def close_search(js \\ %JS{}) do
|
||||
js
|
||||
|> JS.hide(
|
||||
|
@ -388,12 +293,4 @@ defmodule AshHqWeb.AppViewLive do
|
|||
|> JS.hide(transition: "fade-out", to: "#search-versions")
|
||||
|> JS.show(transition: "fade-in", to: "#search-body")
|
||||
end
|
||||
|
||||
def close_catalogue(js \\ %JS{}) do
|
||||
js
|
||||
|> JS.hide(
|
||||
transition: "fade-out",
|
||||
to: "#catalogue-box"
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue