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

Helpers for bulk-action lifecycle hook authors.

The 3-arity variants of `:on_bulk_action_success` and
`:on_bulk_action_error` (and the unarchive conflict-skip success branch)
receive `(summary, state, socket)` and can return either:

  * a plain `socket` — the core handler then fires its **default flash**
    (e.g. `"3 succeeded, 2 failed"` on partial, or the error flash).
  * `{:halt, socket}` — the core handler **skips** the default flash; the
    hook is fully responsible for messaging.

Use `silence/1` for the halt path and (optionally) `use_default/1` as a
documentation-friendly no-op when you want the default flash to fire.

## Examples

Replace the default with a custom message:

    hooks do
      on_bulk_action_success :master_unarchive, fn summary, _state, socket ->
        socket
        |> Phoenix.LiveView.put_flash(:info, "Restored #{summary.succeeded_count} components.")
        |> MishkaGervaz.Table.Web.Events.BulkActionHooks.silence()
      end
    end

Suppress the error flash entirely (e.g. log it instead):

    on_bulk_action_error :destroy, fn summary, _state, socket ->
      Logger.warning("destroy failed: #{inspect(summary.failed_errors)}")
      MishkaGervaz.Table.Web.Events.BulkActionHooks.silence(socket)
    end

Let the default fire and just observe:

    on_bulk_action_success :destroy, fn summary, _state, socket ->
      :telemetry.execute([:my_app, :destroy, :success], %{count: summary.succeeded_count})
      socket
    end

## Customization

Like the sibling handlers in `events/`, the helpers are overridable:

    defmodule MyApp.BulkActionHooks do
      use MishkaGervaz.Table.Web.Events.BulkActionHooks

      # Wrap silence/1 with logging
      def silence(socket) do
        Logger.debug("default bulk flash suppressed")
        super(socket)
      end
    end

See `MishkaGervaz.Table.Web.Events.BulkActionResult` for the summary
shape, and `MishkaGervaz.Table.Web.Events.BulkActionHandler` for the
full lifecycle.

# `put_flash`

```elixir
@callback put_flash(Phoenix.LiveView.Socket.t(), atom(), String.t()) ::
  Phoenix.LiveView.Socket.t()
```

Sets a flash message that reliably reaches the parent LiveView.

Bulk hooks run inside `MishkaGervaz.Table.Web.Live` — a `Phoenix.LiveComponent`.
Calling `Phoenix.LiveView.put_flash/3` directly only puts the flash on the
*component's* `@flash`, and Phoenix only copies it to the parent on a
subsequent `push_patch` / `push_navigate` (per the `put_flash/3` doc). The
parent's layout reads the parent's `@flash`, so a direct `put_flash` from
a hook often appears late or not at all.

This helper sends `{:put_flash, kind, msg}` to the LiveView process; admin
pages have a `handle_info/2` bridge that calls `put_flash/3` on the parent.

# `silence`

```elixir
@callback silence(Phoenix.LiveView.Socket.t()) :: {:halt, Phoenix.LiveView.Socket.t()}
```

Halts the core handler's default flash; the hook owns messaging.

# `use_default`

```elixir
@callback use_default(Phoenix.LiveView.Socket.t()) :: Phoenix.LiveView.Socket.t()
```

Continues with the core handler's default flash; documentation-friendly alias for returning the socket unchanged.

# `put_flash`

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

Convenience entry point delegating to `__MODULE__.Default.put_flash/3`.

# `silence`

```elixir
@spec silence(Phoenix.LiveView.Socket.t()) :: {:halt, Phoenix.LiveView.Socket.t()}
```

Convenience entry point delegating to `__MODULE__.Default.silence/1`.

# `use_default`

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

Convenience entry point delegating to `__MODULE__.Default.use_default/1`.

---

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