Load persisted step logs when a step is expanded

eaaaea6 · gmorell · 2026-06-25 19:27

2 files +30 -2
Message
{commit_body(@commit)}

Files changed

modified lib/git_gud/workflows.ex
+14 −0
@@ -539,6 +539,20 @@ defmodule GitGud.Workflows do
539 539 append_log(step, seq, [%{content: body}])
540 540 end
541 541
542 + @doc """
543 + Persisted log rows for a step, ascending by sequence. Hydrates the log
544 + view when a step is opened (live appends arrive separately via PubSub).
545 + Returns `%{seq, body}` mapsthe shape the log stream renders.
546 + """
547 + def list_step_logs(step_id) when is_integer(step_id) do
548 + from(l in "workflow_step_logs",
549 + where: l.workflow_step_id == ^step_id,
550 + order_by: [asc: l.seq],
551 + select: %{seq: l.seq, body: l.body}
552 + )
553 + |> Repo.all()
554 + end
555 +
542 556 defp next_log_seq(step_id) do
543 557 max_seq =
544 558 Repo.one(
modified lib/git_gud_web/live/workflow_live/show.ex
+16 −2
@@ -92,8 +92,22 @@ defmodule GitGudWeb.WorkflowLive.Show do
92 92 @impl true
93 93 def handle_event("toggle_step", %{"id" => id}, socket) do
94 94 id = String.to_integer(id)
95 expanded = if socket.assigns.expanded_step == id, do: nil, else: id
96 {:noreply, assign(socket, :expanded_step, expanded)}
95 +
96 + if socket.assigns.expanded_step == id do
97 + {:noreply, assign(socket, :expanded_step, nil)}
98 + else
99 + # Hydrate the log view from persisted rows. The stream is seeded
100 + # empty at mount and only ever fed by live PubSub appends, so a
101 + # finished (or reloaded) run shows nothing until we load them here.
102 + # `reset: true` replaces the stream with the authoritative set;
103 + # dom_id keys on `seq` so any in-flight live appends dedupe.
104 + logs = Workflows.list_step_logs(id)
105 +
106 + {:noreply,
107 + socket
108 + |> assign(:expanded_step, id)
109 + |> stream(stream_name(id), logs, reset: true, dom_id: &"log-#{&1.seq}")}
110 + end
97 111 end
98 112
99 113 def handle_event("rerun", _params, socket) do

Parents: fe5a1ea