LiveComponent for MishkaGervaz admin tables.
This is a thin orchestrator that delegates to specialized modules:
State- State managementDataLoader- Async data loading with streamsEvents- Event handlingRenderer- 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 IDresource- Ash resource module withMishkaGervaz.Resourceextensioncurrent_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}
endExpanded 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}
endAuto 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}
endConfigure refresh in DSL:
refresh do
enabled true
interval 30_000 # 30 seconds
endSee 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.