fix: use static routes

This commit is contained in:
Zach Daniel 2021-03-22 17:44:34 -04:00
parent 7dec87b43e
commit aa464fea36
15 changed files with 240 additions and 347 deletions

View file

@ -23,9 +23,18 @@ defmodule AshAdmin.Api do
""" """
def name(api) do def name(api) do
Ash.Dsl.Extension.get_opt(api, [:admin], :name, nil, true) || Ash.Dsl.Extension.get_opt(api, [:admin], :name, nil, true) || default_name(api)
api end
|> Module.split()
|> Enum.at(-2) defp default_name(api) do
split = api |> Module.split()
case List.last(split) do
"Api" ->
Enum.at(split, -2)
last ->
last
end
end end
end end

View file

@ -17,6 +17,7 @@ defmodule AshAdmin.Components.Resource.DataTable do
prop(params, :any) prop(params, :any)
prop(table, :any, required: true) prop(table, :any, required: true)
prop(tables, :any, required: true) prop(tables, :any, required: true)
prop(prefix, :any, required: true)
data(initialized, :boolean, default: false) data(initialized, :boolean, default: false)
data(data, :any) data(data, :any)
@ -202,6 +203,7 @@ defmodule AshAdmin.Components.Resource.DataTable do
api={{ @api }} api={{ @api }}
set_actor={{ @set_actor }} set_actor={{ @set_actor }}
attributes={{ AshAdmin.Resource.table_columns(@resource) }} attributes={{ AshAdmin.Resource.table_columns(@resource) }}
prefix={{ @prefix }}
/> />
{{ render_pagination_links(assigns, :bottom) }} {{ render_pagination_links(assigns, :bottom) }}
</div> </div>

View file

