# `PhoenixKitWeb.Components.Dashboard.LiveTabs`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.165/lib/phoenix_kit_web/components/dashboard/live_tabs.ex#L1)

LiveView integration for dashboard tabs with real-time updates.

This module provides hooks and helpers for LiveViews to integrate with
the dashboard tab system, including:

- Automatic tab subscription and updates
- Badge value synchronization via PubSub
- Presence tracking for viewer counts
- Group collapse state management

## Usage in LiveViews

    defmodule MyAppWeb.DashboardLive do
      use MyAppWeb, :live_view
      use PhoenixKitWeb.Components.Dashboard.LiveTabs

      def mount(_params, _session, socket) do
        socket =
          socket
          |> init_dashboard_tabs()
          |> track_tab_presence(:my_tab)

        {:ok, socket}
      end

      # Tabs automatically update when badges change
    end

## Manual Integration

If you prefer manual control:

    def mount(_params, _session, socket) do
      if connected?(socket) do
        Phoenix.PubSub.subscribe(PhoenixKit.PubSub, PhoenixKit.Dashboard.pubsub_topic())

        # Subscribe to badge topics for live updates
        for tab <- PhoenixKit.Dashboard.get_tabs() do
          if tab.badge && tab.badge.subscribe do
            topic = PhoenixKit.Dashboard.Badge.get_topic(tab.badge)
            Phoenix.PubSub.subscribe(PhoenixKit.PubSub, topic)
          end
        end
      end

      {:ok, assign(socket, :dashboard_tabs, PhoenixKit.Dashboard.get_tabs())}
    end

    def handle_info({:tab_updated, _tab}, socket) do
      {:noreply, assign(socket, :dashboard_tabs, PhoenixKit.Dashboard.get_tabs())}
    end

# `__using__`
*macro* 

Use this module in a LiveView to get dashboard tab helpers.

# `clear_tab_attention`

```elixir
@spec clear_tab_attention(Phoenix.LiveView.Socket.t(), atom()) ::
  Phoenix.LiveView.Socket.t()
```

Clears attention animation from a tab.

# `get_badge_value`

```elixir
@spec get_badge_value(map(), map()) :: any()
```

Gets the badge value for a tab, checking context-aware values first.

For context-aware badges, returns the value from `:context_badge_values`.
For regular badges, returns the badge's stored value.

## Examples

    # In template
    <%= get_badge_value(@context_badge_values, tab) %>

# `init_dashboard_tabs`

```elixir
@spec init_dashboard_tabs(
  Phoenix.LiveView.Socket.t(),
  keyword()
) :: Phoenix.LiveView.Socket.t()
```

Initializes dashboard tabs in a LiveView socket.

This function:
1. Loads tabs from the registry
2. Subscribes to tab updates
3. Subscribes to badge update topics (with context resolution for context-aware badges)
4. Initializes viewer counts
5. Loads initial values for context-aware badges

## Options

- `:show_presence` - Load and track presence counts (default: true)
- `:subscribe_badges` - Subscribe to live badge topics (default: true)

## Context-Aware Badges

For badges with `context_key` set, this function:
- Resolves topic placeholders using the current context from `current_contexts_map`
- Loads initial badge values using the badge's loader function
- Stores context badge values in `:context_badge_values` assign

## Examples

    socket = init_dashboard_tabs(socket)
    socket = init_dashboard_tabs(socket, show_presence: false)

# `refresh_dashboard_tabs`

```elixir
@spec refresh_dashboard_tabs(Phoenix.LiveView.Socket.t()) ::
  Phoenix.LiveView.Socket.t()
```

Refreshes the dashboard tabs from the registry.

Call this when you need to force a refresh of tab data.
Context-aware badge values are preserved during refresh.

# `reinit_context_badges`

```elixir
@spec reinit_context_badges(Phoenix.LiveView.Socket.t()) ::
  Phoenix.LiveView.Socket.t()
```

Reinitializes context-aware badges when context changes.

Call this when the user switches context (e.g., selects a different organization).
It will:
- Subscribe to new context-specific PubSub topics
- Load new badge values for the new context
- Merge updated values into dashboard tabs

Note: Old PubSub subscriptions are not explicitly removed. They will be cleaned
up when the LiveView process terminates. If your context switch doesn't involve
navigation, filter incoming PubSub messages by checking the current context.

## Examples

    def handle_info({:context_changed, :organization, new_org}, socket) do
      socket =
        socket
        |> assign(:current_contexts_map, %{organization: new_org})
        |> reinit_context_badges()

      {:noreply, socket}
    end

# `set_tab_attention`

```elixir
@spec set_tab_attention(Phoenix.LiveView.Socket.t(), atom(), atom()) ::
  Phoenix.LiveView.Socket.t()
```

Sets attention animation on a tab.

## Examples

    set_tab_attention(socket, :alerts, :pulse)

# `track_tab_presence`

```elixir
@spec track_tab_presence(Phoenix.LiveView.Socket.t(), atom(), keyword()) ::
  Phoenix.LiveView.Socket.t()
```

Tracks the current user's presence on a specific tab.

Call this in mount/3 to track which tab the user is viewing.

## Examples

    socket = track_tab_presence(socket, :orders)
    socket = track_tab_presence(socket, :printers, meta: %{printer_id: 123})

# `untrack_tab_presence`

```elixir
@spec untrack_tab_presence(Phoenix.LiveView.Socket.t()) :: Phoenix.LiveView.Socket.t()
```

Untracks the current user from their tracked tab.

Call this when leaving a tab or on terminate.

# `update_context_badge`

```elixir
@spec update_context_badge(Phoenix.LiveView.Socket.t(), atom(), any()) ::
  Phoenix.LiveView.Socket.t()
```

Updates a context-aware badge value in socket assigns.

Use this when handling PubSub messages for context-aware badges. Unlike
`update_tab_badge/3` which updates global ETS, this updates the socket assigns
so each user sees their own value.

## Examples

    def handle_info({:alert_count_update, count}, socket) do
      {:noreply, update_context_badge(socket, :alerts, count)}
    end

# `update_tab_badge`

```elixir
@spec update_tab_badge(Phoenix.LiveView.Socket.t(), atom(), any()) ::
  Phoenix.LiveView.Socket.t()
```

Updates a specific tab's badge and broadcasts the update.

This is a convenience wrapper that updates the badge and triggers
a broadcast to all connected LiveViews.

## Examples

    update_tab_badge(socket, :notifications, 5)
    update_tab_badge(socket, :alerts, count: 3, color: :error)

---

*Consult [api-reference.md](api-reference.md) for complete listing*
