mirror of
https://github.com/livebook-dev/livebook.git
synced 2025-12-09 05:05:55 +08:00
Make the app list on auth screen live (#1836)
This commit is contained in:
parent
dbab38a763
commit
92bb567645
5 changed files with 85 additions and 32 deletions
|
|
@ -140,4 +140,17 @@ defmodule Livebook.Apps do
|
|||
|
||||
:ok
|
||||
end
|
||||
|
||||
@doc """
|
||||
Checks if the apps directory is configured and contains no notebooks.
|
||||
"""
|
||||
@spec empty_apps_path?() :: boolean()
|
||||
def empty_apps_path?() do
|
||||
if path = Livebook.Config.apps_path() do
|
||||
pattern = Path.join([path, "**", "*.livemd"])
|
||||
Path.wildcard(pattern) == []
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ defmodule LivebookWeb.AuthController do
|
|||
render(conn, "index.html",
|
||||
errors: [],
|
||||
auth_mode: Livebook.Config.auth_mode(),
|
||||
app_sessions: app_sessions(),
|
||||
empty_apps_path?: empty_apps_path?()
|
||||
any_public_app?: any_public_app?(),
|
||||
empty_apps_path?: Livebook.Apps.empty_apps_path?()
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -56,8 +56,8 @@ defmodule LivebookWeb.AuthController do
|
|||
render(conn, "index.html",
|
||||
errors: errors,
|
||||
auth_mode: auth_mode,
|
||||
app_sessions: app_sessions(),
|
||||
empty_apps_path?: empty_apps_path?()
|
||||
any_public_app?: any_public_app?(),
|
||||
empty_apps_path?: Livebook.Apps.empty_apps_path?()
|
||||
)
|
||||
end
|
||||
|
||||
|
|
@ -75,18 +75,8 @@ defmodule LivebookWeb.AuthController do
|
|||
|> halt()
|
||||
end
|
||||
|
||||
defp app_sessions() do
|
||||
defp any_public_app?() do
|
||||
Livebook.Sessions.list_sessions()
|
||||
|> Enum.filter(&(&1.mode == :app and &1.app_info.public? and &1.app_info.registered))
|
||||
|> Enum.sort_by(& &1.notebook_name)
|
||||
end
|
||||
|
||||
defp empty_apps_path?() do
|
||||
if path = Livebook.Config.apps_path() do
|
||||
pattern = Path.join([path, "**", "*.livemd"])
|
||||
Path.wildcard(pattern) == []
|
||||
else
|
||||
false
|
||||
end
|
||||
|> Enum.any?(&(&1.mode == :app and &1.app_info.public?))
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -62,22 +62,15 @@
|
|||
</div>
|
||||
|
||||
<div
|
||||
:if={@app_sessions != [] or @empty_apps_path?}
|
||||
:if={@any_public_app? or @empty_apps_path?}
|
||||
class="w-full h-full px-4 py-8 flex justify-center items-center"
|
||||
>
|
||||
<div class="w-full flex flex-col items-center">
|
||||
<div class="text-gray-700 text-xl font-medium">
|
||||
Public apps
|
||||
</div>
|
||||
<div :if={@app_sessions != []} class="mt-5 max-w-[400px] w-full flex flex-col space-y-4">
|
||||
<.link
|
||||
:for={session <- @app_sessions}
|
||||
navigate={~p"/apps/#{session.app_info.slug}"}
|
||||
class="px-4 py-3 border border-gray-200 rounded-xl text-gray-800 pointer hover:bg-gray-50 flex justify-between"
|
||||
>
|
||||
<span class="font-semibold"><%= session.notebook_name %></span>
|
||||
<.remix_icon icon="arrow-right-line" class="" />
|
||||
</.link>
|
||||
<div :if={@any_public_app?} class="w-full mt-5 mx-auto max-w-[400px]">
|
||||
<%= live_render(@conn, LivebookWeb.AuthAppListLive) %>
|
||||
</div>
|
||||
<div :if={@empty_apps_path?} class="mt-5 text-gray-600">
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -5,41 +5,42 @@ defmodule LivebookWeb.AppHelpers do
|
|||
Renders app status with indicator.
|
||||
"""
|
||||
attr :status, :atom, required: true
|
||||
attr :show_label, :boolean, default: true
|
||||
|
||||
def app_status(%{status: :booting} = assigns) do
|
||||
~H"""
|
||||
<.app_status_indicator text="Booting" variant={:progressing} />
|
||||
<.app_status_indicator text={@show_label && "Booting"} variant={:progressing} />
|
||||
"""
|
||||
end
|
||||
|
||||
def app_status(%{status: :running} = assigns) do
|
||||
~H"""
|
||||
<.app_status_indicator text="Running" variant={:success} />
|
||||
<.app_status_indicator text={@show_label && "Running"} variant={:success} />
|
||||
"""
|
||||
end
|
||||
|
||||
def app_status(%{status: :error} = assigns) do
|
||||
~H"""
|
||||
<.app_status_indicator text="Error" variant={:error} />
|
||||
<.app_status_indicator text={@show_label && "Error"} variant={:error} />
|
||||
"""
|
||||
end
|
||||
|
||||
def app_status(%{status: :shutting_down} = assigns) do
|
||||
~H"""
|
||||
<.app_status_indicator text="Shutting down" variant={:inactive} />
|
||||
<.app_status_indicator text={@show_label && "Shutting down"} variant={:inactive} />
|
||||
"""
|
||||
end
|
||||
|
||||
def app_status(%{status: :stopped} = assigns) do
|
||||
~H"""
|
||||
<.app_status_indicator text="Stopped" variant={:inactive} />
|
||||
<.app_status_indicator text={@show_label && "Stopped"} variant={:inactive} />
|
||||
"""
|
||||
end
|
||||
|
||||
defp app_status_indicator(assigns) do
|
||||
~H"""
|
||||
<div class="flex items-center space-x-2">
|
||||
<div><%= @text %></div>
|
||||
<div :if={@text}><%= @text %></div>
|
||||
<.status_indicator variant={@variant} />
|
||||
</div>
|
||||
"""
|
||||
|
|
|
|||
56
lib/livebook_web/live/auth_app_list_live.ex
Normal file
56
lib/livebook_web/live/auth_app_list_live.ex
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
defmodule LivebookWeb.AuthAppListLive do
|
||||
use LivebookWeb, :live_view
|
||||
|
||||
import LivebookWeb.AppHelpers
|
||||
import LivebookWeb.SessionHelpers
|
||||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
if connected?(socket) do
|
||||
Livebook.Sessions.subscribe()
|
||||
end
|
||||
|
||||
sessions = Livebook.Sessions.list_sessions() |> Enum.filter(&(&1.mode == :app))
|
||||
|
||||
{:ok, assign(socket, sessions: sessions), layout: false}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def render(assigns) do
|
||||
~H"""
|
||||
<div class="w-full flex flex-col space-y-4">
|
||||
<.link
|
||||
:for={session <- visible_sessions(@sessions)}
|
||||
navigate={~p"/apps/#{session.app_info.slug}"}
|
||||
class={[
|
||||
"px-4 py-3 border border-gray-200 rounded-xl text-gray-800 pointer hover:bg-gray-50 flex justify-between",
|
||||
not session.app_info.registered && "pointer-events-none"
|
||||
]}
|
||||
>
|
||||
<span class="font-semibold"><%= session.notebook_name %></span>
|
||||
<%= if session.app_info.registered do %>
|
||||
<.remix_icon icon="arrow-right-line" class="" />
|
||||
<% else %>
|
||||
<div class="mr-0.5 flex">
|
||||
<.app_status status={session.app_info.status} show_label={false} />
|
||||
</div>
|
||||
<% end %>
|
||||
</.link>
|
||||
</div>
|
||||
"""
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info({type, session} = event, socket)
|
||||
when type in [:session_created, :session_updated, :session_closed] and session.mode == :app do
|
||||
{:noreply, update(socket, :sessions, &update_session_list(&1, event))}
|
||||
end
|
||||
|
||||
def handle_info(_message, socket), do: {:noreply, socket}
|
||||
|
||||
defp visible_sessions(sessions) do
|
||||
sessions
|
||||
|> Enum.filter(& &1.app_info.public?)
|
||||
|> Enum.sort_by(& &1.notebook_name)
|
||||
end
|
||||
end
|
||||
Loading…
Add table
Reference in a new issue