# SPDX-FileCopyrightText: 2020 Zach Daniel # SPDX-FileCopyrightText: 2020 ash_admin contributors # # SPDX-License-Identifier: MIT defmodule AshAdmin.Components.Resource.Form do @moduledoc false use Phoenix.LiveComponent import AshAdmin.Helpers import AshAdmin.CoreComponents require Logger attr :resource, :any, required: true attr :domain, :any, required: true attr :record, :any, default: nil attr :type, :atom, default: nil attr :actor, :any, default: nil attr :tenant, :any, default: nil attr :authorizing, :boolean, default: false attr :action, :any, required: true attr :table, :any, required: true attr :tables, :any, required: true attr :prefix, :any, required: true attr :url_path, :any, required: true attr :params, :any, required: true attr :polymorphic_actions, :any, required: true def mount(socket) do {:ok, socket |> assign_new(:load_errors, fn -> %{} end) |> assign_new(:loaded, fn -> %{} end) |> assign_new(:uploaded_files, fn -> %{} end) |> assign(:params, %{})} end def update(assigns, socket) do {:ok, socket |> assign(assigns) |> assign(:typeahead_options, []) |> assign_form() |> allow_uploading_form_arguments() |> assign(:initialized, true)} end def render(assigns) do ~H"""
{render_form(assigns)}
{AshAdmin.Components.Resource.Show.render_show( assigns, @record, @resource, "Original Record", false )}
""" end defp all_errors(form) do form |> AshPhoenix.Form.errors(for_path: :all) |> Enum.flat_map(fn {path, errors} -> Enum.map(errors, fn {field, message} -> path = List.wrap(path) case Enum.reject(path ++ List.wrap(field), &is_nil/1) do [] -> {nil, message} items -> {Enum.join(items, "."), message} end end) end) end defp render_form(assigns) do ~H"""
  • {field}: {message}

{String.capitalize(to_string(@action.type))} {AshAdmin.Resource.name(@resource)}

<.form :let={form} as={:action} for={to_form(%{}, as: :action)} phx-change="change_action" phx-target={@myself} id="_action_form" > <.input type="select" field={form[:action]} disabled={Enum.count(actions(@resource, @type)) <= 1} options={actions(@resource, @type)} value={to_string(@action.name)} />
<.form :let={form} for={@form} phx-change="validate" phx-submit="save" phx-target={@myself} autocomplete={false} id="form" > <.input :for={kv <- form.hidden} name={form.name <> "[#{elem(kv, 0)}]"} value={elem(kv, 1)} type="hidden" /> {render_attributes(assigns, @resource, @action, form)}
""" end defp save_button_text(:update), do: "Save" defp save_button_text(type), do: type |> to_string() |> String.capitalize() def render_attributes( assigns, resource, action, form, exactly \\ nil, skip \\ [] ) do assigns = assign(assigns, resource: resource, action: action, form: form, exactly: exactly, skip: skip ) ~H""" <% {attributes, flags, bottom_attributes, relationship_args} = attributes(@resource, @action, @exactly) %>
{render_attribute_input(assigns, attribute, @form)} <.error_tag :for={{error, vars} <- Keyword.get_values(@form.errors || [], attribute.name)} :if={!Ash.Type.embedded_type?(attribute.type)} > {replace_vars(error, vars)}