mirror of
https://github.com/ash-project/ash_admin.git
synced 2024-09-19 12:53:28 +12:00
parent
514ff491da
commit
bd4b5581c8
12 changed files with 158 additions and 7 deletions
|
@ -15,6 +15,7 @@ spark_locals_without_parens = [
|
||||||
resource_group_labels: 1,
|
resource_group_labels: 1,
|
||||||
show?: 1,
|
show?: 1,
|
||||||
show_action: 1,
|
show_action: 1,
|
||||||
|
show_resources: 1,
|
||||||
show_sensitive_fields: 1,
|
show_sensitive_fields: 1,
|
||||||
table_columns: 1,
|
table_columns: 1,
|
||||||
type: 1,
|
type: 1,
|
||||||
|
|
|
@ -5,6 +5,13 @@ defmodule Demo.Tickets.Domain do
|
||||||
|
|
||||||
admin do
|
admin do
|
||||||
show? true
|
show? true
|
||||||
|
show_resources [
|
||||||
|
Demo.Tickets.Customer,
|
||||||
|
Demo.Tickets.Representative,
|
||||||
|
Demo.Tickets.Ticket,
|
||||||
|
Demo.Tickets.Comment,
|
||||||
|
Demo.Tickets.Organization
|
||||||
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
resources do
|
resources do
|
||||||
|
|
|
@ -20,6 +20,7 @@ Configure the admin dashboard for a given domain.
|
||||||
|------|------|---------|------|
|
|------|------|---------|------|
|
||||||
| [`name`](#admin-name){: #admin-name } | `String.t` | | The name of the domain in the dashboard. Will be derived if not set. |
|
| [`name`](#admin-name){: #admin-name } | `String.t` | | The name of the domain in the dashboard. Will be derived if not set. |
|
||||||
| [`show?`](#admin-show?){: #admin-show? } | `boolean` | `false` | Whether or not this domain and its resources should be included in the admin dashboard. |
|
| [`show?`](#admin-show?){: #admin-show? } | `boolean` | `false` | Whether or not this domain and its resources should be included in the admin dashboard. |
|
||||||
|
| [`show_resources`](#admin-show_resources){: #admin-show_resources } | `atom \| list(atom)` | `:*` | List of resources that should be included in the admin dashboard |
|
||||||
| [`default_resource_page`](#admin-default_resource_page){: #admin-default_resource_page } | `:schema \| :primary_read` | `:schema` | Set the default page for the resource to be the primary read action or the resource schema. Schema is the default for backwards compatibility, if a resource doesn't have a primary read action it will fallback to the schema view. |
|
| [`default_resource_page`](#admin-default_resource_page){: #admin-default_resource_page } | `:schema \| :primary_read` | `:schema` | Set the default page for the resource to be the primary read action or the resource schema. Schema is the default for backwards compatibility, if a resource doesn't have a primary read action it will fallback to the schema view. |
|
||||||
| [`resource_group_labels`](#admin-resource_group_labels){: #admin-resource_group_labels } | `keyword` | `[]` | Humanized names for each resource group to appear in the admin area. These will be used as labels in the top navigation dropdown. If a key for a group does not appear in this mapping, the label will not be rendered. |
|
| [`resource_group_labels`](#admin-resource_group_labels){: #admin-resource_group_labels } | `keyword` | `[]` | Humanized names for each resource group to appear in the admin area. These will be used as labels in the top navigation dropdown. If a key for a group does not appear in this mapping, the label will not be rendered. |
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ defmodule AshAdmin.ActorPlug.Plug do
|
||||||
|
|
||||||
defp actor_resources(domains) do
|
defp actor_resources(domains) do
|
||||||
for domain <- domains,
|
for domain <- domains,
|
||||||
resource <- Ash.Domain.Info.resources(domain),
|
resource <- AshAdmin.Domain.show_resources(domain),
|
||||||
AshAdmin.Helpers.primary_action(resource, :read) && AshAdmin.Resource.actor?(resource),
|
AshAdmin.Helpers.primary_action(resource, :read) && AshAdmin.Resource.actor?(resource),
|
||||||
do: {domain, resource}
|
do: {domain, resource}
|
||||||
end
|
end
|
||||||
|
@ -120,7 +120,7 @@ defmodule AshAdmin.ActorPlug.Plug do
|
||||||
resource =
|
resource =
|
||||||
if domain do
|
if domain do
|
||||||
domain
|
domain
|
||||||
|> Ash.Domain.Info.resources()
|
|> AshAdmin.Domain.show_resources()
|
||||||
|> Enum.find(&(AshAdmin.Resource.name(&1) == resource))
|
|> Enum.find(&(AshAdmin.Resource.name(&1) == resource))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,7 @@ defmodule AshAdmin.Components.TopNav do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp dropdown_groups(prefix, current_resource, domain) do
|
defp dropdown_groups(prefix, current_resource, domain) do
|
||||||
for resource <- Ash.Domain.Info.resources(domain) do
|
for resource <- AshAdmin.Domain.show_resources(domain) do
|
||||||
%{
|
%{
|
||||||
text: AshAdmin.Resource.name(resource),
|
text: AshAdmin.Resource.name(resource),
|
||||||
to:
|
to:
|
||||||
|
@ -180,7 +180,7 @@ defmodule AshAdmin.Components.TopNav do
|
||||||
defp show_tenant_form?(domains) do
|
defp show_tenant_form?(domains) do
|
||||||
Enum.any?(domains, fn domain ->
|
Enum.any?(domains, fn domain ->
|
||||||
domain
|
domain
|
||||||
|> Ash.Domain.Info.resources()
|
|> AshAdmin.Domain.show_resources()
|
||||||
|> Enum.any?(fn resource ->
|
|> Enum.any?(fn resource ->
|
||||||
Ash.Resource.Info.multitenancy_strategy(resource)
|
Ash.Resource.Info.multitenancy_strategy(resource)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -13,6 +13,11 @@ defmodule AshAdmin.Domain do
|
||||||
doc:
|
doc:
|
||||||
"Whether or not this domain and its resources should be included in the admin dashboard."
|
"Whether or not this domain and its resources should be included in the admin dashboard."
|
||||||
],
|
],
|
||||||
|
show_resources: [
|
||||||
|
type: {:wrap_list, :atom},
|
||||||
|
default: :*,
|
||||||
|
doc: "List of resources that should be included in the admin dashboard"
|
||||||
|
],
|
||||||
default_resource_page: [
|
default_resource_page: [
|
||||||
type: {:in, [:schema, :primary_read]},
|
type: {:in, [:schema, :primary_read]},
|
||||||
default: :schema,
|
default: :schema,
|
||||||
|
@ -28,7 +33,9 @@ defmodule AshAdmin.Domain do
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
use Spark.Dsl.Extension, sections: [@admin]
|
use Spark.Dsl.Extension,
|
||||||
|
sections: [@admin],
|
||||||
|
transformers: [AshAdmin.ShowResourcesTransformer]
|
||||||
|
|
||||||
@moduledoc """
|
@moduledoc """
|
||||||
A domain extension to alter the behavior of a domain in the admin UI.
|
A domain extension to alter the behavior of a domain in the admin UI.
|
||||||
|
@ -42,6 +49,10 @@ defmodule AshAdmin.Domain do
|
||||||
Spark.Dsl.Extension.get_opt(domain, [:admin], :show?, false, true)
|
Spark.Dsl.Extension.get_opt(domain, [:admin], :show?, false, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show_resources(domain) do
|
||||||
|
Spark.Dsl.Extension.get_opt(domain, [:admin], :show_resources, [], true)
|
||||||
|
end
|
||||||
|
|
||||||
def default_resource_page(domain) do
|
def default_resource_page(domain) do
|
||||||
Spark.Dsl.Extension.get_opt(domain, [:admin], :default_resource_page, :schema, true)
|
Spark.Dsl.Extension.get_opt(domain, [:admin], :default_resource_page, :schema, true)
|
||||||
end
|
end
|
||||||
|
|
|
@ -124,7 +124,7 @@ defmodule AshAdmin.PageLive do
|
||||||
|
|
||||||
defp assign_resource(socket, resource) do
|
defp assign_resource(socket, resource) do
|
||||||
if socket.assigns.domain do
|
if socket.assigns.domain do
|
||||||
resources = Ash.Domain.Info.resources(socket.assigns.domain)
|
resources = AshAdmin.Domain.show_resources(socket.assigns.domain)
|
||||||
|
|
||||||
resource =
|
resource =
|
||||||
Enum.find(resources, fn domain_resources ->
|
Enum.find(resources, fn domain_resources ->
|
||||||
|
|
|
@ -194,7 +194,7 @@ defmodule AshAdmin.Resource do
|
||||||
|
|
||||||
defp find_polymorphic_tables(resource, domains) do
|
defp find_polymorphic_tables(resource, domains) do
|
||||||
domains
|
domains
|
||||||
|> Enum.flat_map(&Ash.Domain.Info.resources/1)
|
|> Enum.flat_map(&AshAdmin.Domain.show_resources/1)
|
||||||
|> Enum.flat_map(&Ash.Resource.Info.relationships/1)
|
|> Enum.flat_map(&Ash.Resource.Info.relationships/1)
|
||||||
|> Enum.filter(&(&1.destination == resource))
|
|> Enum.filter(&(&1.destination == resource))
|
||||||
|> Enum.map(& &1.context[:data_layer][:table])
|
|> Enum.map(& &1.context[:data_layer][:table])
|
||||||
|
|
28
lib/ash_admin/show_resources_transformer.ex
Normal file
28
lib/ash_admin/show_resources_transformer.ex
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
defmodule AshAdmin.ShowResourcesTransformer do
|
||||||
|
use Spark.Dsl.Transformer
|
||||||
|
|
||||||
|
def transform(dsl) do
|
||||||
|
module = Spark.Dsl.Transformer.get_persisted(dsl, :module)
|
||||||
|
all_resources = Ash.Domain.Info.resources(dsl)
|
||||||
|
|
||||||
|
resources =
|
||||||
|
case AshAdmin.Domain.show_resources(dsl) do
|
||||||
|
[:*] ->
|
||||||
|
all_resources
|
||||||
|
|
||||||
|
resources ->
|
||||||
|
case Enum.find(resources, &(&1 not in all_resources)) do
|
||||||
|
nil ->
|
||||||
|
resources
|
||||||
|
|
||||||
|
bad_resource ->
|
||||||
|
raise Spark.Error.DslError,
|
||||||
|
module: module,
|
||||||
|
path: [:admin, :show_resources],
|
||||||
|
message: "#{inspect(bad_resource)} is not a valid resource in #{inspect(module)}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
{:ok, Spark.Dsl.Transformer.set_option(dsl, [:admin], :show_resources, resources)}
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,91 @@
|
||||||
defmodule AshAdmin.Test.AshAdminTest do
|
defmodule AshAdmin.Test.AshAdminTest do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
use ExUnit.Case, async: true
|
use ExUnit.Case, async: true
|
||||||
|
|
||||||
|
test "all resources are shown by default", _ do
|
||||||
|
defmodule Domain do
|
||||||
|
@moduledoc false
|
||||||
|
use Ash.Domain,
|
||||||
|
extensions: [AshAdmin.Domain]
|
||||||
|
|
||||||
|
admin do
|
||||||
|
show? true
|
||||||
|
end
|
||||||
|
|
||||||
|
resources do
|
||||||
|
resource AshAdmin.Test.Post
|
||||||
|
resource AshAdmin.Test.Comment
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert AshAdmin.Domain.show_resources(Domain) === [
|
||||||
|
AshAdmin.Test.Post,
|
||||||
|
AshAdmin.Test.Comment
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "all resources are shown when :* option is selected", _ do
|
||||||
|
defmodule Domain do
|
||||||
|
@moduledoc false
|
||||||
|
use Ash.Domain,
|
||||||
|
extensions: [AshAdmin.Domain]
|
||||||
|
|
||||||
|
admin do
|
||||||
|
show? true
|
||||||
|
show_resources :*
|
||||||
|
end
|
||||||
|
|
||||||
|
resources do
|
||||||
|
resource AshAdmin.Test.Post
|
||||||
|
resource AshAdmin.Test.Comment
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert AshAdmin.Domain.show_resources(Domain) === [
|
||||||
|
AshAdmin.Test.Post,
|
||||||
|
AshAdmin.Test.Comment
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "selected resources are shown", _ do
|
||||||
|
defmodule Domain do
|
||||||
|
@moduledoc false
|
||||||
|
use Ash.Domain,
|
||||||
|
extensions: [AshAdmin.Domain]
|
||||||
|
|
||||||
|
admin do
|
||||||
|
show? true
|
||||||
|
show_resources AshAdmin.Test.Post
|
||||||
|
end
|
||||||
|
|
||||||
|
resources do
|
||||||
|
resource AshAdmin.Test.Post
|
||||||
|
resource AshAdmin.Test.Comment
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert AshAdmin.Domain.show_resources(Domain) === [
|
||||||
|
AshAdmin.Test.Post
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "if shown resrouces option not eixsting resource providede error", _ do
|
||||||
|
assert_raise(Spark.Error.DslError, "[AshAdmin.Test.AshAdminTest.Domain]\n admin -> show_resources:\n SomeRandom is not a valid resource in AshAdmin.Test.AshAdminTest.Domain", fn ->
|
||||||
|
defmodule Domain do
|
||||||
|
@moduledoc false
|
||||||
|
use Ash.Domain,
|
||||||
|
extensions: [AshAdmin.Domain]
|
||||||
|
|
||||||
|
admin do
|
||||||
|
show? true
|
||||||
|
show_resources [AshAdmin.Test.Post, SomeRandom]
|
||||||
|
end
|
||||||
|
|
||||||
|
resources do
|
||||||
|
resource AshAdmin.Test.Post
|
||||||
|
resource AshAdmin.Test.Comment
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,5 +9,6 @@ defmodule AshAdmin.Test.Domain do
|
||||||
|
|
||||||
resources do
|
resources do
|
||||||
resource(AshAdmin.Test.Post)
|
resource(AshAdmin.Test.Post)
|
||||||
|
resource(AshAdmin.Test.Comment)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
15
test/support/resources/comment.ex
Normal file
15
test/support/resources/comment.ex
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
defmodule AshAdmin.Test.Comment do
|
||||||
|
@moduledoc false
|
||||||
|
use Ash.Resource,
|
||||||
|
domain: AshAdmin.Test.Domain,
|
||||||
|
data_layer: Ash.DataLayer.Ets
|
||||||
|
|
||||||
|
attributes do
|
||||||
|
uuid_primary_key(:id)
|
||||||
|
|
||||||
|
attribute :body, :string do
|
||||||
|
allow_nil?(false)
|
||||||
|
public?(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue