defmodule GitGudWeb.UserLive.Ci do
@moduledoc """
A user's personal CI view: runs they care about — anything in a repo
they own, are an org member of, or have team access to, plus runs they
personally triggered.
Live-updates by re-querying on any run status change instance-wide
(`Workflows.ci_topic/0`).
"""
use GitGudWeb, :live_view
import GitGudWeb.CiComponents
alias GitGud.Repositories
alias GitGud.Workflows
@impl true
def mount(_params, _session, socket) do
user = socket.assigns.current_scope.user
if connected?(socket),
do: Phoenix.PubSub.subscribe(GitGud.PubSub, Workflows.ci_topic())
{:ok,
socket
|> assign(:user, user)
|> assign(:repo_ids, Repositories.relevant_repo_ids_for_user(user))
|> assign(:filter, :active)
|> assign(:page_title, "My CI")
|> load_runs()}
end
defp load_runs(socket) do
%{user: user, repo_ids: repo_ids} = socket.assigns
active =
Workflows.list_runs_for_user(user.id, repo_ids, statuses: Workflows.active_statuses())
runs =
case socket.assigns.filter do
:active -> active
:all -> Workflows.list_runs_for_user(user.id, repo_ids, limit: 100)
end
socket
|> assign(:active_count, length(active))
|> assign(:runs, runs)
end
@impl true
def handle_event("filter", %{"scope" => scope}, socket) do
filter = if scope == "all", do: :all, else: :active
{:noreply, socket |> assign(:filter, filter) |> load_runs()}
end
@impl true
def handle_info({:ci_run_changed, _run_id}, socket) do
{:noreply, load_runs(socket)}
end
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="space-y-4">
<header class="flex items-baseline justify-between">
<h1 class="text-xl font-semibold">My CI</h1>
<.filter_tabs current={@filter} active_count={@active_count} />
</header>
<p class="text-sm opacity-70">
Runs across repositories you own or work on, plus any run you triggered.
</p>
<ul class="divide-y divide-base-300">
<li :if={@runs == []} class="py-6 opacity-60 text-sm">
{if @filter == :active, do: "Nothing in flight right now.", else: "No workflow runs yet."}
</li>
<.run_row :for={run <- @runs} run={run} show_actor?={true} />
</ul>
</div>
</Layouts.app>
"""
end
end
2.4 KiB · text
5af55d9