mirror of
https://github.com/ash-project/ash_phoenix.git
synced 2024-09-20 07:12:49 +12:00
improvement: experimental Form.params
options
fix: don't allow embeds to be sparse
This commit is contained in:
parent
ce9e7fc639
commit
2075d4e975
2 changed files with 80 additions and 50 deletions
|
@ -69,7 +69,8 @@ defmodule AshPhoenix.Form.Auto do
|
|||
],
|
||||
sparse_lists?: [
|
||||
type: :boolean,
|
||||
doc: "Sets all list type forms to `sparse?: true` by default.",
|
||||
doc:
|
||||
"Sets all list type forms to `sparse?: true` by default. Has no effect on forms derived for embedded resources.",
|
||||
default: false
|
||||
]
|
||||
]
|
||||
|
@ -451,9 +452,9 @@ defmodule AshPhoenix.Form.Auto do
|
|||
[
|
||||
type: type,
|
||||
resource: embed,
|
||||
sparse?: auto_opts[:sparse_lists?],
|
||||
create_action: create_action.name,
|
||||
update_action: update_action.name,
|
||||
embed?: true,
|
||||
data: data,
|
||||
forms: [],
|
||||
updater: fn opts ->
|
||||
|
|
|
@ -1260,8 +1260,12 @@ defmodule AshPhoenix.Form do
|
|||
"""
|
||||
@spec params(t()) :: map
|
||||
def params(form, opts \\ []) do
|
||||
# These options aren't documented because they are still experimental
|
||||
hidden? = opts[:hidden?] || false
|
||||
indexed_lists? = opts[:indexed_lists?] || false
|
||||
indexer = opts[:indexer]
|
||||
indexed_lists? = opts[:indexed_lists?] || not is_nil(indexer) || false
|
||||
transform = opts[:transform]
|
||||
only_touched? = Keyword.get(opts, :only_touched?, true)
|
||||
|
||||
form_keys =
|
||||
form.form_keys
|
||||
|
@ -1279,57 +1283,79 @@ defmodule AshPhoenix.Form do
|
|||
params
|
||||
end
|
||||
|
||||
form.form_keys
|
||||
|> Enum.filter(fn {key, _} ->
|
||||
untransformed_params =
|
||||
form.form_keys
|
||||
|> only_touched(form, only_touched?)
|
||||
|> Enum.reduce(params, fn {key, config}, params ->
|
||||
case config[:type] || :single do
|
||||
:single ->
|
||||
if form.forms[key] do
|
||||
nested_params =
|
||||
if form.forms[key] do
|
||||
params(form.forms[key], opts)
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
if form.form_keys[key][:merge?] do
|
||||
Map.merge(nested_params || %{}, params)
|
||||
else
|
||||
Map.put(params, to_string(config[:for] || key), nested_params)
|
||||
end
|
||||
else
|
||||
Map.put(params, to_string(config[:for] || key), nil)
|
||||
end
|
||||
|
||||
:list ->
|
||||
for_name = to_string(config[:for] || key)
|
||||
|
||||
if indexed_lists? do
|
||||
params
|
||||
|> Map.put_new(for_name, %{})
|
||||
|> Map.update!(for_name, fn current ->
|
||||
if indexer do
|
||||
Enum.reduce(form.forms[key], current, fn form, current ->
|
||||
Map.put(current, indexer.(form), params(form, opts))
|
||||
end)
|
||||
else
|
||||
max =
|
||||
current
|
||||
|> Map.keys()
|
||||
|> Enum.map(&String.to_integer/1)
|
||||
|> Enum.max(fn -> -1 end)
|
||||
|
||||
form.forms[key]
|
||||
|> Enum.reduce({current, max + 1}, fn form, {current, i} ->
|
||||
{Map.put(current, to_string(i), params(form, opts)), i + 1}
|
||||
end)
|
||||
|> elem(0)
|
||||
end
|
||||
end)
|
||||
else
|
||||
params
|
||||
|> Map.put_new(for_name, [])
|
||||
|> Map.update!(for_name, fn current ->
|
||||
current ++ Enum.map(form.forms[key] || [], ¶ms(&1, opts))
|
||||
end)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
if transform do
|
||||
Map.new(untransformed_params, transform)
|
||||
else
|
||||
untransformed_params
|
||||
end
|
||||
end
|
||||
|
||||
defp only_touched(form_keys, true, form) do
|
||||
Enum.filter(form_keys, fn {key, _} ->
|
||||
MapSet.member?(form.touched_forms, to_string(key))
|
||||
end)
|
||||
|> Enum.reduce(params, fn {key, config}, params ->
|
||||
case config[:type] || :single do
|
||||
:single ->
|
||||
if form.forms[key] do
|
||||
nested_params =
|
||||
if form.forms[key] do
|
||||
params(form.forms[key], opts)
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
if form.form_keys[key][:merge?] do
|
||||
Map.merge(nested_params || %{}, params)
|
||||
else
|
||||
Map.put(params, to_string(config[:for] || key), nested_params)
|
||||
end
|
||||
else
|
||||
Map.put(params, to_string(config[:for] || key), nil)
|
||||
end
|
||||
|
||||
:list ->
|
||||
for_name = to_string(config[:for] || key)
|
||||
|
||||
if indexed_lists? do
|
||||
params
|
||||
|> Map.put_new(for_name, %{})
|
||||
|> Map.update!(for_name, fn current ->
|
||||
max =
|
||||
current |> Map.keys() |> Enum.map(&String.to_integer/1) |> Enum.max(fn -> -1 end)
|
||||
|
||||
form.forms[key]
|
||||
|> Enum.reduce({current, max + 1}, fn form, {current, i} ->
|
||||
{Map.put(current, to_string(i), params(form, opts)), i + 1}
|
||||
end)
|
||||
|> elem(0)
|
||||
end)
|
||||
else
|
||||
params
|
||||
|> Map.put_new(for_name, [])
|
||||
|> Map.update!(for_name, fn current ->
|
||||
current ++ Enum.map(form.forms[key] || [], ¶ms(&1, opts))
|
||||
end)
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp only_touched(form_keys, _, _), do: form_keys
|
||||
|
||||
@add_form_opts [
|
||||
prepend: [
|
||||
type: :boolean,
|
||||
|
@ -2851,6 +2877,9 @@ defmodule AshPhoenix.Form do
|
|||
|> Enum.sort_by(fn {params, key} ->
|
||||
params["_index"] || key
|
||||
end)
|
||||
|
||||
# rescue
|
||||
# _ ->
|
||||
end
|
||||
|
||||
defp indexed_list(other) do
|
||||
|
|
Loading…
Reference in a new issue