lib/openagents_web/live/timeline_live.ex

436d37facc96 · 2 KB

defmodule OpenAgentsWeb.TimelineLive do
  @moduledoc """
  The account's unified timeline as a page.

  Every entry is rooted in the account's visitor. Only the current account's
  own coder, voice, and chat activity is shown, newest first.
  """

  use OpenAgentsWeb, :live_view

  alias OpenAgents.Timeline

  @impl true
  def mount(_params, _session, %{assigns: %{current_user: current_user}} = socket) do
    entries =
      Timeline.for_user(current_user)
      |> Enum.reverse()

    {:ok,
     socket
     |> assign(:page_title, "Timeline")
     |> assign(:entries, entries)}
  end

  @impl true
  def render(assigns) do
    ~H"""
    <Layouts.app
      flash={@flash}
      sidebar_sections={assigns[:sidebar_sections]}
      current_scope={@current_scope}
    >
      <main id="timeline" class="mx-auto w-full max-w-5xl space-y-6 px-4 py-10">
        <.header>
          Timeline
          <:subtitle>Your account's activity, newest first.</:subtitle>
        </.header>

        <.empty :if={@entries == []} id="timeline-empty" title="No activity yet">
          Your chat, voice, and coder sessions appear here when they start.
        </.empty>

        <.table
          :if={@entries != []}
          id="timeline-table"
          rows={@entries}
          row_id={&"timeline-entry-#{&1.record_id}"}
        >
          <:col :let={entry} label="When">
            <span :if={is_nil(entry.timestamp)} class="text-muted-foreground">—</span>
            <.time_ago :if={entry.timestamp} at={entry.timestamp} />
          </:col>
          <:col :let={entry} label="Modality">
            {modality_label(entry.modality)}
          </:col>
          <:col :let={entry} label="Kind">
            <.badge variant={kind_variant(entry.kind)}>{kind_label(entry.kind)}</.badge>
          </:col>
          <:col :let={entry} label="Summary">
            {entry.summary}
          </:col>
        </.table>
      </main>
    </Layouts.app>
    """
  end

  defp modality_label(modality) do
    modality
    |> to_string()
    |> String.capitalize()
  end

  defp kind_label(kind) do
    kind
    |> to_string()
    |> String.replace("_", " ")
    |> String.capitalize()
  end

  defp kind_variant(:turn), do: :info
  defp kind_variant(:tool_step), do: :warning
  defp kind_variant(:decision), do: :success
  defp kind_variant(:system), do: :default
  defp kind_variant(_kind), do: :default
end