defmodule LivebookWeb.SessionLive.PackageSearchLive do use LivebookWeb, :live_view @impl true def mount(_params, %{"session_pid" => session_pid, "runtime" => runtime}, socket) do socket = assign(socket, session: Livebook.Session.get_by_pid(session_pid), runtime: runtime, search: "", search_ref: nil, packages: [], error_message: nil ) socket = if connected?(socket), do: do_search(socket, ""), else: socket {:ok, socket} end @impl true def render(assigns) do ~H"""

Search packages

Find external packages for your notebook

<.text_field name="search" value={@search} phx-debounce="250" placeholder="Search" autocomplete="off" spellcheck="false" autofocus />
<%= cond do %> <% @error_message -> %>
{@error_message}
<% @packages == [] -> %>
<.remix_icon icon="windy-line" class="text-xl" />
No results
<% true -> %> <.package :for={{package, idx} <- Enum.with_index(@packages)} package={package} idx={idx} /> <% end %>
""" end defp package(assigns) do ~H"""
<%= if @package[:url] do %> {@package.name} <% else %> {@package.name} <% end %> {@package.version}
{@package.description}
<.button color="gray" small aria-label="add" phx-click={JS.push("add", value: %{idx: @idx})}> <.remix_icon icon="add-line" /> Add
""" end @impl true def handle_event("search", %{"search" => search}, socket) do {:noreply, do_search(socket, search)} end @impl true def handle_event("submit", %{}, socket) do socket = case socket.assigns.packages do [] -> socket [first | _] -> add_dependency(socket, first.dependency) end {:noreply, socket} end @impl true def handle_event("add", %{"idx" => idx}, socket) do package = Enum.fetch!(socket.assigns.packages, idx) socket = add_dependency(socket, package.dependency) {:noreply, socket} end @impl true def handle_info( {:runtime_search_packages_response, ref, response}, %{assigns: %{search_ref: ref}} = socket ) do socket = case response do {:ok, packages} -> assign(socket, packages: packages, error_message: nil) {:error, message} -> assign(socket, error_message: Livebook.Utils.upcase_first(message)) end {:noreply, assign(socket, search_ref: nil)} end def handle_info(_message, socket), do: {:noreply, socket} defp do_search(socket, search) do search_ref = Livebook.Runtime.search_packages(socket.assigns.runtime, self(), search) assign(socket, search_ref: search_ref, search: search) end defp add_dependency(socket, dependency) do Livebook.Session.add_dependencies(socket.assigns.session.pid, [dependency]) assign(socket, search: "", search_ref: nil, packages: []) end end