MishkaGervaz.Table.Web.Refresh (MishkaGervaz v0.0.1-alpha.2)

Copy Markdown View Source

Auto-refresh functionality for MishkaGervaz tables.

Provides automatic data reloading at configurable intervals with intelligent pausing during user interactions.

Configuration

Enable in domain table config:

mishka_gervaz do
  table do
    refresh do
      enabled true
      interval 30_000  # 30 seconds
      pause_on_interaction true
      show_indicator true
      pause_on_blur true
    end
  end
end

Usage in LiveComponent

The table LiveComponent integrates with this module:

def mount(socket) do
  socket =
    socket
    |> assign(:refresh_config, get_refresh_config())
    |> Refresh.init()

  {:ok, socket}
end

def handle_info(:gervaz_refresh, socket) do
  socket =
    socket
    |> reload_data()
    |> Refresh.schedule(socket.assigns.refresh_config)

  {:noreply, socket}
end

def handle_event("filter", params, socket) do
  # Pause refresh during interaction
  socket = Refresh.pause(socket)

  # ... handle filter ...

  # Resume after interaction
  socket = Refresh.resume(socket, socket.assigns.refresh_config)
  {:noreply, socket}
end

Client-side Integration

For pause_on_blur, add this to your app.js:

window.addEventListener("blur", () => {
  document.querySelectorAll("[data-gervaz-refresh]").forEach(el => {
    el.dispatchEvent(new CustomEvent("gervaz:pause_refresh"))
  })
})

window.addEventListener("focus", () => {
  document.querySelectorAll("[data-gervaz-refresh]").forEach(el => {
    el.dispatchEvent(new CustomEvent("gervaz:resume_refresh"))
  })
})

See MishkaGervaz.Table.Web.State, MishkaGervaz.Table.Web.AutoState, MishkaGervaz.Table.Web.DataLoader, MishkaGervaz.Table.Dsl.Refresh (resource-level DSL section), MishkaGervaz.Table.Dsl.Defaults (domain-level defaults).

Summary

Functions

Check if refresh is currently active.

Get default refresh configuration.

Build refresh indicator assigns for templates.

Initialize refresh state in socket.

Pause auto-refresh.

Check if refresh is paused.

Get the refresh message atom used for handle_info.

Resume auto-refresh after pause.

Schedule the next refresh.

Stop auto-refresh completely.

Get time until next refresh in milliseconds.

Functions

active?(socket)

@spec active?(Phoenix.LiveView.Socket.t()) :: boolean()

Check if refresh is currently active.

default_config()

@spec default_config() :: map()

Get default refresh configuration.

indicator_assigns(socket, config)

@spec indicator_assigns(Phoenix.LiveView.Socket.t(), map()) :: map()

Build refresh indicator assigns for templates.

Returns a map with:

  • active? - whether refresh is active
  • paused? - whether refresh is paused
  • interval - refresh interval in ms
  • next_in - time until next refresh in ms

init(socket)

Initialize refresh state in socket.

Call this in mount/1:

socket
|> assign(:refresh_config, config)
|> Refresh.init()

pause(socket)

Pause auto-refresh.

Call this when user starts interacting:

def handle_event("filter", _params, socket) do
  socket = Refresh.pause(socket)
  # ... handle filter
end

paused?(socket)

@spec paused?(Phoenix.LiveView.Socket.t()) :: boolean()

Check if refresh is paused.

refresh_message()

@spec refresh_message() :: atom()

Get the refresh message atom used for handle_info.

resume(socket, config)

Resume auto-refresh after pause.

Call this when user finishes interacting:

socket
|> Refresh.resume(socket.assigns.refresh_config)

schedule(socket, config)

Schedule the next refresh.

Call this after handling @refresh_message:

def handle_info(:gervaz_refresh, socket) do
  socket =
    socket
    |> reload_data()
    |> Refresh.schedule(socket.assigns.refresh_config)

  {:noreply, socket}
end

stop(socket)

Stop auto-refresh completely.

Call this in terminate/2 or when disabling:

Refresh.stop(socket)

time_until_next(socket, config)

@spec time_until_next(Phoenix.LiveView.Socket.t(), map()) :: non_neg_integer() | nil

Get time until next refresh in milliseconds.

Returns nil if refresh is not scheduled.