Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Sort resource_group_labels by given order #225

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion documentation/dsls/DSL-AshAdmin.Domain.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Configure the admin dashboard for a given domain.
| [`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. |
| [`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 and will be shown sorted as given. If a key for a group does not appear in this mapping, the label will not be rendered. |



Expand Down
36 changes: 12 additions & 24 deletions lib/ash_admin/components/top_nav.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ defmodule AshAdmin.Components.TopNav do
@moduledoc false
use Phoenix.LiveComponent
import AshAdmin.Helpers
alias AshAdmin.Components.TopNav.{ActorSelect, DrawerDropdown, Dropdown, TenantForm}

alias AshAdmin.Components.TopNav.{
ActorSelect,
DrawerDropdown,
Dropdown,
DropdownHelper,
TenantForm
}

attr :domain, :any, required: true
attr :resource, :any, required: true
Expand Down Expand Up @@ -44,8 +51,8 @@ defmodule AshAdmin.Components.TopNav do
class="mr-1"
id={AshAdmin.Domain.name(domain) <> "_domain_nav"}
name={AshAdmin.Domain.name(domain)}
groups={dropdown_groups(@prefix, @resource, domain)}
group_labels={dropdown_group_labels(domain)}
groups={DropdownHelper.dropdown_groups(@prefix, @resource, domain)}
group_labels={DropdownHelper.dropdown_group_labels(domain)}
/>
</div>
<div class="ml-10 flex items-center">
Expand Down Expand Up @@ -132,34 +139,15 @@ defmodule AshAdmin.Components.TopNav do
module={DrawerDropdown}
id={AshAdmin.Domain.name(domain) <> "_domain_nav_drawer"}
name={AshAdmin.Domain.name(domain)}
groups={dropdown_groups(@prefix, @resource, domain)}
group_labels={dropdown_group_labels(domain)}
groups={DropdownHelper.dropdown_groups(@prefix, @resource, domain)}
group_labels={DropdownHelper.dropdown_group_labels(domain)}
/>
</div>
</div>
</nav>
"""
end

defp dropdown_groups(prefix, current_resource, domain) do
for resource <- AshAdmin.Domain.show_resources(domain) do
%{
text: AshAdmin.Resource.name(resource),
to:
"#{prefix}?domain=#{AshAdmin.Domain.name(domain)}&resource=#{AshAdmin.Resource.name(resource)}",
active: resource == current_resource,
group: AshAdmin.Resource.resource_group(resource)
}
end
|> Enum.group_by(fn resource -> resource.group end)
|> Enum.sort_by(fn {label, _items} -> label || "_____always_put_me_last" end)
|> Keyword.values()
end

defp dropdown_group_labels(domain) do
AshAdmin.Domain.resource_group_labels(domain)
end

def mount(socket) do
{:ok, assign(socket, nav_collapsed: false, open: false)}
end
Expand Down
26 changes: 26 additions & 0 deletions lib/ash_admin/components/top_nav/helpers/dropdown_helper.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
defmodule AshAdmin.Components.TopNav.DropdownHelper do
@moduledoc false

def dropdown_groups(prefix, current_resource, domain) do
for resource <- AshAdmin.Domain.show_resources(domain) do
%{
text: AshAdmin.Resource.name(resource),
to:
"#{prefix}?domain=#{AshAdmin.Domain.name(domain)}&resource=#{AshAdmin.Resource.name(resource)}",
active: resource == current_resource,
group: AshAdmin.Resource.resource_group(resource)
}
end
|> Enum.group_by(fn resource -> resource.group end)
|> Enum.with_index()
|> Enum.sort_by(fn
{{nil, _links}, _index} -> {1, nil}
{{_group, _links}, index} -> {0, index}
end)
|> Enum.map(fn {{_group, links}, _index} -> links end)
end

def dropdown_group_labels(domain) do
AshAdmin.Domain.resource_group_labels(domain)
end
end
2 changes: 1 addition & 1 deletion lib/ash_admin/domain.ex
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ defmodule AshAdmin.Domain do
type: :keyword_list,
default: [],
doc:
"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."
"Humanized names for each resource group to appear in the admin area. These will be used as labels in the top navigation dropdown and will be shown sorted as given. If a key for a group does not appear in this mapping, the label will not be rendered."
]
]
}
Expand Down
64 changes: 64 additions & 0 deletions test/components/top_nav/helpers/dropdown_helper_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
defmodule AshAdmin.Test.Components.TopNav.Helpers.DropdownHelperTest do
use ExUnit.Case, async: true

alias AshAdmin.Components.TopNav.DropdownHelper

describe "dropdown_groups/3" do
test "groups resources" do
prefix = "/admin"
current_resource = AshAdmin.Test.Post
domain = AshAdmin.Test.Domain

blog_link = %{
active: false,
group: :group_b,
text: "Blog",
to: "/admin?domain=Test&resource=Blog"
}

post_link = %{
active: true,
group: :group_a,
text: "Post",
to: "/admin?domain=Test&resource=Post"
}

comment_link = %{
active: false,
group: nil,
text: "Comment",
to: "/admin?domain=Test&resource=Comment"
}

assert_unordered(
[[blog_link], [comment_link], [post_link]],
DropdownHelper.dropdown_groups(prefix, current_resource, domain)
)
end

test "groups resources by given order from the domain" do
prefix = "/admin"
current_resource = AshAdmin.Test.Post
domain = AshAdmin.Test.Domain

assert [
[%{group: :group_b, text: "Blog"} = _blog_link],
[%{group: :group_a, text: "Post"} = _post_link],
[%{group: nil, text: "Comment"} = _comment_link]
] = DropdownHelper.dropdown_groups(prefix, current_resource, domain)
end
end

describe "dropdown_group_labels/3" do
test "returns groups" do
domain = AshAdmin.Test.Domain

assert [group_b: "Group B", group_a: "Group A", group_c: "Group C"] =
DropdownHelper.dropdown_group_labels(domain)
end
end

defp assert_unordered(enum, other_enum) do
assert MapSet.new(enum) == MapSet.new(other_enum)
end
end
2 changes: 2 additions & 0 deletions test/support/domain.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ defmodule AshAdmin.Test.Domain do

admin do
show? true
resource_group_labels group_b: "Group B", group_a: "Group A", group_c: "Group C"
end

resources do
resource(AshAdmin.Test.Blog)
resource(AshAdmin.Test.Post)
resource(AshAdmin.Test.Comment)
end
Expand Down
20 changes: 20 additions & 0 deletions test/support/resources/blog.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
defmodule AshAdmin.Test.Blog do
@moduledoc false
use Ash.Resource,
domain: AshAdmin.Test.Domain,
data_layer: Ash.DataLayer.Ets,
extensions: [AshAdmin.Resource]

attributes do
uuid_primary_key(:id)

attribute :body, :string do
allow_nil?(false)
public?(true)
end
end

admin do
resource_group(:group_b)
end
end
7 changes: 6 additions & 1 deletion test/support/resources/post.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ defmodule AshAdmin.Test.Post do
@moduledoc false
use Ash.Resource,
domain: AshAdmin.Test.Domain,
data_layer: Ash.DataLayer.Ets
data_layer: Ash.DataLayer.Ets,
extensions: [AshAdmin.Resource]

attributes do
uuid_primary_key(:id)
Expand All @@ -12,4 +13,8 @@ defmodule AshAdmin.Test.Post do
public?(true)
end
end

admin do
resource_group(:group_a)
end
end
Loading