2022-03-26 10:17:01 +13:00
|
|
|
defmodule AshHqWeb.AppViewLive do
|
2022-09-09 16:31:50 +12:00
|
|
|
# credo:disable-for-this-file Credo.Check.Readability.MaxLineLength
|
2022-03-26 10:17:01 +13:00
|
|
|
use Surface.LiveView,
|
|
|
|
container: {:div, class: "h-full"}
|
|
|
|
|
2022-09-28 16:18:05 +13:00
|
|
|
alias AshHqWeb.Components.{CatalogueModal, Search}
|
2022-09-13 08:47:14 +12:00
|
|
|
alias AshHqWeb.Components.AppView.TopBar
|
2022-08-16 13:23:59 +12:00
|
|
|
alias AshHqWeb.Pages.{Docs, Home, LogIn, Register, ResetPassword, UserSettings}
|
2022-03-26 10:17:01 +13:00
|
|
|
alias Phoenix.LiveView.JS
|
2022-09-09 16:31:50 +12:00
|
|
|
alias Surface.Components.Context
|
2022-03-28 10:26:35 +13:00
|
|
|
require Ash.Query
|
2022-03-26 10:17:01 +13:00
|
|
|
|
2022-09-09 16:31:50 +12:00
|
|
|
data configured_theme, :string, default: :system
|
|
|
|
data searching, :boolean, default: false
|
|
|
|
data selected_versions, :map, default: %{}
|
|
|
|
data libraries, :list, default: []
|
|
|
|
data selected_types, :map, default: %{}
|
|
|
|
data current_user, :map
|
|
|
|
|
|
|
|
data library, :any, default: nil
|
|
|
|
data extension, :any, default: nil
|
|
|
|
data docs, :any, default: nil
|
|
|
|
data library_version, :any, default: nil
|
|
|
|
data guide, :any, default: nil
|
|
|
|
data doc_path, :list, default: []
|
|
|
|
data dsls, :list, default: []
|
|
|
|
data dsl, :any, default: nil
|
|
|
|
data options, :list, default: []
|
|
|
|
data module, :any, default: nil
|
|
|
|
|
|
|
|
def render(%{platform: :ios} = assigns) do
|
|
|
|
~F"""
|
|
|
|
{#case @live_action}
|
|
|
|
{#match :home}
|
|
|
|
<Home id="home" />
|
|
|
|
{/case}
|
|
|
|
"""
|
|
|
|
end
|
2022-03-26 10:17:01 +13:00
|
|
|
|
|
|
|
def render(assigns) do
|
|
|
|
~F"""
|
|
|
|
<div
|
|
|
|
id="app"
|
|
|
|
class={"h-full font-sans": true, "#{@configured_theme}": true}
|
|
|
|
phx-hook="ColorTheme"
|
|
|
|
>
|
2022-07-15 07:09:04 +12:00
|
|
|
<Search
|
|
|
|
id="search-box"
|
|
|
|
close={close_search()}
|
|
|
|
libraries={@libraries}
|
|
|
|
selected_types={@selected_types}
|
|
|
|
change_types="change-types"
|
2022-09-28 16:18:05 +13:00
|
|
|
selected_versions={@selected_versions}
|
2022-07-15 07:09:04 +12:00
|
|
|
change_versions="change-versions"
|
2022-09-28 16:18:05 +13:00
|
|
|
remove_version="remove_version"
|
|
|
|
/>
|
|
|
|
<CatalogueModal
|
|
|
|
id="catalogue-box"
|
|
|
|
close={close_catalogue()}
|
|
|
|
libraries={@libraries}
|
2022-07-15 07:09:04 +12:00
|
|
|
selected_versions={@selected_versions}
|
2022-09-28 16:18:05 +13:00
|
|
|
change_versions="change-versions"
|
2022-07-15 07:09:04 +12:00
|
|
|
/>
|
2022-03-29 11:05:19 +13:00
|
|
|
<button id="search-button" class="hidden" phx-click={AshHqWeb.AppViewLive.toggle_search()} />
|
2022-03-28 10:26:35 +13:00
|
|
|
<div
|
|
|
|
id="main-container"
|
2022-04-02 08:11:17 +13:00
|
|
|
class={
|
2022-09-13 05:44:52 +12:00
|
|
|
"h-screen w-screen bg-white dark:bg-base-dark-900 dark:text-white flex flex-col items-stretch",
|
2022-07-28 08:00:02 +12:00
|
|
|
"overflow-y-auto overflow-x-hidden": @live_action == :home,
|
2022-04-02 08:11:17 +13:00
|
|
|
"overflow-hidden": @live_action == :docs_dsl
|
|
|
|
}
|
2022-03-28 10:26:35 +13:00
|
|
|
>
|
2022-09-13 12:35:59 +12:00
|
|
|
<TopBar
|
|
|
|
live_action={@live_action}
|
|
|
|
toggle_theme="toggle_theme"
|
|
|
|
configured_theme={@configured_theme}
|
|
|
|
/>
|
2022-08-16 13:23:59 +12:00
|
|
|
{#for flash <- List.wrap(live_flash(@flash, :error))}
|
|
|
|
<p class="alert alert-warning" role="alert">{flash}</p>
|
|
|
|
{/for}
|
|
|
|
{#for flash <- List.wrap(live_flash(@flash, :info))}
|
|
|
|
<p class="alert alert-info max-h-min" role="alert">{flash}</p>
|
|
|
|
{/for}
|
2022-09-13 12:35:59 +12:00
|
|
|
{#case @live_action}
|
|
|
|
{#match :home}
|
|
|
|
<Home id="home" />
|
|
|
|
{#match :docs_dsl}
|
|
|
|
<Docs
|
|
|
|
id="docs"
|
|
|
|
uri={@uri}
|
|
|
|
params={@params}
|
|
|
|
remove_version="remove_version"
|
|
|
|
change_versions="change-versions"
|
|
|
|
selected_versions={@selected_versions}
|
|
|
|
libraries={@libraries}
|
|
|
|
/>
|
|
|
|
{#match :user_settings}
|
|
|
|
<UserSettings id="user_settings" current_user={@current_user} />
|
|
|
|
{#match :log_in}
|
|
|
|
<LogIn id="log_in" />
|
|
|
|
{#match :register}
|
|
|
|
<Register id="register" />
|
|
|
|
{#match :reset_password}
|
|
|
|
<ResetPassword id="reset_password" params={@params} />
|
|
|
|
{/case}
|
2022-03-26 10:17:01 +13:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
"""
|
|
|
|
end
|
|
|
|
|
2022-08-31 17:39:22 +12:00
|
|
|
# defp toggle_account_dropdown(js \\ %JS{}) do
|
|
|
|
# js
|
|
|
|
# |> JS.toggle(
|
|
|
|
# to: "#account-dropdown",
|
|
|
|
# in: {
|
|
|
|
# "transition ease-out duration-100",
|
|
|
|
# "opacity-0 scale-95",
|
|
|
|
# "opacity-100 scale-100"
|
|
|
|
# },
|
|
|
|
# out: {
|
|
|
|
# "transition ease-in duration-75",
|
|
|
|
# "opacity-100 scale-100",
|
|
|
|
# "opacity-0 scale-05"
|
|
|
|
# }
|
|
|
|
# )
|
|
|
|
# end
|
2022-08-07 11:22:58 +12:00
|
|
|
|
2022-08-23 15:02:53 +12:00
|
|
|
# {#if @current_user}
|
|
|
|
# <div class="relative inline-block text-left">
|
|
|
|
# <div>
|
|
|
|
# <button
|
|
|
|
# phx-click={toggle_account_dropdown()}
|
|
|
|
# type="button"
|
2022-09-08 15:51:47 +12:00
|
|
|
# class="inline-flex items-center justify-center w-full rounded-md shadow-sm font-medium dark:text-base-dark-400 dark:hover:text-base-dark-200 hover:text-base-dark-600"
|
2022-08-23 15:02:53 +12:00
|
|
|
# id="menu-button"
|
|
|
|
# aria-expanded="true"
|
|
|
|
# aria-haspopup="true"
|
|
|
|
# >
|
|
|
|
# Account
|
|
|
|
# <Heroicons.Solid.ChevronDownIcon class="-mr-1 ml-2 h-5 w-5" />
|
|
|
|
# </button>
|
|
|
|
# </div>
|
|
|
|
|
|
|
|
# <div
|
|
|
|
# id="account-dropdown"
|
|
|
|
# style="display: none;"
|
2022-09-08 15:51:47 +12:00
|
|
|
# class="origin-top-right absolute right-0 mt-2 w-56 rounded-md shadow-lg bg-white dark:text-white dark:bg-base-dark-900 ring-1 ring-black ring-opacity-5 divide-y divide-base-light-100 focus:outline-none"
|
2022-08-23 15:02:53 +12:00
|
|
|
# role="menu"
|
|
|
|
# aria-orientation="vertical"
|
|
|
|
# aria-labelledby="menu-button"
|
|
|
|
# tabindex="-1"
|
|
|
|
# phx-click-away={toggle_account_dropdown()}
|
|
|
|
# >
|
|
|
|
# <div class="py-1" role="none">
|
2022-09-08 15:51:47 +12:00
|
|
|
# <!-- Active: "bg-base-light-100 text-base-light-900", Not Active: "text-base-light-700" -->
|
2022-08-23 15:02:53 +12:00
|
|
|
# <LiveRedirect
|
|
|
|
# to={Routes.app_view_path(AshHqWeb.Endpoint, :user_settings)}
|
|
|
|
# class="dark:text-white group flex items-center px-4 py-2 text-sm"
|
|
|
|
# >
|
2022-09-08 15:51:47 +12:00
|
|
|
# <Heroicons.Solid.PencilAltIcon class="mr-3 h-5 w-5 text-base-light-400 group-hover:text-base-light-500" />
|
2022-08-23 15:02:53 +12:00
|
|
|
# Settings
|
|
|
|
# </LiveRedirect>
|
|
|
|
# </div>
|
|
|
|
# <div class="py-1" role="none">
|
|
|
|
# <Link
|
|
|
|
# label="logout"
|
|
|
|
# to={Routes.user_session_path(AshHqWeb.Endpoint, :delete)}
|
|
|
|
# class="dark:text-white group flex items-center px-4 py-2 text-sm"
|
|
|
|
# method={:delete}
|
|
|
|
# id="logout-link"
|
|
|
|
# >
|
2022-09-08 15:51:47 +12:00
|
|
|
# <Heroicons.Outline.LogoutIcon class="mr-3 h-5 w-5 text-base-light-400 group-hover:text-base-light-500" />
|
2022-08-23 15:02:53 +12:00
|
|
|
# Logout
|
|
|
|
# </Link>
|
|
|
|
# </div>
|
|
|
|
# </div>
|
|
|
|
# </div>
|
|
|
|
# {#else}
|
|
|
|
# <LiveRedirect to={Routes.app_view_path(AshHqWeb.Endpoint, :log_in)}>
|
|
|
|
# Sign In
|
|
|
|
# </LiveRedirect>
|
|
|
|
# {/if}
|
|
|
|
|
2022-03-28 10:26:35 +13:00
|
|
|
def handle_params(params, uri, socket) do
|
2022-08-04 01:53:59 +12:00
|
|
|
{:noreply,
|
|
|
|
socket
|
2022-09-13 08:47:14 +12:00
|
|
|
|> assign(params: params, uri: uri)}
|
2022-03-26 10:17:01 +13:00
|
|
|
end
|
|
|
|
|
2022-08-31 20:11:15 +12:00
|
|
|
def handle_event("remove_version", %{"library" => library}, socket) do
|
|
|
|
new_selected_versions = Map.put(socket.assigns.selected_versions, library, "")
|
|
|
|
|
|
|
|
{:noreply,
|
|
|
|
socket
|
|
|
|
|> assign(:selected_versions, new_selected_versions)
|
2022-09-13 08:47:14 +12:00
|
|
|
|> push_event("selected-versions", new_selected_versions)}
|
2022-08-31 20:11:15 +12:00
|
|
|
end
|
|
|
|
|
|
|
|
def handle_event("add_version", %{"library" => library}, socket) do
|
|
|
|
new_selected_versions = Map.put(socket.assigns.selected_versions, library, "latest")
|
|
|
|
|
|
|
|
send_update(AshHqWeb.Components.VersionPills,
|
|
|
|
id: "mobile-sidebar-version-pills",
|
|
|
|
action: :close_add_version
|
|
|
|
)
|
|
|
|
|
|
|
|
send_update(AshHqWeb.Components.VersionPills,
|
|
|
|
id: "sidebar-version-pills",
|
|
|
|
action: :close_add_version
|
|
|
|
)
|
|
|
|
|
|
|
|
{:noreply,
|
|
|
|
socket
|
|
|
|
|> assign(:selected_versions, new_selected_versions)
|
2022-09-13 08:47:14 +12:00
|
|
|
|> push_event("selected-versions", new_selected_versions)}
|
2022-08-31 20:11:15 +12:00
|
|
|
end
|
|
|
|
|
2022-03-28 10:26:35 +13:00
|
|
|
def handle_event("change-versions", %{"versions" => versions}, socket) do
|
|
|
|
{:noreply,
|
|
|
|
socket
|
|
|
|
|> assign(:selected_versions, versions)
|
|
|
|
|> push_event("selected-versions", versions)}
|
2022-03-26 10:17:01 +13:00
|
|
|
end
|
|
|
|
|
2022-03-30 17:40:17 +13:00
|
|
|
def handle_event("change-types", %{"types" => types}, socket) do
|
|
|
|
types =
|
|
|
|
types
|
|
|
|
|> Enum.filter(fn {_, value} ->
|
|
|
|
value == "true"
|
|
|
|
end)
|
|
|
|
|> Enum.map(&elem(&1, 0))
|
|
|
|
|
|
|
|
{:noreply,
|
|
|
|
socket
|
|
|
|
|> assign(
|
|
|
|
:selected_types,
|
|
|
|
types
|
|
|
|
)
|
|
|
|
|> push_event("selected-types", %{types: types})}
|
|
|
|
end
|
|
|
|
|
2022-03-26 10:17:01 +13:00
|
|
|
def handle_event("toggle_theme", _, socket) do
|
|
|
|
theme =
|
|
|
|
case socket.assigns.configured_theme do
|
|
|
|
"light" ->
|
|
|
|
"dark"
|
|
|
|
|
|
|
|
"dark" ->
|
2022-04-02 11:49:26 +13:00
|
|
|
"system"
|
|
|
|
|
|
|
|
"system" ->
|
2022-03-26 10:17:01 +13:00
|
|
|
"light"
|
|
|
|
end
|
|
|
|
|
|
|
|
{:noreply,
|
|
|
|
socket
|
|
|
|
|> assign(:configured_theme, theme)
|
|
|
|
|> push_event("set_theme", %{theme: theme})}
|
|
|
|
end
|
|
|
|
|
2022-03-28 10:26:35 +13:00
|
|
|
def mount(_params, session, socket) do
|
2022-09-09 16:31:50 +12:00
|
|
|
socket = Context.put(socket, platform: socket.assigns.platform)
|
2022-04-02 11:49:26 +13:00
|
|
|
configured_theme = session["theme"] || "system"
|
2022-03-26 10:17:01 +13:00
|
|
|
|
2022-03-28 10:26:35 +13:00
|
|
|
configured_library_versions =
|
|
|
|
case session["selected_versions"] do
|
|
|
|
nil ->
|
|
|
|
%{}
|
|
|
|
|
|
|
|
"" ->
|
|
|
|
%{}
|
|
|
|
|
|
|
|
value ->
|
|
|
|
value
|
|
|
|
|> String.split(",")
|
|
|
|
|> Map.new(fn str ->
|
|
|
|
str
|
|
|
|
|> String.split(":")
|
|
|
|
|> List.to_tuple()
|
|
|
|
end)
|
2022-03-26 10:17:01 +13:00
|
|
|
end
|
|
|
|
|
2022-03-30 17:40:17 +13:00
|
|
|
all_types = AshHq.Docs.Extensions.Search.Types.types()
|
|
|
|
|
|
|
|
selected_types =
|
|
|
|
case session["selected_types"] do
|
|
|
|
nil ->
|
|
|
|
AshHq.Docs.Extensions.Search.Types.types()
|
|
|
|
|
|
|
|
types ->
|
|
|
|
types
|
|
|
|
|> String.split(",")
|
|
|
|
|> Enum.filter(&(&1 in all_types))
|
|
|
|
end
|
|
|
|
|
2022-06-05 08:58:50 +12:00
|
|
|
versions_query =
|
|
|
|
AshHq.Docs.LibraryVersion
|
|
|
|
|> Ash.Query.sort(version: :desc)
|
|
|
|
|
|
|
|
libraries = AshHq.Docs.Library.read!(load: [versions: versions_query])
|
|
|
|
|
|
|
|
selected_versions =
|
2022-08-20 04:35:07 +12:00
|
|
|
Enum.reduce(libraries, configured_library_versions, fn library, acc ->
|
2022-08-31 20:11:15 +12:00
|
|
|
if library.name == "ash" do
|
|
|
|
Map.put_new(acc, library.id, "latest")
|
|
|
|
else
|
|
|
|
Map.put_new(acc, library.id, "")
|
|
|
|
end
|
2022-06-05 08:58:50 +12:00
|
|
|
end)
|
2022-03-26 10:17:01 +13:00
|
|
|
|
2022-06-05 08:58:50 +12:00
|
|
|
{:ok,
|
|
|
|
socket
|
|
|
|
|> assign(:libraries, libraries)
|
|
|
|
|> assign(
|
|
|
|
:selected_versions,
|
|
|
|
selected_versions
|
|
|
|
)
|
|
|
|
|> assign(
|
|
|
|
:selected_types,
|
|
|
|
selected_types
|
|
|
|
)
|
2022-08-20 04:35:07 +12:00
|
|
|
|> assign(:selected_versions, selected_versions)
|
2022-09-13 13:25:03 +12:00
|
|
|
|> assign(configured_theme: configured_theme)
|
2022-06-05 08:58:50 +12:00
|
|
|
|> push_event("selected-versions", selected_versions)
|
2022-08-04 01:53:59 +12:00
|
|
|
|> push_event("selected_types", %{types: selected_types})}
|
2022-03-26 10:17:01 +13:00
|
|
|
end
|
|
|
|
|
2022-03-28 10:26:35 +13:00
|
|
|
def toggle_search(js \\ %JS{}) do
|
|
|
|
js
|
|
|
|
|> JS.toggle(
|
2022-03-30 05:12:28 +13:00
|
|
|
to: "#search-box",
|
|
|
|
in: {
|
|
|
|
"transition ease-in duration-100",
|
|
|
|
"opacity-0",
|
|
|
|
"opacity-100"
|
|
|
|
},
|
|
|
|
out: {
|
|
|
|
"transition ease-out duration-75",
|
|
|
|
"opacity-100",
|
|
|
|
"opacity-0"
|
|
|
|
}
|
2022-03-28 10:26:35 +13:00
|
|
|
)
|
|
|
|
|> JS.dispatch("js:focus", to: "#search-input")
|
2022-03-26 10:17:01 +13:00
|
|
|
end
|
|
|
|
|
2022-09-28 16:18:05 +13:00
|
|
|
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"
|
|
|
|
}
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2022-03-28 10:26:35 +13:00
|
|
|
def close_search(js \\ %JS{}) do
|
|
|
|
js
|
|
|
|
|> JS.hide(
|
2022-03-29 11:05:19 +13:00
|
|
|
transition: "fade-out",
|
|
|
|
to: "#search-box"
|
2022-03-28 10:26:35 +13:00
|
|
|
)
|
2022-09-28 16:18:05 +13:00
|
|
|
|> 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"
|
|
|
|
)
|
2022-03-26 10:17:01 +13:00
|
|
|
end
|
|
|
|
end
|