@ -32,6 +32,7 @@ defmodule AshAdmin.Components.Resource.Form do
prop(action, :any, required: true) prop(action, :any, required: true)
prop(table, :any, required: true) prop(table, :any, required: true)
prop(tables, :any, required: true) prop(tables, :any, required: true)
prop(prefix, :any, required: true)
def update(assigns, socket) do def update(assigns, socket) do
{:ok, {:ok,
@ -70,8 +71,13 @@ defmodule AshAdmin.Components.Resource.Form do
<div class="shadow-lg overflow-hidden sm:rounded-md bg-white"> <div class="shadow-lg overflow-hidden sm:rounded-md bg-white">
<div :if={{ @changeset.action_failed? }} class="ml-4 mt-4 text-red-500"> <div :if={{ @changeset.action_failed? }} class="ml-4 mt-4 text-red-500">
<ul> <ul>
<li :for={{ {field, message} <- AshPhoenix.errors_for(@changeset, as: :simple) }}> <li :for={{ {field, message} <- errors_for(@changeset) }}>
{{ to_name(field) }}: {{ message }} <span :if={{field}}>
{{ to_name(field) }}:
</span>
<span>
{{message}}
</span>
</li> </li>
</ul> </ul>
</div> </div>
@ -123,6 +129,18 @@ defmodule AshAdmin.Components.Resource.Form do
""" """
end end
defp errors_for(changeset) do
changeset
|> AshPhoenix.transform_errors(fn
_, %{class: :forbidden} ->
{nil, "Forbidden", []}
_, other ->
other
end)
|> AshPhoenix.errors_for(as: :simple)
end
defp save_button_text(:update), do: "Save" defp save_button_text(:update), do: "Save"
defp save_button_text(type), do: type |> to_string() |> String.capitalize() defp save_button_text(type), do: type |> to_string() |> String.capitalize()
@ -560,19 +578,16 @@ defmodule AshAdmin.Components.Resource.Form do
defp text_input_type(_), do: "text" defp text_input_type(_), do: "text"
defp redirect_to(socket, record) do defp redirect_to(socket, record) do
show_action = AshAdmin.Resource.show_action(socket.assigns.resource) if AshAdmin.Resource.show_action(socket.assigns.resource) do
if show_action do
{:noreply, {:noreply,
socket socket
|> redirect( |> redirect(
to: to:
ash_show_path( ash_show_path(
socket, socket.assigns.prefix,
socket.assigns.api, socket.assigns.api,
socket.assigns.resource, socket.assigns.resource,
record, record,
show_action,
socket.assigns.table socket.assigns.table
) )
)} )}
@ -580,7 +595,10 @@ defmodule AshAdmin.Components.Resource.Form do
case Ash.Resource.Info.primary_action(socket.assigns.resource, :update) do case Ash.Resource.Info.primary_action(socket.assigns.resource, :update) do
nil -> nil ->
{:noreply, {:noreply,
redirect(socket, to: ash_admin_path(socket.assigns.api, socket.assigns.resource))} redirect(socket,
to:
ash_admin_path(socket.assigns.prefix, socket.assigns.api, socket.assigns.resource)
)}
update -> update ->
{:noreply, {:noreply,
@ -588,7 +606,7 @@ defmodule AshAdmin.Components.Resource.Form do
|> redirect( |> redirect(
to: to:
ash_update_path( ash_update_path(
socket, socket.assigns.prefix,
socket.assigns.api, socket.assigns.api,
socket.assigns.resource, socket.assigns.resource,
record, record,
@ -607,7 +625,7 @@ defmodule AshAdmin.Components.Resource.Form do
push_redirect(socket, push_redirect(socket,
to: to:
ash_create_path( ash_create_path(
socket, socket.assigns.prefix,
socket.assigns.api, socket.assigns.api,
socket.assigns.resource, socket.assigns.resource,
socket.assigns.action.name, socket.assigns.action.name,
@ -620,7 +638,7 @@ defmodule AshAdmin.Components.Resource.Form do
push_redirect(socket, push_redirect(socket,
to: to:
ash_update_path( ash_update_path(
socket, socket.assigns.prefix,
socket.assigns.api, socket.assigns.api,
socket.assigns.resource, socket.assigns.resource,
socket.assigns.record, socket.assigns.record,
@ -634,7 +652,7 @@ defmodule AshAdmin.Components.Resource.Form do
push_redirect(socket, push_redirect(socket,
to: to:
ash_destroy_path( ash_destroy_path(
socket, socket.assigns.prefix,
socket.assigns.api, socket.assigns.api,
socket.assigns.resource, socket.assigns.resource,
socket.assigns.record, socket.assigns.record,
@ -664,7 +682,7 @@ defmodule AshAdmin.Components.Resource.Form do
push_redirect(socket, push_redirect(socket,
to: to:
ash_create_path( ash_create_path(
socket, socket.assigns.prefix,
socket.assigns.api, socket.assigns.api,
socket.assigns.resource, socket.assigns.resource,
action.name, action.name,
@ -677,7 +695,21 @@ defmodule AshAdmin.Components.Resource.Form do
push_redirect(socket, push_redirect(socket,
to: to:
ash_update_path( ash_update_path(
socket, socket.assigns.prefix,
socket.assigns.api,
socket.assigns.resource,
socket.assigns.record,
action.name,
socket.assigns.table
)
)}
:destroy ->
{:noreply,
push_redirect(socket,
to:
ash_destroy_path(
socket.assigns.prefix,
socket.assigns.api, socket.assigns.api,
socket.assigns.resource, socket.assigns.resource,
socket.assigns.record, socket.assigns.record,
@ -775,7 +807,7 @@ defmodule AshAdmin.Components.Resource.Form do
{:ok, created} -> {:ok, created} ->
redirect_to(socket, created) redirect_to(socket, created)
{:error, %{changeset: changeset}} -> {:error, %{changeset: changeset} = error} ->
{:noreply, assign(socket, :changeset, changeset)} {:noreply, assign(socket, :changeset, changeset)}
end end
@ -813,7 +845,14 @@ defmodule AshAdmin.Components.Resource.Form do
:ok -> :ok ->
{:noreply, {:noreply,
socket socket
|> redirect(to: ash_admin_path(socket, socket.assigns.api, socket.assigns.resource))} |> redirect(
to:
ash_admin_path(
socket.assigns.prefix,
socket.assigns.api,
socket.assigns.resource
)
)}
{:error, %{changeset: changeset}} -> {:error, %{changeset: changeset}} ->
{:noreply, assign(socket, :changeset, changeset)} {:noreply, assign(socket, :changeset, changeset)}

View file

@ -10,6 +10,7 @@ defmodule AshAdmin.Components.Resource.Nav do
prop(tab, :string, required: true) prop(tab, :string, required: true)
prop(action, :any) prop(action, :any)
prop(table, :any, default: nil) prop(table, :any, default: nil)
prop(prefix, :any, default: nil)
def render(assigns) do def render(assigns) do
~H""" ~H"""
@ -19,7 +20,7 @@ defmodule AshAdmin.Components.Resource.Nav do
<div class="flex items-center w-full"> <div class="flex items-center w-full">
<div class="flex-shrink-0"> <div class="flex-shrink-0">
<h3 class="text-white text-lg"> <h3 class="text-white text-lg">
<LiveRedirect to={{ ash_admin_path(@socket, @api, @resource) }}> <LiveRedirect to={{ ash_admin_path(@prefix, @api, @resource) }}>
{{ AshAdmin.Resource.name(@resource) }} {{ AshAdmin.Resource.name(@resource) }}
</LiveRedirect> </LiveRedirect>
</h3> </h3>
@ -29,7 +30,7 @@ defmodule AshAdmin.Components.Resource.Nav do
<div :if={{ has_create_action?(@resource) }} class="relative"> <div :if={{ has_create_action?(@resource) }} class="relative">
<LiveRedirect <LiveRedirect
to={{ash_create_path( to={{ash_create_path(
@socket, @prefix,
@api, @api,
@resource, @resource,
Ash.Resource.Info.primary_action(@resource, :create).name, Ash.Resource.Info.primary_action(@resource, :create).name,
@ -45,7 +46,7 @@ defmodule AshAdmin.Components.Resource.Nav do
name="Read" name="Read"
id={{ "#{@resource}_data_dropdown" }} id={{ "#{@resource}_data_dropdown" }}
active={{ @tab == "data" }} active={{ @tab == "data" }}
groups={{ data_groups(@socket, @api, @resource, @action, @table) }} groups={{ data_groups(@prefix, @api, @resource, @action, @table) }}
/> />
</div> </div>
</div> </div>
@ -56,7 +57,7 @@ defmodule AshAdmin.Components.Resource.Nav do
""" """
end end
defp data_groups(socket, api, resource, current_action, table) do defp data_groups(prefix, api, resource, current_action, table) do
read_actions = AshAdmin.Resource.read_actions(resource) read_actions = AshAdmin.Resource.read_actions(resource)
[ [
@ -67,7 +68,7 @@ defmodule AshAdmin.Components.Resource.Nav do
|> Enum.map(fn action -> |> Enum.map(fn action ->
%{ %{
text: action_name(action), text: action_name(action),
to: ash_action_path(socket, api, resource, :read, action.name, table), to: ash_action_path(prefix, api, resource, :read, action.name, table),
active: current_action == action active: current_action == action
} }
end) end)

View file

@ -6,6 +6,7 @@ defmodule AshAdmin.Components.Resource.RelationshipTable do
prop(resource, :any, required: true) prop(resource, :any, required: true)
prop(api, :any, required: true) prop(api, :any, required: true)
prop(prefix, :any, required: true)
def render(assigns) do def render(assigns) do
~H""" ~H"""
@ -33,7 +34,7 @@ defmodule AshAdmin.Components.Resource.RelationshipTable do
<td class="text-center"> <td class="text-center">
{{ relationship.type }}</td> {{ relationship.type }}</td>
<td class="text-center"> <td class="text-center">
<LiveRedirect to={{ ash_admin_path(@socket, @api, relationship.destination) }}> <LiveRedirect to={{ ash_admin_path(@prefix, @api, relationship.destination) }}>
{{ AshAdmin.Resource.name(relationship.destination) }} {{ AshAdmin.Resource.name(relationship.destination) }}
</LiveRedirect> </LiveRedirect>
</td> </td>

View file

@ -21,6 +21,7 @@ defmodule AshAdmin.Components.Resource do
prop(record, :any, default: nil) prop(record, :any, default: nil)
prop(table, :any, default: nil) prop(table, :any, default: nil)
prop(tables, :any, default: nil) prop(tables, :any, default: nil)
prop(prefix, :any, default: nil)
data(filter_open, :boolean, default: false) data(filter_open, :boolean, default: false)
slot(default) slot(default)
@ -34,6 +35,7 @@ defmodule AshAdmin.Components.Resource do
tab={{ @tab }} tab={{ @tab }}
action={{ @action }} action={{ @action }}
table={{ @table }} table={{ @table }}
prefix={{ @prefix }}
/> />
<div class="mx-24 relative grid grid-cols-1 justify-items-center"> <div class="mx-24 relative grid grid-cols-1 justify-items-center">
</div> </div>
@ -54,6 +56,7 @@ defmodule AshAdmin.Components.Resource do
tenant={{ @tenant }} tenant={{ @tenant }}
table={{ @table }} table={{ @table }}
tables={{ @tables }} tables={{ @tables }}
prefix={{ @prefix }}
/> />
</div> </div>
<div :if={{ @record && match?({:ok, record} when not is_nil(record), @record) && @tab == "destroy" }}> <div :if={{ @record && match?({:ok, record} when not is_nil(record), @record) && @tab == "destroy" }}>
@ -72,6 +75,7 @@ defmodule AshAdmin.Components.Resource do
tenant={{ @tenant }} tenant={{ @tenant }}
table={{ @table }} table={{ @table }}
tables={{ @tables }} tables={{ @tables }}
prefix={{ @prefix }}
/> />
</div> </div>
<Show <Show
@ -85,8 +89,9 @@ defmodule AshAdmin.Components.Resource do
tenant={{ @tenant }} tenant={{ @tenant }}
set_actor={{ @set_actor }} set_actor={{ @set_actor }}
table={{ @table }} table={{ @table }}
prefix={{ @prefix }}
/> />
<Info :if={{ @tab == "info" }} resource={{ @resource }} api={{ @api }} /> <Info :if={{ @tab == "info" }} resource={{ @resource }} api={{ @api }} prefix={{ @prefix }} />
<Form <Form
:if={{ @tab == "create" }} :if={{ @tab == "create" }}
type={{ :create }} type={{ :create }}
@ -100,6 +105,7 @@ defmodule AshAdmin.Components.Resource do
tenant={{ @tenant }} tenant={{ @tenant }}
table={{ @table }} table={{ @table }}
tables={{ @tables }} tables={{ @tables }}
prefix={{ @prefix }}
/> />
<DataTable <DataTable
:if={{ @tab == "data" }} :if={{ @tab == "data" }}
@ -114,6 +120,7 @@ defmodule AshAdmin.Components.Resource do
authorizing={{ @authorizing }} authorizing={{ @authorizing }}
table={{ @table }} table={{ @table }}
tables={{ @tables }} tables={{ @tables }}
prefix={{ @prefix }}
/> />
</div> </div>
""" """

View file

@ -6,12 +6,13 @@ defmodule AshAdmin.Components.Resource.Info do
prop(resource, :any, required: true) prop(resource, :any, required: true)
prop(api, :any, required: true) prop(api, :any, required: true)
prop(prefix, :any, required: true)
def render(assigns) do def render(assigns) do
~H""" ~H"""
<div class="relative mx-12"> <div class="relative mx-12">
<AttributeTable resource={{ @resource }} /> <AttributeTable resource={{ @resource }} />
<RelationshipTable api={{ @api }} resource={{ @resource }} /> <RelationshipTable api={{ @api }} resource={{ @resource }} prefix={{ @prefix }} />
</div> </div>
""" """
end end

View file

@ -15,6 +15,7 @@ defmodule AshAdmin.Components.Resource.Show do
prop(tenant, :any) prop(tenant, :any)
prop(set_actor, :event, required: true) prop(set_actor, :event, required: true)
prop(table, :any, required: true) prop(table, :any, required: true)
prop(prefix, :any, required: true)
data(load_errors, :map, default: %{}) data(load_errors, :map, default: %{})
@ -55,7 +56,7 @@ defmodule AshAdmin.Components.Resource.Show do
<div :if={{ buttons? }} class="px-4 py-3 text-right sm:px-6"> <div :if={{ buttons? }} class="px-4 py-3 text-right sm:px-6">
<LiveRedirect <LiveRedirect
to={{ash_destroy_path( to={{ash_destroy_path(
@socket, @prefix,
@api, @api,
@resource, @resource,
@record, @record,
@ -70,7 +71,7 @@ defmodule AshAdmin.Components.Resource.Show do
<LiveRedirect <LiveRedirect
to={{ash_update_path( to={{ash_update_path(
@socket, @prefix,
@api, @api,
@resource, @resource,
@record, @record,
@ -144,11 +145,10 @@ defmodule AshAdmin.Components.Resource.Show do
<LiveRedirect <LiveRedirect
:if={{ AshAdmin.Resource.show_action(destination) }} :if={{ AshAdmin.Resource.show_action(destination) }}
to={{ash_show_path( to={{ash_show_path(
@socket, @prefix,
@api, @api,
destination, destination,
record, record,
AshAdmin.Resource.show_action(destination),
context[:data_layer][:table] context[:data_layer][:table]
)}} )}}
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
@ -178,6 +178,7 @@ defmodule AshAdmin.Components.Resource.Show do
api={{ @api }} api={{ @api }}
set_actor={{ @set_actor }} set_actor={{ @set_actor }}
table={{ context[:data_layer][:table] }} table={{ context[:data_layer][:table] }}
prefix={{ @prefix }}
/> />
</div> </div>
""" """
@ -187,7 +188,7 @@ defmodule AshAdmin.Components.Resource.Show do
~H""" ~H"""
{{ {attributes, flags, bottom_attributes} = {{ {attributes, flags, bottom_attributes} =
AshAdmin.Components.Resource.Form.attributes(resource, :show) AshAdmin.Components.Resource.Form.attributes(resource, :show)
nil }} nil }}
<div class="grid grid-cols-6 gap-6"> <div class="grid grid-cols-6 gap-6">
<div <div

View file

@ -12,6 +12,7 @@ defmodule AshAdmin.Components.Resource.Table do
prop(api, :any, required: true) prop(api, :any, required: true)
prop(set_actor, :event, required: true) prop(set_actor, :event, required: true)
prop(table, :any, required: true) prop(table, :any, required: true)
prop(prefix, :any, required: true)
def render(assigns) do def render(assigns) do
~H""" ~H"""
@ -28,14 +29,14 @@ defmodule AshAdmin.Components.Resource.Table do
<td :if={{ @actions && actions?(@resource) }}> <td :if={{ @actions && actions?(@resource) }}>
<div class="flex h-max justify-items-center"> <div class="flex h-max justify-items-center">
<div :if={{ AshAdmin.Resource.show_action(@resource) }}> <div :if={{ AshAdmin.Resource.show_action(@resource) }}>
<LiveRedirect to={{ ash_show_path(@socket, @api, @resource, record, AshAdmin.Resource.show_action(@resource), @table) }}> <LiveRedirect to={{ ash_show_path(@prefix, @api, @resource, record, @table) }}>
{{ {:safe, Heroicons.Solid.information_circle(class: "h-5 w-5 text-gray-500")} }} {{ {:safe, Heroicons.Solid.information_circle(class: "h-5 w-5 text-gray-500")} }}
</LiveRedirect> </LiveRedirect>
</div> </div>
<div :if={{ Ash.Resource.Info.primary_action(@resource, :update) }}> <div :if={{ Ash.Resource.Info.primary_action(@resource, :update) }}>
<LiveRedirect to={{ash_update_path( <LiveRedirect to={{ash_update_path(
@socket, @prefix,
@api, @api,
@resource, @resource,
record, record,
@ -48,7 +49,7 @@ defmodule AshAdmin.Components.Resource.Table do
<div :if={{ Ash.Resource.Info.primary_action(@resource, :destroy) }}> <div :if={{ Ash.Resource.Info.primary_action(@resource, :destroy) }}>
<LiveRedirect to={{ash_destroy_path( <LiveRedirect to={{ash_destroy_path(
@socket, @prefix,
@api, @api,
@resource, @resource,
record, record,

View file

@ -21,6 +21,7 @@ defmodule AshAdmin.Components.TopNav do
prop(actor_paused, :boolean, required: true) prop(actor_paused, :boolean, required: true)
prop(actor, :any, required: true) prop(actor, :any, required: true)
prop(actor_api, :any, required: true) prop(actor_api, :any, required: true)
prop(prefix, :any, required: true)
def render(assigns) do def render(assigns) do
~H""" ~H"""
@ -30,7 +31,7 @@ defmodule AshAdmin.Components.TopNav do
<div class="flex items-center w-full"> <div class="flex items-center w-full">
<div class="flex-shrink-0"> <div class="flex-shrink-0">
<h3 class="text-white text-lg"> <h3 class="text-white text-lg">
<LiveRedirect to={{ ash_admin_path(@socket) }}> <LiveRedirect to={{ ash_admin_path(@prefix) }}>
Admin Admin
</LiveRedirect> </LiveRedirect>
</h3> </h3>
@ -44,7 +45,7 @@ defmodule AshAdmin.Components.TopNav do
class="mr-1" class="mr-1"
id={{ AshAdmin.Api.name(api) <> "_api_nav" }} id={{ AshAdmin.Api.name(api) <> "_api_nav" }}
name={{ AshAdmin.Api.name(api) }} name={{ AshAdmin.Api.name(api) }}
groups={{ dropdown_groups(@socket, @resource, api) }} groups={{ dropdown_groups(@prefix, @resource, api) }}
/> />
</div> </div>
<div class="ml-10 flex items-center"> <div class="ml-10 flex items-center">
@ -59,6 +60,7 @@ defmodule AshAdmin.Components.TopNav do
clear_actor={{ @clear_actor }} clear_actor={{ @clear_actor }}
actor_api={{ @actor_api }} actor_api={{ @actor_api }}
api={{ @api }} api={{ @api }}
prefix={{ @prefix }}
/> />
<TenantForm <TenantForm
:if={{ show_tenant_form?(@apis) }} :if={{ show_tenant_form?(@apis) }}
@ -112,6 +114,7 @@ defmodule AshAdmin.Components.TopNav do
clear_actor={{ @clear_actor }} clear_actor={{ @clear_actor }}
actor_api={{ @actor_api }} actor_api={{ @actor_api }}
api={{ @api }} api={{ @api }}
prefix={{ @prefix }}
/> />
</div> </div>
<div class="block px-4 py-2 text-sm"> <div class="block px-4 py-2 text-sm">
@ -127,7 +130,7 @@ defmodule AshAdmin.Components.TopNav do
:for={{ api <- @apis }} :for={{ api <- @apis }}
id={{ AshAdmin.Api.name(api) <> "_api_nav_drawer" }} id={{ AshAdmin.Api.name(api) <> "_api_nav_drawer" }}
name={{ AshAdmin.Api.name(api) }} name={{ AshAdmin.Api.name(api) }}
groups={{ dropdown_groups(@socket, @resource, api) }} groups={{ dropdown_groups(@prefix, @resource, api) }}
/> />
</div> </div>
</div> </div>
@ -135,12 +138,12 @@ defmodule AshAdmin.Components.TopNav do
""" """
end end
defp dropdown_groups(socket, current_resource, api) do defp dropdown_groups(prefix, current_resource, api) do
[ [
for resource <- Ash.Api.resources(api) do for resource <- Ash.Api.resources(api) do
%{ %{
text: AshAdmin.Resource.name(resource), text: AshAdmin.Resource.name(resource),
to: ash_admin_path(socket, api, resource), to: ash_admin_path(prefix, api, resource),
active: resource == current_resource active: resource == current_resource
} }
end end

View file

@ -15,6 +15,7 @@ defmodule AshAdmin.Components.TopNav.ActorSelect do
prop(clear_actor, :event, required: true) prop(clear_actor, :event, required: true)
prop(api, :any, required: true) prop(api, :any, required: true)
prop(actor_api, :any, required: true) prop(actor_api, :any, required: true)
prop(prefix, :any, required: true)
def render(assigns) do def render(assigns) do
~H""" ~H"""
@ -74,11 +75,10 @@ defmodule AshAdmin.Components.TopNav.ActorSelect do
<LiveRedirect <LiveRedirect
class="hover:text-blue-400 hover:underline" class="hover:text-blue-400 hover:underline"
to={{ash_show_path( to={{ash_show_path(
@socket, @prefix,
@actor_api, @actor_api,
@actor.__struct__, @actor.__struct__,
@actor, @actor,
AshAdmin.Resource.show_action(@actor.__struct__),
nil nil
)}} )}}
> >
@ -108,7 +108,7 @@ defmodule AshAdmin.Components.TopNav.ActorSelect do
defp render_actor_link(assigns, [{api, resource}]) do defp render_actor_link(assigns, [{api, resource}]) do
~H""" ~H"""
<LiveRedirect to={{ash_action_path( <LiveRedirect to={{ash_action_path(
@socket, @prefix,
api, api,
resource, resource,
:read, :read,
@ -125,7 +125,7 @@ defmodule AshAdmin.Components.TopNav.ActorSelect do
<div aria-labelledby="actor-banner"> <div aria-labelledby="actor-banner">
<LiveRedirect <LiveRedirect
to={{ash_action_path( to={{ash_action_path(
@socket, @prefix,
api, api,
resource, resource,
:read, :read,

View file

@ -47,10 +47,6 @@ defmodule AshAdmin.Helpers do
Ash.Changeset.set_context(changeset, %{data_layer: %{table: table}}) Ash.Changeset.set_context(changeset, %{data_layer: %{table: table}})
end end
def ash_admin_path(socket) do
apply(socket.router.__helpers__(), :ash_admin_path, [socket, :page])
end
def self_path(url_path, socket_params, new_params) do def self_path(url_path, socket_params, new_params) do
url_path <> url_path <>
"?" <> "?" <>
@ -88,238 +84,135 @@ defmodule AshAdmin.Helpers do
end end
end end
@doc """ defp prefix(nil, path), do: path
TODO defp prefix(prefix, path), do: prefix <> path
"""
def ash_admin_path(socket, api) do def ash_admin_path(prefix) do
apply( prefix(prefix, "/")
socket.router.__helpers__(), end
String.to_existing_atom(String.downcase(AshAdmin.Api.name(api) <> "_path")),
[socket, :api_page] def ash_admin_path(prefix, api) do
prefix(prefix, "/#{AshAdmin.Api.name(api)}")
end
def ash_admin_path(prefix, api, resource) do
prefix(
prefix,
"/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}"
) )
end end
def ash_admin_path(socket, api, resource) do def ash_create_path(prefix, api, resource) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase(AshAdmin.Api.name(api) <> AshAdmin.Resource.name(resource) <> "_path") "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/create"
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page]
) )
end end
def ash_create_path(socket, api, resource) do def ash_create_path(prefix, api, resource, action_name, nil) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/create/#{action_name}"
AshAdmin.Api.name(api) <> AshAdmin.Resource.name(resource) <> "create_path"
)
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page]
) )
end end
def ash_create_path(socket, api, resource, action_name, nil) do def ash_create_path(prefix, api, resource, action_name, table) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/#{table}/create/#{
AshAdmin.Api.name(api) <> action_name
AshAdmin.Resource.name(resource) <> "create" <> to_string(action_name) <> "_path" }"
)
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page]
) )
end end
def ash_create_path(socket, api, resource, action_name, table) do def ash_update_path(prefix, api, resource, record) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/update/#{
AshAdmin.Api.name(api) <> encode_primary_key(record)
AshAdmin.Resource.name(resource) <> }"
table <>
"create" <> to_string(action_name) <> "_path"
)
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page]
) )
end end
def ash_update_path(socket, api, resource, record) do def ash_update_path(prefix, api, resource, record, action_name, nil) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/update/#{action_name}/#{
AshAdmin.Api.name(api) <> AshAdmin.Resource.name(resource) <> "update_path" encode_primary_key(record)
) }"
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page, encode_primary_key(record)]
) )
end end
def ash_update_path(socket, api, resource, record, action_name, nil) do def ash_update_path(prefix, api, resource, record, action_name, table) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/#{table}/update/#{
AshAdmin.Api.name(api) <> action_name
AshAdmin.Resource.name(resource) <> "update" <> to_string(action_name) <> "_path" }/#{encode_primary_key(record)}"
)
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page, encode_primary_key(record)]
) )
end end
def ash_update_path(socket, api, resource, record, action_name, table) do def ash_destroy_path(prefix, api, resource, record) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/destroy/#{
AshAdmin.Api.name(api) <> encode_primary_key(record)
AshAdmin.Resource.name(resource) <> }"
table <> "update" <> to_string(action_name) <> "_path"
)
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page, encode_primary_key(record)]
) )
end end
def ash_destroy_path(socket, api, resource, record) do def ash_destroy_path(prefix, api, resource, record, action_name, nil) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/destroy/#{action_name}/#{
AshAdmin.Api.name(api) <> AshAdmin.Resource.name(resource) <> "destroy_path" encode_primary_key(record)
) }"
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page, encode_primary_key(record)]
) )
end end
def ash_destroy_path(socket, api, resource, record, action_name, nil) do def ash_destroy_path(prefix, api, resource, record, action_name, table) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/#{table}/destroy/#{
AshAdmin.Api.name(api) <> action_name
AshAdmin.Resource.name(resource) <> "destroy" <> to_string(action_name) <> "_path" }#{encode_primary_key(record)}"
)
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page, encode_primary_key(record)]
) )
end end
def ash_destroy_path(socket, api, resource, record, action_name, table) do def ash_action_path(prefix, api, resource, action_type, action_name, nil) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/#{action_type}/#{
AshAdmin.Api.name(api) <> action_name
AshAdmin.Resource.name(resource) <> }"
table <> "destroy" <> to_string(action_name) <> "_path"
)
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page, encode_primary_key(record)]
) )
end end
def ash_action_path(socket, api, resource, action_type, action_name, nil) do def ash_action_path(prefix, api, resource, action_type, action_name, table) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/#{table}/#{action_type}/#{
AshAdmin.Api.name(api) <> action_name
AshAdmin.Resource.name(resource) <> "_#{action_type}" <> "_#{action_name}" <> "_path" }"
)
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page]
)
end
def ash_action_path(socket, api, resource, action_type, action_name, table) do
route =
String.to_existing_atom(
String.downcase(
AshAdmin.Api.name(api) <>
AshAdmin.Resource.name(resource) <>
table <> "_#{action_type}" <> "_#{action_name}" <> "_path"
)
)
apply(
socket.router.__helpers__(),
route,
[socket, :resource_page]
) )
end end
# sobelow_skip ["DOS.StringToAtom"] # sobelow_skip ["DOS.StringToAtom"]
def ash_show_path(socket, api, resource, record, action_name, nil) do def ash_show_path(prefix, api, resource, record, nil) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/show/#{
AshAdmin.Api.name(api) <> encode_primary_key(record)
AshAdmin.Resource.name(resource) <> "_show" <> "_#{action_name}" <> "_path" }"
)
)
apply(
socket.router.__helpers__(),
route,
[socket, :show_page, encode_primary_key(record)]
) )
end end
def ash_show_path(socket, api, resource, record, action_name, table) do def ash_show_path(prefix, api, resource, record, table) do
route = prefix(
String.to_existing_atom( prefix,
String.downcase( "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}/#{table}/show/#{
AshAdmin.Api.name(api) <> encode_primary_key(record)
AshAdmin.Resource.name(resource) <> table <> "_show" <> "_#{action_name}" <> "_path" }"
)
)
apply(
socket.router.__helpers__(),
route,
[socket, :show_page, encode_primary_key(record)]
) )
end end

View file

@ -19,6 +19,7 @@ defmodule AshAdmin.PageLive do
def mount( def mount(
_params, _params,
%{ %{
"prefix" => prefix,
"api" => api, "api" => api,
"apis" => apis, "apis" => apis,
"tab" => tab, "tab" => tab,
@ -28,6 +29,8 @@ defmodule AshAdmin.PageLive do
} = session, } = session,
socket socket
) do ) do
socket = assign(socket, :prefix, prefix)
actor_paused = actor_paused =
if is_nil(session["actor_paused"]) do if is_nil(session["actor_paused"]) do
true true
@ -48,6 +51,7 @@ defmodule AshAdmin.PageLive do
{:ok, {:ok,
socket socket
|> Surface.init() |> Surface.init()
|> assign(:prefix, prefix)
|> assign(:api, api) |> assign(:api, api)
|> assign(:apis, apis) |> assign(:apis, apis)
|> assign(:resource, resource) |> assign(:resource, resource)
@ -87,6 +91,7 @@ defmodule AshAdmin.PageLive do
toggle_authorizing="toggle_authorizing" toggle_authorizing="toggle_authorizing"
toggle_actor_paused="toggle_actor_paused" toggle_actor_paused="toggle_actor_paused"
clear_actor="clear_actor" clear_actor="clear_actor"
prefix={{ @prefix }}
/> />
<Resource <Resource
:if={{ @resource }} :if={{ @resource }}
@ -105,6 +110,7 @@ defmodule AshAdmin.PageLive do
authorizing={{ @authorizing }} authorizing={{ @authorizing }}
table={{ @table }} table={{ @table }}
tables={{ @tables }} tables={{ @tables }}
prefix={{ @prefix }}
/> />
""" """
end end

View file

@ -12,6 +12,8 @@ defmodule AshAdmin.Router do
```elixir ```elixir
defmodule MyAppWeb.Router do defmodule MyAppWeb.Router do
use Phoenix.Router use Phoenix.Router
import AshAdmin.Router
admin_browser_pipeline :something admin_browser_pipeline :something
scope "/" do scope "/" do
@ -65,6 +67,13 @@ defmodule AshAdmin.Router do
scope path, alias: false, as: false do scope path, alias: false, as: false do
import Phoenix.LiveView.Router, only: [live: 4] import Phoenix.LiveView.Router, only: [live: 4]
prefix =
if opts[:prefix] do
opts[:prefix] <> path
else
path
end
apis = opts[:apis] apis = opts[:apis]
Enum.each(apis, &Code.ensure_compiled/1) Enum.each(apis, &Code.ensure_compiled/1)
api = List.first(opts[:apis]) api = List.first(opts[:apis])
@ -78,7 +87,8 @@ defmodule AshAdmin.Router do
"/", "/",
AshAdmin.PageLive, AshAdmin.PageLive,
:page, :page,
AshAdmin.Router.__options__(opts, :ash_admin, %{ AshAdmin.Router.__options__(opts, %{
"prefix" => prefix,
"apis" => apis, "apis" => apis,
"api" => api, "api" => api,
"tab" => nil, "tab" => nil,
@ -89,17 +99,12 @@ defmodule AshAdmin.Router do
) )
for api <- apis do for api <- apis do
as =
api
|> AshAdmin.Api.name()
|> String.downcase()
|> String.to_atom()
live( live(
"/#{AshAdmin.Api.name(api)}", "/#{AshAdmin.Api.name(api)}",
AshAdmin.PageLive, AshAdmin.PageLive,
:api_page, :api_page,
AshAdmin.Router.__options__(opts, as, %{ AshAdmin.Router.__options__(opts, %{
"prefix" => prefix,
"apis" => apis, "apis" => apis,
"api" => api, "api" => api,
"tab" => "info", "tab" => "info",
@ -112,19 +117,12 @@ defmodule AshAdmin.Router do
for resource <- Ash.Api.resources(api) do for resource <- Ash.Api.resources(api) do
for {table, alias_part, polymorphic_part} <- for {table, alias_part, polymorphic_part} <-
AshAdmin.Router.polymorphic_parts(resource, apis) do AshAdmin.Router.polymorphic_parts(resource, apis) do
as =
api
|> AshAdmin.Api.name()
|> Kernel.<>(AshAdmin.Resource.name(resource))
|> Kernel.<>(alias_part)
|> String.downcase()
|> String.to_atom()
live( live(
"/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{polymorphic_part}", "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{polymorphic_part}",
AshAdmin.PageLive, AshAdmin.PageLive,
:resource_page, :resource_page,
AshAdmin.Router.__options__(opts, as, %{ AshAdmin.Router.__options__(opts, %{
"prefix" => prefix,
"apis" => apis, "apis" => apis,
"api" => api, "api" => api,
"tab" => "info", "tab" => "info",
@ -136,22 +134,14 @@ defmodule AshAdmin.Router do
) )
if Enum.any?(Ash.Resource.Info.actions(resource), &(&1.type == :create)) do if Enum.any?(Ash.Resource.Info.actions(resource), &(&1.type == :create)) do
as =
api
|> AshAdmin.Api.name()
|> Kernel.<>(AshAdmin.Resource.name(resource))
|> Kernel.<>(alias_part)
|> Kernel.<>("create")
|> String.downcase()
|> String.to_atom()
live( live(
"/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{ "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{
polymorphic_part polymorphic_part
}/create", }/create",
AshAdmin.PageLive, AshAdmin.PageLive,
:resource_page, :resource_page,
AshAdmin.Router.__options__(opts, as, %{ AshAdmin.Router.__options__(opts, %{
"prefix" => prefix,
"apis" => apis, "apis" => apis,
"api" => api, "api" => api,
"resource" => resource, "resource" => resource,
@ -164,23 +154,14 @@ defmodule AshAdmin.Router do
end end
for %{type: :create} = action <- Ash.Resource.Info.actions(resource) do for %{type: :create} = action <- Ash.Resource.Info.actions(resource) do
as =
api
|> AshAdmin.Api.name()
|> Kernel.<>(AshAdmin.Resource.name(resource))
|> Kernel.<>(alias_part)
|> Kernel.<>("create")
|> Kernel.<>(to_string(action.name))
|> String.downcase()
|> String.to_atom()
live( live(
"/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{ "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{
polymorphic_part polymorphic_part
}/create/#{action.name}", }/create/#{action.name}",
AshAdmin.PageLive, AshAdmin.PageLive,
:resource_page, :resource_page,
AshAdmin.Router.__options__(opts, as, %{ AshAdmin.Router.__options__(opts, %{
"prefix" => prefix,
"apis" => apis, "apis" => apis,
"api" => api, "api" => api,
"resource" => resource, "resource" => resource,
@ -193,22 +174,14 @@ defmodule AshAdmin.Router do
end end
if Enum.any?(Ash.Resource.Info.actions(resource), &(&1.type == :update)) do if Enum.any?(Ash.Resource.Info.actions(resource), &(&1.type == :update)) do
as =
api
|> AshAdmin.Api.name()
|> Kernel.<>(AshAdmin.Resource.name(resource))
|> Kernel.<>(alias_part)
|> Kernel.<>("update")
|> String.downcase()
|> String.to_atom()
live( live(
"/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{ "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{
polymorphic_part polymorphic_part
}/update/:primary_key", }/update/:primary_key",
AshAdmin.PageLive, AshAdmin.PageLive,
:resource_page, :resource_page,
AshAdmin.Router.__options__(opts, as, %{ AshAdmin.Router.__options__(opts, %{
"prefix" => prefix,
"apis" => apis, "apis" => apis,
"api" => api, "api" => api,
"resource" => resource, "resource" => resource,
@ -220,23 +193,14 @@ defmodule AshAdmin.Router do
) )
for %{type: :update} = action <- Ash.Resource.Info.actions(resource) do for %{type: :update} = action <- Ash.Resource.Info.actions(resource) do
as =
api
|> AshAdmin.Api.name()
|> Kernel.<>(AshAdmin.Resource.name(resource))
|> Kernel.<>(alias_part)
|> Kernel.<>("update")
|> Kernel.<>(to_string(action.name))
|> String.downcase()
|> String.to_atom()
live( live(
"/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{ "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{
polymorphic_part polymorphic_part
}/update/#{action.name}/:primary_key", }/update/#{action.name}/:primary_key",
AshAdmin.PageLive, AshAdmin.PageLive,
:resource_page, :resource_page,
AshAdmin.Router.__options__(opts, as, %{ AshAdmin.Router.__options__(opts, %{
"prefix" => prefix,
"apis" => apis, "apis" => apis,
"api" => api, "api" => api,
"resource" => resource, "resource" => resource,
@ -250,22 +214,14 @@ defmodule AshAdmin.Router do
end end
if Enum.any?(Ash.Resource.Info.actions(resource), &(&1.type == :destroy)) do if Enum.any?(Ash.Resource.Info.actions(resource), &(&1.type == :destroy)) do
as =
api
|> AshAdmin.Api.name()
|> Kernel.<>(AshAdmin.Resource.name(resource))
|> Kernel.<>(alias_part)
|> Kernel.<>("destroy")
|> String.downcase()
|> String.to_atom()
live( live(
"/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{ "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{
polymorphic_part polymorphic_part
}/destroy/:primary_key", }/destroy/:primary_key",
AshAdmin.PageLive, AshAdmin.PageLive,
:resource_page, :resource_page,
AshAdmin.Router.__options__(opts, as, %{ AshAdmin.Router.__options__(opts, %{
"prefix" => prefix,
"apis" => apis, "apis" => apis,
"api" => api, "api" => api,
"resource" => resource, "resource" => resource,
@ -277,23 +233,14 @@ defmodule AshAdmin.Router do
) )
for %{type: :destroy} = action <- Ash.Resource.Info.actions(resource) do for %{type: :destroy} = action <- Ash.Resource.Info.actions(resource) do
as =
api
|> AshAdmin.Api.name()
|> Kernel.<>(AshAdmin.Resource.name(resource))
|> Kernel.<>(alias_part)
|> Kernel.<>("destroy")
|> Kernel.<>(to_string(action.name))
|> String.downcase()
|> String.to_atom()
live( live(
"/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{ "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{
polymorphic_part polymorphic_part
}/destroy/#{action.name}/:primary_key", }/destroy/#{action.name}/:primary_key",
AshAdmin.PageLive, AshAdmin.PageLive,
:resource_page, :resource_page,
AshAdmin.Router.__options__(opts, as, %{ AshAdmin.Router.__options__(opts, %{
"prefix" => prefix,
"apis" => apis, "apis" => apis,
"api" => api, "api" => api,
"resource" => resource, "resource" => resource,
@ -312,23 +259,14 @@ defmodule AshAdmin.Router do
action = action =
Ash.Resource.Info.action(resource, AshAdmin.Resource.show_action(resource)) Ash.Resource.Info.action(resource, AshAdmin.Resource.show_action(resource))
as =
api
|> AshAdmin.Api.name()
|> Kernel.<>(AshAdmin.Resource.name(resource))
|> Kernel.<>(alias_part)
|> Kernel.<>("_show")
|> Kernel.<>("_#{action.name}")
|> String.downcase()
|> String.to_atom()
live( live(
"/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{ "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{
polymorphic_part polymorphic_part
}/show/:primary_key", }/show/:primary_key",
AshAdmin.PageLive, AshAdmin.PageLive,
:show_page, :show_page,
AshAdmin.Router.__options__(opts, as, %{ AshAdmin.Router.__options__(opts, %{
"prefix" => prefix,
"apis" => apis, "apis" => apis,
"api" => api, "api" => api,
"resource" => resource, "resource" => resource,
@ -341,23 +279,14 @@ defmodule AshAdmin.Router do
end end
for %{type: :read} = action <- Ash.Resource.Info.actions(resource) do for %{type: :read} = action <- Ash.Resource.Info.actions(resource) do
as =
api
|> AshAdmin.Api.name()
|> Kernel.<>(AshAdmin.Resource.name(resource))
|> Kernel.<>(alias_part)
|> Kernel.<>("_read")
|> Kernel.<>("_#{action.name}")
|> String.downcase()
|> String.to_atom()
live( live(
"/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{ "/#{AshAdmin.Api.name(api)}/#{AshAdmin.Resource.name(resource)}#{
polymorphic_part polymorphic_part
}/#{action.type}/#{action.name}", }/#{action.type}/#{action.name}",
AshAdmin.PageLive, AshAdmin.PageLive,
:resource_page, :resource_page,
AshAdmin.Router.__options__(opts, as, %{ AshAdmin.Router.__options__(opts, %{
"prefix" => prefix,
"apis" => apis, "apis" => apis,
"api" => api, "api" => api,
"resource" => resource, "resource" => resource,
@ -376,14 +305,13 @@ defmodule AshAdmin.Router do
end end
@doc false @doc false
def __options__(options, as, session) do def __options__(options, session) do
live_socket_path = Keyword.get(options, :live_socket_path, "/live") live_socket_path = Keyword.get(options, :live_socket_path, "/live")
[ [
session: {__MODULE__, :__session__, [session]}, session: {__MODULE__, :__session__, [session]},
private: %{live_socket_path: live_socket_path}, private: %{live_socket_path: live_socket_path},
layout: {AshAdmin.LayoutView, :admin}, layout: {AshAdmin.LayoutView, :admin}
as: as
] ]
end end

View file

@ -90,7 +90,8 @@ defmodule AshAdmin.MixProject do
defp deps do defp deps do
[ [
{:ash, "~> 1.36 and >= 1.36.18"}, {:ash, "~> 1.36 and >= 1.36.18"},
{:ash_phoenix, "~> 0.4 and >= 0.4.4"}, # {:ash_phoenix, "~> 0.4 and >= 0.4.4"},
{:ash_phoenix, path: "../ash_phoenix"},
{:surface, "~> 0.3.1"}, {:surface, "~> 0.3.1"},
{:phoenix_live_view, "~> 0.15.4"}, {:phoenix_live_view, "~> 0.15.4"},
{:phoenix_html, "~> 2.14.1 or ~> 2.15"}, {:phoenix_html, "~> 2.14.1 or ~> 2.15"},