defmodule ServerWeb.VmSearchLive do use ServerWeb, :live_view alias Server.{Hosts, Metrics} @impl true def mount(_params, _session, socket) do if connected?(socket), do: Phoenix.PubSub.subscribe(Server.PubSub, "metrics") {:ok, socket |> assign(:q, "") |> assign(:vms, load_vms())} end @impl true def handle_info({:metric_inserted, _, _}, socket) do {:noreply, assign(socket, :vms, load_vms())} end @impl true def handle_event("search", %{"q" => q}, socket) do {:noreply, assign(socket, :q, q)} end defp load_vms do for host <- Hosts.list_all(), runtime_sample = Metrics.latest_sample(host.id, "fast"), vm <- get_in(runtime_sample && runtime_sample.payload, ["vms_runtime", "vms"]) || [], into: [] do detail_sample = Metrics.latest_sample(host.id, "medium") detail_vms = get_in(detail_sample && detail_sample.payload, ["vms_detail", "vms"]) || [] detail_vm = Enum.find(detail_vms, &(&1["vmid"] == vm["vmid"])) || %{} ips = detail_vm["ips"] || [] %{ vmid: vm["vmid"], name: vm["name"], type: vm["type"], status: vm["status"], host_name: host.name, ips: ips } end end defp filter(vms, ""), do: vms defp filter(vms, q) do q = String.downcase(q) Enum.filter(vms, fn vm -> String.contains?(String.downcase(vm.name || ""), q) or Enum.any?(vm.ips, &String.contains?(&1, q)) end) end @impl true def render(assigns) do ~H"""
| Name | Host | Type | Status | IPs |
|---|---|---|---|---|
| {vm.name} | <.link navigate={~p"/hosts/#{vm.host_name}"} class="text-zinc-700 hover:text-zinc-900 underline" > {vm.host_name} | {vm.type} | {vm.status} | {Enum.join(vm.ips, ", ")} |
| No matches. | ||||