# `MishkaGervaz.Table.Web.Live`
[🔗](https://github.com/mishka-group/mishka_gervaz/blob/v0.0.1-alpha.3/lib/mishka_gervaz/table/web/live.ex#L1)

LiveComponent for MishkaGervaz admin tables.

This is a thin orchestrator that delegates to specialized modules:
- `State` - State management
- `DataLoader` - Async data loading with streams
- `Events` - Event handling
- `Renderer` - Template rendering

## Usage

Minimal usage (all config from DSL):

    <.live_component
      module={MishkaGervaz.Table.Web.Live}
      id="posts-table"
      resource={MyApp.Post}
      current_user={@current_user}
    />

That's it! Everything else comes from the DSL defined on your resource.

## Required Assigns

- `id` - Unique component ID
- `resource` - Ash resource module with `MishkaGervaz.Resource` extension
- `current_user` - Current user for authorization

## Parent LiveView Integration

The component sends messages to the parent for certain actions:

    def handle_info({:show_modal, id}, socket), do: ...
    def handle_info({:edit_modal, id}, socket), do: ...
    def handle_info({:show_versions, id}, socket), do: ...
    def handle_info({:expand_row, id}, socket), do: ...
    def handle_info({:row_action, event_name, payload}, socket), do: ...
    def handle_info({:bulk_action, action_name, selected_ids}, socket), do: ...

## PubSub Integration (Automatic)

The component automatically subscribes to PubSub topics when `realtime` is configured
on the resource or domain. It uses `prefix` from the resource's realtime config and
`pubsub` module from domain defaults.

The parent LiveView only needs to forward broadcast notifications to the component:

    def handle_info(
          %Phoenix.Socket.Broadcast{topic: "site" <> _, payload: %Ash.Notifier.Notification{} = notification},
          socket
        ) do
      # Get component_id stored by the component during subscription
      if component_id = Process.get({:mishka_gervaz_component, "site"}) do
        send_update(MishkaGervaz.Table.Web.Live,
          id: component_id,
          pubsub_notification: notification
        )
      end
      {:noreply, socket}
    end

## Expanded Row Content

When a row is expanded via `:raw_accordion` action, send content back:

    def handle_info({:expand_row, id}, socket) do
      # Load expanded content async
      html = render_expanded_content(id)
      send_update(MishkaGervaz.Table.Web.Live,
        id: "posts-table",
        expanded_html: html
      )
      {:noreply, socket}
    end

## Auto Refresh Integration

When `refresh` is enabled in the DSL, the component schedules a timer that sends
`:gervaz_refresh` to the parent LiveView. The parent must handle this and forward
it to the component:

    def handle_info(:gervaz_refresh, socket) do
      # Forward to the table component
      send_update(MishkaGervaz.Table.Web.Live,
        id: "posts-table",
        gervaz_refresh: true
      )
      {:noreply, socket}
    end

Configure refresh in DSL:

    refresh do
      enabled true
      interval 30_000  # 30 seconds
    end

See `MishkaGervaz.Table.Web.State`,
`MishkaGervaz.Table.Web.DataLoader`,
`MishkaGervaz.Table.Web.Events`,
`MishkaGervaz.Table.Web.Renderer`,
`MishkaGervaz.Table.Web.Refresh`,
`MishkaGervaz.Table.Web.UrlSync`,
`MishkaGervaz.Resource.Info.Table`.

---

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