mirror of
https://github.com/ash-project/ash_phoenix.git
synced 2024-09-19 06:42:47 +12:00
improvement: update to latest ash, prepare for ash-2.0
This commit is contained in:
parent
5723a449a7
commit
0d1d5b5465
13 changed files with 100 additions and 25 deletions
15
documentation/topics/working-with-phoenix.md
Normal file
15
documentation/topics/working-with-phoenix.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Working With Phoenix
|
||||
|
||||
The AshPhoenix plugin adds lots of helpers for working with Phoenix Liveview (and regular views).
|
||||
|
||||
{{mix_dep:ash_phoenix}}
|
||||
|
||||
## Whats in the box?
|
||||
|
||||
- {{link:ash_phoenix:module:AshPhoenix.Form}} - A form data structure for using resource actions with phoenix forms
|
||||
- {{link:ash_phoenix:module:AshPhoenix.Form.Auto}} - Tools to automatically determine nested form structures based on calls `manage_relationship` for an action.
|
||||
- {{link:ash_phoenix:module:AshPhoenix.FilterForm}} - A form data structure for building filter statements
|
||||
- {{link:ash_phoenix:module:AshPhoenix.LiveView}} - Helpers for querying data and integrating changes
|
||||
- {{link:ash_phoenix:module:AshPhoenix.SubdomainPlug}} - A plug to determine a tenant using subdomains for multitenancy
|
||||
- {{link:ash_phoenix:module:AshPhoenix.FormData.Error}} - A protocol to allow errors to be rendered in forms
|
||||
- `Phoenix.HTML.Safe` implementations for `Ash.CiString` and `Ash.NotLoaded`
|
|
@ -5,24 +5,6 @@ defmodule AshPhoenix do
|
|||
These will be deprecated at some point, once the work on `AshPhoenix.Form` is complete.
|
||||
"""
|
||||
|
||||
require Logger
|
||||
|
||||
def hide_errors(%Ash.Changeset{} = changeset) do
|
||||
Ash.Changeset.put_context(changeset, :private, %{ash_phoenix: %{hide_errors: true}})
|
||||
end
|
||||
|
||||
def hide_errors(%Ash.Query{} = query) do
|
||||
Ash.Query.put_context(query, :private, %{ash_phoenix: %{hide_errors: true}})
|
||||
end
|
||||
|
||||
def hiding_errors?(%Ash.Changeset{} = changeset) do
|
||||
changeset.context[:private][:ash_phoenix][:hide_errors] == true
|
||||
end
|
||||
|
||||
def hiding_errors?(%Ash.Query{} = query) do
|
||||
query.context[:private][:ash_phoenix][:hide_errors] == true
|
||||
end
|
||||
|
||||
@doc false
|
||||
def replace_vars(message, vars) do
|
||||
Enum.reduce(vars || [], message, fn {key, value}, acc ->
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
defmodule AshPhoenix.Form.Auto do
|
||||
@moduledoc """
|
||||
A (slightly) experimental tool to automatically generate available nested forms based on a resource and action.
|
||||
A tool to automatically generate available nested forms based on a resource and action.
|
||||
|
||||
To use this, specify `forms: [auto?: true]` when creating the form.
|
||||
|
||||
Keep in mind, you can always specify these manually when creating a form by simply specifying the `forms` option.
|
||||
|
||||
There are two things that this builds forms for:
|
||||
|
||||
1. Attributes/arguments who's type is an embedded resource.
|
||||
|
@ -25,7 +27,7 @@ defmodule AshPhoenix.Form.Auto do
|
|||
<%= text_input comment_form, :on_create_field %>
|
||||
<% else %>
|
||||
<%= text_input comment_form, :text %>
|
||||
<%= text_input comment_form, :on_create_field %>
|
||||
<%= text_input comment_form, :on_update_field %>
|
||||
<% end %>
|
||||
|
||||
<button phx-click="remove_form" phx-value-path="<%= comment_form.name %>">Add Comment</button>
|
||||
|
|
|
@ -332,7 +332,6 @@ defmodule AshPhoenix.Form do
|
|||
]
|
||||
]
|
||||
|
||||
@doc false
|
||||
defp validate_opts_with_extra_keys(opts, schema) do
|
||||
keys = Keyword.keys(schema)
|
||||
|
||||
|
@ -1513,6 +1512,13 @@ defmodule AshPhoenix.Form do
|
|||
]
|
||||
]
|
||||
|
||||
@doc """
|
||||
Updates the form at the provided path using the given function.
|
||||
|
||||
Marks all forms along the path as touched by default. To prevent it, provide `mark_as_touched?: false`.
|
||||
|
||||
This can be useful if you have a button that should modify a nested form in some way, for example.
|
||||
"""
|
||||
@spec update_form(t(), list(atom | integer) | String.t(), (t() -> t())) :: t()
|
||||
def update_form(form, path, func, opts \\ []) do
|
||||
opts = Spark.OptionsHelpers.validate!(opts, @update_form_opts)
|
||||
|
@ -1573,6 +1579,9 @@ defmodule AshPhoenix.Form do
|
|||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns true if a given form path exists in the form
|
||||
"""
|
||||
@spec has_form?(t(), list(atom | integer) | String.t()) :: boolean
|
||||
def has_form?(form, path) do
|
||||
not is_nil(get_form(form, path))
|
||||
|
@ -1581,6 +1590,9 @@ defmodule AshPhoenix.Form do
|
|||
false
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets the form at the specified path
|
||||
"""
|
||||
@spec get_form(t(), list(atom | integer) | String.t()) :: t() | nil
|
||||
def get_form(form, path) do
|
||||
path =
|
||||
|
@ -1764,6 +1776,7 @@ defmodule AshPhoenix.Form do
|
|||
end)
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec errors_for(t(), list(atom | integer) | String.t(), type :: :simple | :raw | :plaintext) ::
|
||||
[{atom, {String.t(), Keyword.t()}}] | [String.t()] | map | nil
|
||||
@deprecated "Use errors/2 instead"
|
||||
|
@ -2153,6 +2166,8 @@ defmodule AshPhoenix.Form do
|
|||
```elixir
|
||||
Enum.reduce(removed_form_paths, form, &AshPhoenix.Form.remove_form(&2, &1))
|
||||
```
|
||||
|
||||
#{Spark.OptionsHelpers.docs(@remove_form_opts)}
|
||||
"""
|
||||
def remove_form(form, path, opts \\ []) do
|
||||
opts = Spark.OptionsHelpers.validate!(opts, @remove_form_opts)
|
||||
|
@ -2231,6 +2246,7 @@ defmodule AshPhoenix.Form do
|
|||
end)
|
||||
end
|
||||
|
||||
@doc false
|
||||
def arguments_changed?(form) do
|
||||
changeset = form.source
|
||||
|
||||
|
@ -2292,6 +2308,9 @@ defmodule AshPhoenix.Form do
|
|||
defp apply_or_return(value, nil, _type, _), do: value
|
||||
defp apply_or_return(value, function, type, _), do: function.(value, type)
|
||||
|
||||
@doc """
|
||||
Returns the hidden fields for a form as a keyword list
|
||||
"""
|
||||
def hidden_fields(form) do
|
||||
hidden =
|
||||
if form.type in [:read, :update, :destroy] && form.data do
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
defmodule AshPhoenix.Form.InvalidPath do
|
||||
@moduledoc "Raised when an invalid path is used to find, update or remove a form"
|
||||
defexception [:path]
|
||||
|
||||
def exception(opts) do
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
defmodule AshPhoenix.Form.NoActionConfigured do
|
||||
@moduledoc "Raised when a form action should happen but no action of the appropriate type has been configured"
|
||||
defexception [:action, :path]
|
||||
|
||||
def exception(opts) do
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
defmodule AshPhoenix.Form.NoDataLoaded do
|
||||
@moduledoc "Raised when a data needed to be used but the required data was not loaded"
|
||||
defexception [:path]
|
||||
|
||||
def exception(opts) do
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
defmodule AshPhoenix.Form.NoFormConfigured do
|
||||
@moduledoc "Raised when attempting to refer to a form but no nested form with that name was configured.
|
||||
defexception [:field, :available, :path]
|
||||
|
||||
def exception(opts) do
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
defmodule AshPhoenix.Form.NoResourceConfigured do
|
||||
@moduledoc "Raised when a form needed to be constructed but the resource for that form could not be determined"
|
||||
defexception [:path]
|
||||
|
||||
def exception(opts) do
|
||||
|
|
|
@ -1,4 +1,14 @@
|
|||
defprotocol AshPhoenix.FormData.Error do
|
||||
@moduledoc """
|
||||
A protocol for allowing errors to be rendered into a form.
|
||||
|
||||
To implement, define a `to_form_error/1` and return a single error or list of errors of the following shape:
|
||||
|
||||
`{:field_name, message, replacements}`
|
||||
|
||||
Replacements is a keyword list to allow for translations, by extracting out the constants like numbers from the message.
|
||||
"""
|
||||
|
||||
def to_form_error(exception)
|
||||
end
|
||||
|
||||
|
|
|
@ -74,6 +74,12 @@ defmodule AshPhoenix.LiveView do
|
|||
Additionally, you'll need to define a `handle_info/2` callback for your liveview to receive any
|
||||
notifications, and pass that notification into `handle_live/3`. See `handle_live/3` for more.
|
||||
|
||||
## Important
|
||||
|
||||
The logic for handling events to keep data live is currently very limited. It will simply rerun the query
|
||||
every time. To this end, you should feel free to intercept individual events and handle them yourself for
|
||||
more optimized liveness.
|
||||
|
||||
## Pagination
|
||||
|
||||
To make paginated views convenient, as well as making it possible to keep those views live, Ash does not
|
||||
|
@ -89,7 +95,7 @@ defmodule AshPhoenix.LiveView do
|
|||
## Options:
|
||||
#{NimbleOptions.docs(@opts)}
|
||||
|
||||
A great way to get readable millisecond values, you can use the functions in erlang's `:timer` module,
|
||||
A great way to get readable millisecond values is to use the functions in erlang's `:timer` module,
|
||||
like `:timer.hours/1`, `:timer.minutes/1`, and `:timer.seconds/1`
|
||||
|
||||
#### refetch_interval
|
||||
|
|
37
lib/doc_index.ex
Normal file
37
lib/doc_index.ex
Normal file
|
@ -0,0 +1,37 @@
|
|||
defmodule AshPhoenix.DocIndex do
|
||||
@moduledoc """
|
||||
The doc index for ash_phoenix in ash-hq.org
|
||||
"""
|
||||
|
||||
use Spark.DocIndex,
|
||||
guides_from: [
|
||||
"documentation/**/*.md"
|
||||
]
|
||||
|
||||
def for_library, do: "ash_phoenix"
|
||||
|
||||
def extensions do
|
||||
[]
|
||||
end
|
||||
|
||||
def code_modules,
|
||||
do: [
|
||||
{"Phoenix Helpers",
|
||||
[
|
||||
AshPhoenix.Form,
|
||||
AshPhoenix.Form.Auto,
|
||||
AshPhoenix.FilterForm,
|
||||
AshPhoenix.LiveView,
|
||||
AshPhoenix.FormData.Error,
|
||||
AshPhoenix.SubdomainPlug
|
||||
],
|
||||
{"Errors",
|
||||
[
|
||||
AshPhoenix.Form.InvalidPath,
|
||||
AshPhoenix.Form.NoActionConfigured,
|
||||
AshPhoenix.Form.NoDataLoaded,
|
||||
AshPhoenix.Form.NoFormConfigured,
|
||||
AshPhoenix.FOrm.NoResourceConfigured
|
||||
]}}
|
||||
]
|
||||
end
|
5
mix.exs
5
mix.exs
|
@ -5,7 +5,7 @@ defmodule AshPhoenix.MixProject do
|
|||
Utilities for integrating Ash with Phoenix
|
||||
"""
|
||||
|
||||
@version "0.7.7"
|
||||
@version "1.0.0-pre.0"
|
||||
|
||||
def project do
|
||||
[
|
||||
|
@ -72,8 +72,7 @@ defmodule AshPhoenix.MixProject do
|
|||
# Run "mix help deps" to learn about dependencies.
|
||||
defp deps do
|
||||
[
|
||||
# {:ash, ash_version("~> 1.53 and >= 1.53.3")},
|
||||
{:ash, github: "ash-project/ash", branch: "2.0"},
|
||||
{:ash, ash_version("~> 2.0.0-pre.3")},
|
||||
{:phoenix, "~> 1.5.6 or ~> 1.6.0"},
|
||||
{:phoenix_html, "~> 2.14 or ~> 3.0"},
|
||||
{:phoenix_live_view, "~> 0.15"},
|
||||
|
|
Loading…
Reference in a new issue