# `MishkaGervaz.Form.Web.Live`
[🔗](https://github.com/mishka-group/mishka_gervaz/blob/v0.0.2/lib/mishka_gervaz/form/web/live.ex#L1)

LiveComponent for MishkaGervaz admin forms.

This is a thin orchestrator that delegates to specialized modules:
- `State` - State management
- `DataLoader` - Record loading and relation options
- `Events` - Event handling
- `Renderer` - Template rendering

## Usage

Create mode (new record):

    <.live_component
      module={MishkaGervaz.Form.Web.Live}
      id="post-form"
      resource={MyApp.Post}
      current_user={@current_user}
    />

Edit mode (existing record):

    <.live_component
      module={MishkaGervaz.Form.Web.Live}
      id="post-form"
      resource={MyApp.Post}
      current_user={@current_user}
      record_id={@post_id}
    />

## Required Assigns

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

## Optional Assigns

- `record_id` - ID of record to edit (nil for create mode)
- `defaults` - Map of default field values for create mode (e.g., `%{workspace_id: @workspace_id}`).
  A picker's default is saved only while the picker still holds it: once it is cleared, or emptied
  because a field it depends on changed, the save leaves it out.
  An update that leaves the key out, such as the `send_update/2` a table's Edit sends with only a
  `record_id`, keeps the defaults the form has. Pass `defaults: nil` to drop them.
- `reset` - `true` starts the form over on its `record_id`, even when that is the record already
  open, or `nil` while the form is already on create. See "Opening a form again".

## Opening a form again

A form that stays mounted while it is hidden — in a modal that is shown and hidden, say — keeps
what was typed, its errors and its pending uploads through a close that sends it nothing, such as
a modal's close icon. Whatever opens it again starts it over:

    send_update(MishkaGervaz.Form.Web.Live, id: "post-form", record_id: nil, reset: true)

A create returns to the empty create form, with the form's `defaults`; an edit reads its record
again. The uploads are cancelled. A create is drawn once without its `<form>` before the empty one
is built, so every control is drawn anew, a `phx-update="ignore"` one included, and reads the new
value. A table's Edit sends `reset: true` with the row's `record_id`. A button that opens the form
without asking the server uses `reset/2`.

## After a save

A create save always returns the form to an empty create form. An update save depends on how the
form was mounted:

- mounted with a `record_id` assign (even `nil`) — the form stays on the saved record, reloaded
  for editing. Pass a different `record_id`, or `nil`, to move it.
- mounted without one, and opened for editing with `send_update/2` — the form returns to an
  empty create form.

## Parent LiveView Integration

The component sends messages to the parent for certain actions:

    def handle_info({:form_saved, :create, result}, socket), do: ...
    def handle_info({:form_saved, :update, result}, socket), do: ...
    def handle_info({:form_cancelled, resource}, socket), do: ...
    def handle_info({:form_event, event, params}, socket), do: ...
    def handle_info({:add_nested_field, field_name}, socket), do: ...
    def handle_info({:remove_nested_field, field_name, index}, socket), do: ...

See `MishkaGervaz.Form.Web.State` (state shape + override surface),
`MishkaGervaz.Form.Web.DataLoader` (record + relation loading),
`MishkaGervaz.Form.Web.Events` (event handling),
`MishkaGervaz.Form.Web.Renderer` (template dispatch),
`MishkaGervaz.Form.Web.UploadHelpers`, and
`MishkaGervaz.Form.Behaviours.Template`.

# `reset`

```elixir
@spec reset(Phoenix.LiveView.JS.t(), String.t()) :: Phoenix.LiveView.JS.t()
```

The JS command that starts the form with this component `id` over as an empty create form, as
`reset: true` with a `nil` `record_id` does. For a button that shows a hidden form on the client:

    <button phx-click={MishkaGervaz.Form.Web.Live.reset("post-form") |> show_modal("post-modal")}>

It pushes the form's `reset` event to the element with the id `"<id>-form-wrapper"`.

---

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