mirror of
https://github.com/ash-project/ash_admin.git
synced 2024-09-19 12:53:28 +12:00
improvement: Top nav resource grouping (#15)
This commit is contained in:
parent
cae33cafbc
commit
c050c8c228
8 changed files with 64 additions and 11 deletions
|
@ -11,6 +11,8 @@ locals_without_parens = [
|
|||
polymorphic_tables: 1,
|
||||
read_actions: 1,
|
||||
relationship_display_fields: 1,
|
||||
resource_group: 1,
|
||||
resource_group_labels: 1,
|
||||
show?: 1,
|
||||
show_action: 1,
|
||||
table_columns: 1,
|
||||
|
|
|
@ -11,6 +11,12 @@ defmodule AshAdmin.Api do
|
|||
type: :boolean,
|
||||
default: false,
|
||||
doc: "Wether or not this api and its resources should be included in the admin dashboard"
|
||||
],
|
||||
resource_group_labels: [
|
||||
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."
|
||||
]
|
||||
]
|
||||
}
|
||||
|
@ -36,6 +42,10 @@ defmodule AshAdmin.Api do
|
|||
Ash.Dsl.Extension.get_opt(api, [:admin], :show?, false, true)
|
||||
end
|
||||
|
||||
def resource_group_labels(api) do
|
||||
Ash.Dsl.Extension.get_opt(api, [:admin], :resource_group_labels, [], true)
|
||||
end
|
||||
|
||||
defp default_name(api) do
|
||||
split = api |> Module.split()
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ defmodule AshAdmin.Components.TopNav do
|
|||
id={AshAdmin.Api.name(api) <> "_api_nav"}
|
||||
name={AshAdmin.Api.name(api)}
|
||||
groups={dropdown_groups(@prefix, @resource, api)}
|
||||
group_labels={dropdown_group_labels(api)}
|
||||
/>
|
||||
{/for}
|
||||
</div>
|
||||
|
@ -131,6 +132,7 @@ defmodule AshAdmin.Components.TopNav do
|
|||
id={AshAdmin.Api.name(api) <> "_api_nav_drawer"}
|
||||
name={AshAdmin.Api.name(api)}
|
||||
groups={dropdown_groups(@prefix, @resource, api)}
|
||||
group_labels={dropdown_group_labels(api)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -139,16 +141,22 @@ defmodule AshAdmin.Components.TopNav do
|
|||
end
|
||||
|
||||
defp dropdown_groups(prefix, current_resource, api) do
|
||||
[
|
||||
for resource <- Ash.Api.resources(api) do
|
||||
%{
|
||||
text: AshAdmin.Resource.name(resource),
|
||||
to:
|
||||
"#{prefix}?api=#{AshAdmin.Api.name(api)}&resource=#{AshAdmin.Resource.name(resource)}",
|
||||
active: resource == current_resource
|
||||
}
|
||||
end
|
||||
]
|
||||
for resource <- Ash.Api.resources(api) do
|
||||
%{
|
||||
text: AshAdmin.Resource.name(resource),
|
||||
to:
|
||||
"#{prefix}?api=#{AshAdmin.Api.name(api)}&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(api) do
|
||||
AshAdmin.Api.resource_group_labels(api)
|
||||
end
|
||||
|
||||
def handle_event("collapse_nav", _, socket) do
|
||||
|
|
|
@ -6,6 +6,7 @@ defmodule AshAdmin.Components.TopNav.DrawerDropdown do
|
|||
|
||||
prop(name, :string, required: true)
|
||||
prop(groups, :list, required: true)
|
||||
prop(group_labels, :keyword, required: false)
|
||||
|
||||
data(open, :boolean, default: false)
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ defmodule AshAdmin.Components.TopNav.Dropdown do
|
|||
|
||||
prop(name, :string, required: true)
|
||||
prop(groups, :list, required: true)
|
||||
prop(group_labels, :keyword, required: false)
|
||||
prop(active, :boolean, required: true)
|
||||
prop(class, :css_class)
|
||||
|
||||
|
@ -64,6 +65,7 @@ defmodule AshAdmin.Components.TopNav.Dropdown do
|
|||
aria-orientation="vertical"
|
||||
aria-labelledby={"#{@id}_dropown"}
|
||||
>
|
||||
<.group_label item={hd(group)} group_labels={@group_labels} />
|
||||
{#for link <- group}
|
||||
<LiveRedirect
|
||||
to={link.to}
|
||||
|
@ -86,6 +88,26 @@ defmodule AshAdmin.Components.TopNav.Dropdown do
|
|||
"""
|
||||
end
|
||||
|
||||
defp group_label(assigns) do
|
||||
assigns = Map.put(assigns, :label_text, group_label_text(assigns))
|
||||
|
||||
~F"""
|
||||
{#if @label_text}
|
||||
<span class="block px-4 py-2 text-xs text-gray-400 font-semibold italic">{@label_text}</span>
|
||||
{/if}
|
||||
"""
|
||||
end
|
||||
|
||||
# No labels specified for the whole dropdown
|
||||
defp group_label_text(assigns) when not is_map_key(assigns, :group_labels), do: nil
|
||||
defp group_label_text(%{group_labels: []}), do: nil
|
||||
|
||||
# No label specified for this dropdown group
|
||||
defp group_label_text(%{item: item}) when not is_map_key(item, :group), do: nil
|
||||
|
||||
# Maybe a label to display!
|
||||
defp group_label_text(assigns), do: Keyword.get(assigns.group_labels, assigns.item.group)
|
||||
|
||||
def handle_event("close", _, socket) do
|
||||
{:noreply, assign(socket, :open, false)}
|
||||
end
|
||||
|
|
|
@ -17,6 +17,8 @@ defmodule AshAdmin.Helpers do
|
|||
Plug.Conn.Query.encode(Map.merge(socket_params || %{}, Enum.into(new_params, %{})))
|
||||
end
|
||||
|
||||
def to_name(:id), do: "ID"
|
||||
|
||||
def to_name(name) do
|
||||
name
|
||||
|> to_string()
|
||||
|
|
|
@ -73,6 +73,10 @@ defmodule AshAdmin.Resource do
|
|||
relationship_display_fields: [
|
||||
type: {:list, :atom},
|
||||
doc: "The list of attributes to render when it's shown as a relationship on a datatable"
|
||||
],
|
||||
resource_group: [
|
||||
type: :atom,
|
||||
doc: "A group for the resource to appear in, in the top resource dropdown."
|
||||
]
|
||||
]
|
||||
}
|
||||
|
@ -126,6 +130,10 @@ defmodule AshAdmin.Resource do
|
|||
|> List.last()
|
||||
end
|
||||
|
||||
def resource_group(resource) do
|
||||
Ash.Dsl.Extension.get_opt(resource, [:admin], :resource_group, nil, true)
|
||||
end
|
||||
|
||||
def actor?(resource) do
|
||||
Ash.Dsl.Extension.get_opt(resource, [:admin], :actor?, false, true)
|
||||
end
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue