I have a simple user admin LiveView page which uses streams to list users in a table and provides a delete link on each user row. Users have roles defined as a list of atoms e.g. [:user] or [:admin, :user]
I’m trying to prevent the handle_event("delete",...) call from deleting a user if they have the :admin role. I can prevent the deletion in the Repo easily enough but the table row in the LiveView is still being removed.
The handle_event code is:
@impl true
def handle_event("delete", %{"id" => id}, socket) do
user = Accounts.get_user!(id)
unless Enum.member?(user.roles, :admin) do
{:ok, _} = Accounts.delete_user(user)
{:noreply, stream_delete(socket, :users, user)}
else
{:noreply, socket}
end
end
Anyone who can tell me what’s the obvious factor that am I missing here?
A less jarring approach to some buttons being visible vs not would be to set them disabled instead. The button is then visible but clicking does nothing. You could also change the cursor but I think it does that for you.
If that LiveView user index page was created via the mix phx.gen.live, the phx-click binding will use LiveView’s client side utility command JS.hide/2 to hide the row after pushing the delete event back to the server.
Once you remove |> hide("##{id}") from the phx-click binding, it should no longer be removed on the client side when not deleting a user because it has an :admin role on the server side. That said, I second the suggestions by @Eiji and @w0rd-driven to conditionally remove or disable the delete button from a UI/UX standpoint.
Thank you, @codeanpeace for explaining why it’s being removed and @Eiji for the suggestion - that’s the approach I’ve gone for as the UI/UX is better as highlighted by others on this thread.