diff --git a/lib/decentralised_book_index_web/live/book_live/edit.ex b/lib/decentralised_book_index_web/live/book_live/edit.ex new file mode 100644 index 0000000..b709601 --- /dev/null +++ b/lib/decentralised_book_index_web/live/book_live/edit.ex @@ -0,0 +1,53 @@ +defmodule DecentralisedBookIndexWeb.BookLive.Edit do + use DecentralisedBookIndexWeb, :live_view + + @impl true + def render(assigns) do + ~H""" + <.live_component + module={DecentralisedBookIndexWeb.BookLive.FormComponent} + id={(@book && @book.id) || :new} + title={@page_title} + current_user={@current_user} + action={@live_action} + book={@book} + /> + """ + end + + @impl true + def mount(_params, _session, socket) do + {:ok, + socket + |> stream( + :books, + Ash.read!(DecentralisedBookIndex.Metadata.Book, actor: socket.assigns[:current_user]) + ) + |> assign_new(:current_user, fn -> nil end)} + end + + @impl true + def handle_params(params, _url, socket) do + {:noreply, apply_action(socket, socket.assigns.live_action, params)} + end + + defp apply_action(socket, :edit, %{"id" => id}) do + socket + |> assign(:page_title, "Edit Book") + |> assign( + :book, + Ash.get!(DecentralisedBookIndex.Metadata.Book, id, actor: socket.assigns.current_user) + ) + end + + defp apply_action(socket, :new, _params) do + socket + |> assign(:page_title, "New Book") + |> assign(:book, nil) + end + + @impl true + def handle_info({DecentralisedBookIndexWeb.BookLive.FormComponent, {:saved, book}}, socket) do + {:noreply, stream_insert(socket, :books, book)} + end +end diff --git a/lib/decentralised_book_index_web/live/book_live/form_component.ex b/lib/decentralised_book_index_web/live/book_live/form_component.ex index b64a8cd..3181f1d 100644 --- a/lib/decentralised_book_index_web/live/book_live/form_component.ex +++ b/lib/decentralised_book_index_web/live/book_live/form_component.ex @@ -45,7 +45,12 @@ defmodule DecentralisedBookIndexWeb.BookLive.FormComponent do <% end %> <:actions> - <.button phx-disable-with="Saving...">Save Book + <.save_button phx-disable-with="Saving..."> + Save + + <.cancel_button phx-click="cancel" phx-target={@myself}> + Cancel + @@ -223,7 +228,7 @@ defmodule DecentralisedBookIndexWeb.BookLive.FormComponent do socket = socket |> put_flash(:info, "Book #{socket.assigns.form.source.type}d successfully") - |> push_patch(to: socket.assigns.patch) + |> push_redirect(to: patch_url(socket.assigns.action, book.id)) {:noreply, socket} @@ -232,6 +237,17 @@ defmodule DecentralisedBookIndexWeb.BookLive.FormComponent do end end + def handle_event("cancel", _params, socket) do + book = socket.assigns.book + book_id = if book == nil, do: nil, else: book.id + + socket = + socket + |> push_redirect(to: patch_url(socket.assigns.action, book_id)) + + {:noreply, socket} + end + defp notify_parent(msg), do: send(self(), {__MODULE__, msg}) defp assign_form(%{assigns: %{book: book}} = socket) do @@ -247,4 +263,12 @@ defmodule DecentralisedBookIndexWeb.BookLive.FormComponent do assign(socket, form: to_form(form)) end + + defp patch_url(action, book_id) do + case action do + :edit -> ~p"/books/#{book_id}" + :new -> ~p"/books" + _ -> ~p"/books" + end + end end diff --git a/lib/decentralised_book_index_web/router.ex b/lib/decentralised_book_index_web/router.ex index 9b95d27..5dcc395 100644 --- a/lib/decentralised_book_index_web/router.ex +++ b/lib/decentralised_book_index_web/router.ex @@ -37,13 +37,6 @@ defmodule DecentralisedBookIndexWeb.Router do live "/", BookLive.Index, :index - live "/books", BookLive.Index, :index - live "/books/new", BookLive.Index, :new - live "/books/:id/edit", BookLive.Index, :edit - - live "/books/:id", BookLive.Show, :show - live "/books/:id/show/edit", BookLive.Show, :edit - live "/publishers", PublisherLive.Index, :index live "/publishers/new", PublisherLive.Index, :new live "/publishers/:id/edit", PublisherLive.Index, :edit @@ -70,6 +63,13 @@ defmodule DecentralisedBookIndexWeb.Router do # If an authenticated user must *not* be present: # on_mount {DecentralisedBookIndexWeb.LiveUserAuth, :live_no_user} + live "/books", BookLive.Index, :index + live "/books/new", BookLive.Edit, :new + live "/books/:id/edit", BookLive.Edit, :edit + + live "/books/:id", BookLive.Show, :show + live "/books/:id/show/edit", BookLive.Show, :edit + live "/authors", AuthorLive.Index, :index live "/authors/new", AuthorLive.Edit, :new live "/authors/:id/edit", AuthorLive.Edit, :edit