diff --git a/dev.exs b/dev.exs
index 2cb884a..3c1519b 100644
--- a/dev.exs
+++ b/dev.exs
@@ -18,6 +18,7 @@ Application.put_env(:ash_admin, DemoWeb.Endpoint,
]
],
live_reload: [
+ iframe_attrs: [class: "hidden"],
patterns: [
~r"priv/static/.*(js|css|png|jpeg|jpg|gif|svg)$",
~r"lib/ash_admin/(components|templates/pages)/.*(ex)$"
diff --git a/dev/resources/accounts/resources/user.ex b/dev/resources/accounts/resources/user.ex
index d465438..2fae203 100644
--- a/dev/resources/accounts/resources/user.ex
+++ b/dev/resources/accounts/resources/user.ex
@@ -15,6 +15,7 @@ defmodule Demo.Accounts.User do
field :first_name, type: :short_text
field :last_name, type: :short_text
end
+ table_columns [:id, :first_name, :last_name, :representative, :admin]
end
policies do
diff --git a/dev/resources/tickets/api.ex b/dev/resources/tickets/api.ex
index 206168c..e5743e2 100644
--- a/dev/resources/tickets/api.ex
+++ b/dev/resources/tickets/api.ex
@@ -2,12 +2,13 @@ defmodule Demo.Tickets.Api do
@moduledoc false
use Ash.Api
- alias Demo.Tickets.{Comment, Customer, Representative, Ticket}
+ alias Demo.Tickets.{Comment, Customer, Representative, Ticket, TicketLink}
resources do
resource(Customer)
resource(Representative)
resource(Ticket)
resource(Comment)
+ resource(TicketLink)
end
end
diff --git a/dev/resources/tickets/resources/representative.ex b/dev/resources/tickets/resources/representative.ex
index 8813185..26f6a0e 100644
--- a/dev/resources/tickets/resources/representative.ex
+++ b/dev/resources/tickets/resources/representative.ex
@@ -45,7 +45,7 @@ defmodule Demo.Tickets.Representative do
update :update do
primary? true
- accept [:first_name, :last_name, :assigned_tickets]
+ accept [:first_name, :last_name]
end
end
diff --git a/dev/resources/tickets/resources/ticket.ex b/dev/resources/tickets/resources/ticket.ex
index 4e4a485..147d2fa 100644
--- a/dev/resources/tickets/resources/ticket.ex
+++ b/dev/resources/tickets/resources/ticket.ex
@@ -61,13 +61,47 @@ defmodule Demo.Tickets.Ticket do
end
create :open do
- accept [:subject, :reporter]
+ accept [:subject]
+ primary? true
+ argument :representative, :map, allow_nil?: false
+ argument :tickets, {:array, :map}, allow_nil?: false
+
+ change manage_relationship(:representative, type: :append)
+ change manage_relationship(:tickets, :source_links, on_lookup: {:relate_and_update, :create, :read, :all})
end
update :update, primary?: true
update :assign do
- accept [:representative]
+ accept []
+ argument :representative, :map
+ argument :reassignment_comment, :map, allow_nil?: false
+
+ change manage_relationship(:representative, type: :append)
+ change manage_relationship(:reassignment_comment, :comments, type: :create)
+ end
+
+ update :link do
+ accept []
+ argument :tickets, {:array, :map}, allow_nil?: false
+ argument :link_comment, :map, type: :create
+
+ # Uses the defult create action of the join table, which accepts the `type`
+ change manage_relationship(:tickets, :source_links, on_lookup: {:relate_and_update, :create, :read, :all})
+ change manage_relationship(:link_comment, :comments, type: :create)
+ end
+
+ update :nested_example do
+ accept [:subject]
+ argument :tickets, {:array, :map}
+
+ change manage_relationship(
+ :tickets,
+ :source_links,
+ type: :direct_control,
+ on_match: {:update, :nested_example, :update, [:type]},
+ on_no_match: {:create, :nested_example, :update, [:type]}
+ )
end
destroy :destroy
@@ -108,5 +142,17 @@ defmodule Demo.Tickets.Ticket do
context %{data_layer: %{table: "ticket_comments"}}
destination_field :resource_id
end
+
+ many_to_many :source_links, Demo.Tickets.Ticket do
+ through Demo.Tickets.TicketLink
+ source_field_on_join_table :source_id
+ destination_field_on_join_table :destination_id
+ end
+
+ many_to_many :destination_links, Demo.Tickets.Ticket do
+ through Demo.Tickets.TicketLink
+ source_field_on_join_table :destination_id
+ destination_field_on_join_table :source_id
+ end
end
end
diff --git a/dev/resources/tickets/resources/ticket_link.ex b/dev/resources/tickets/resources/ticket_link.ex
new file mode 100644
index 0000000..ce68617
--- /dev/null
+++ b/dev/resources/tickets/resources/ticket_link.ex
@@ -0,0 +1,27 @@
+defmodule Demo.Tickets.TicketLink do
+ use Ash.Resource,
+ data_layer: AshPostgres.DataLayer
+
+ postgres do
+ table "ticket_links"
+ repo Demo.Repo
+ end
+
+ attributes do
+ attribute :type, :atom, constraints: [
+ one_of: [:causes, :caused_by, :fixes, :fixed_by]
+ ], allow_nil?: false
+ end
+
+ relationships do
+ belongs_to :source, Demo.Tickets.Ticket do
+ primary_key? true
+ required? true
+ end
+
+ belongs_to :destination, Demo.Tickets.Ticket do
+ primary_key? true
+ required? true
+ end
+ end
+end
diff --git a/lib/ash_admin/components/resource/form.ex b/lib/ash_admin/components/resource/form.ex
index fae3351..7c0de8e 100644
--- a/lib/ash_admin/components/resource/form.ex
+++ b/lib/ash_admin/components/resource/form.ex
@@ -10,7 +10,6 @@ defmodule AshAdmin.Components.Resource.Form do
Checkbox,
ErrorTag,
FieldContext,
- HiddenInput,
HiddenInputs,
Inputs,
Label,
@@ -173,7 +172,7 @@ defmodule AshAdmin.Components.Resource.Form do
{{ render_attribute_input(assigns, attribute, form) }}
-
+
@@ -194,7 +193,7 @@ defmodule AshAdmin.Components.Resource.Form do
{{ render_attribute_input(assigns, attribute, form) }}
-
+
@@ -215,15 +214,14 @@ defmodule AshAdmin.Components.Resource.Form do
{{ render_attribute_input(assigns, attribute, form) }}
-
+
- {{ render_relationship_input(assigns, Ash.Resource.Info.relationship(form.source.resource, relationship), form, argument.name, relationship_path <> "[#{relationship}]", opts) }}
-
+ {{ render_relationship_input(assigns, Ash.Resource.Info.relationship(form.source.resource, relationship), form, argument, relationship_path <> "[#{relationship}]", opts) }}
@@ -232,70 +230,9 @@ defmodule AshAdmin.Components.Resource.Form do
defp render_relationship_input(
assigns,
- %{cardinality: :one} = relationship,
+ relationship,
form,
- as,
- relationship_path,
- opts
- ) do
- ~H"""
-
-
"[#{as}]" }}
- >
-
-
-
- {{ render_attributes(
- assigns,
- relationship.destination,
- new_form.source.action,
- new_form,
- fields,
- [],
- relationship_path
- ) }}
-
-
-
-
-
- """
- end
-
- defp render_relationship_input(
- assigns,
- %{cardinality: :many} = relationship,
- form,
- as,
+ %{type: {:array, _}} = argument,
relationship_path,
opts
) do
@@ -303,59 +240,60 @@ defmodule AshAdmin.Components.Resource.Form do
"[#{as}]" }}
+ opts={{ form_opts(form, opts, argument.name, relationship, @actor) }}
>
-
-
- {{ render_attributes(
- assigns,
- relationship.destination,
- new_form.source.action,
- new_form,
- fields,
- [],
- relationship_path
- ) }}
+
+
+ {{ render_attributes(
+ assigns,
+ relationship.destination,
+ inner_form.source.action || :_lookup,
+ maybe_clear_errors(inner_form), # We clear errors from lookup forms
+ relationship_fields(inner_form, field_limit),
+ skip_related(relationship, is_nil(inner_form.source.action)),
+ relationship_path
+ ) }}
+
+
+
-
-
-
+
+
+
-
+
{{ user_display(@actor) }}
-
+