styling, require a code for prompts, admin privs, ordering, filtering, jump-to-page
This commit is contained in:
@@ -2,7 +2,6 @@ defmodule DiffuserWeb.PromptRequestLive.FormComponent do
|
||||
use DiffuserWeb, :live_component
|
||||
|
||||
alias Diffuser.Generator
|
||||
alias Diffuser.Generator.PromptRequest
|
||||
|
||||
@impl true
|
||||
def update(%{prompt_request: prompt_request} = assigns, socket) do
|
||||
@@ -28,30 +27,23 @@ defmodule DiffuserWeb.PromptRequestLive.FormComponent do
|
||||
save_prompt_request(socket, socket.assigns.action, prompt_request_params)
|
||||
end
|
||||
|
||||
defp save_prompt_request(socket, :edit, prompt_request_params) do
|
||||
case Generator.update_prompt_request(socket.assigns.prompt_request, prompt_request_params) do
|
||||
{:ok, %PromptRequest{} = prompt_request} ->
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "Prompt request updated successfully")
|
||||
|> push_redirect(to: Routes.prompt_request_show_path(socket, :show, prompt_request))}
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
{:noreply, assign(socket, :changeset, changeset)}
|
||||
end
|
||||
end
|
||||
|
||||
defp save_prompt_request(socket, :new, prompt_request_params) do
|
||||
defp save_prompt_request(%{assigns: %{user: _user}} = socket, :new, prompt_request_params) do
|
||||
with {:ok, prompt_request} <- Generator.create_prompt_request(prompt_request_params) do
|
||||
Diffuser.Generator.PromptRequestQueue.enqueue(prompt_request)
|
||||
|
||||
{:noreply,
|
||||
socket
|
||||
|> put_flash(:info, "Prompt request created successfully")
|
||||
|> push_redirect(to: Routes.prompt_request_show_path(socket, :show, prompt_request))}
|
||||
|> push_redirect(to: Routes.prompt_request_index_path(socket, :index))}
|
||||
else
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
{:noreply, assign(socket, changeset: changeset)}
|
||||
end
|
||||
end
|
||||
|
||||
defp save_prompt_request(socket, :new, _) do
|
||||
{:noreply,
|
||||
socket
|
||||
|> push_redirect(to: Routes.prompt_request_index_path(socket, :index))}
|
||||
end
|
||||
end
|
||||
|
@@ -1,20 +1,41 @@
|
||||
<div>
|
||||
<h2><%= @title %></h2>
|
||||
<div class="prose grid grid-flow-col">
|
||||
<!-- Put this part before </body> tag -->
|
||||
<.form
|
||||
let={f}
|
||||
for={@changeset}
|
||||
id="prompt_request-form"
|
||||
phx-target={@myself}
|
||||
phx-change="validate"
|
||||
phx-submit="save">
|
||||
|
||||
<.form
|
||||
let={f}
|
||||
for={@changeset}
|
||||
id="prompt_request-form"
|
||||
phx-target={@myself}
|
||||
phx-change="validate"
|
||||
phx-submit="save">
|
||||
|
||||
<%= label f, :prompt %>
|
||||
<%= text_input f, :prompt %>
|
||||
<%= error_tag f, :prompt %>
|
||||
|
||||
<div>
|
||||
<%= submit "Save", phx_disable_with: "Saving..." %>
|
||||
</div>
|
||||
</.form>
|
||||
<div class="form-control w-full">
|
||||
<label class="label">
|
||||
<span class="label-text">What shall we dream of?</span>
|
||||
</label>
|
||||
<%= text_input f, :prompt, class: "input" %>
|
||||
<%= error_tag f, :prompt %>
|
||||
</div>
|
||||
|
||||
<div class="form-control w-full">
|
||||
<label class="label">
|
||||
<span class="label-text">How long should it dream?</span>
|
||||
</label>
|
||||
<%= number_input f, :steps, class: "input", min: 1, max: 60, step: 1 %>
|
||||
<%= error_tag f, :prompt %>
|
||||
</div>
|
||||
|
||||
<div class="form-control w-full">
|
||||
<label class="label">
|
||||
<span class="label-text">How much do your words control the dream?</span>
|
||||
</label>
|
||||
<%= number_input f, :guidance_scale, class: "input", step: 0.1 %>
|
||||
<%= error_tag f, :prompt %>
|
||||
</div>
|
||||
|
||||
<%= hidden_input f, :user, value: @user.id %>
|
||||
|
||||
<div style="text-align: end;" class="pt-6">
|
||||
<%= submit "Save", phx_disable_with: "Saving...", class: "btn" %>
|
||||
</div>
|
||||
</.form>
|
||||
</div>
|
||||
|
@@ -3,46 +3,204 @@ defmodule DiffuserWeb.PromptRequestLive.Index do
|
||||
|
||||
alias Diffuser.Generator
|
||||
alias Diffuser.Generator.PromptRequest
|
||||
alias Diffuser.Accounts
|
||||
alias Diffuser.Accounts.User
|
||||
alias DiffuserWeb.Endpoint
|
||||
alias Phoenix.Socket.Broadcast
|
||||
alias Diffuser.Repo
|
||||
alias Ecto.Association.NotLoaded
|
||||
|
||||
@impl true
|
||||
def mount(_params, _session, socket) do
|
||||
{:ok, socket}
|
||||
def mount(params, %{"user" => user, "is_admin" => is_admin}, socket) do
|
||||
changeset = Accounts.change_user(user)
|
||||
|
||||
{:ok,
|
||||
socket
|
||||
|> assign(:user, user)
|
||||
|> assign(:params, params)
|
||||
|> assign(:is_admin, is_admin)
|
||||
|> assign(:user_changeset, changeset)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_params(params, _url, socket) do
|
||||
page = list_prompt_requests(params)
|
||||
socket = socket |> apply_action(socket.assigns.live_action, params) |> assign(:page, page)
|
||||
page = list_prompt_requests(params) |> subscribe_to_queued_prompts()
|
||||
|
||||
socket =
|
||||
socket
|
||||
|> apply_action(socket.assigns.live_action, params)
|
||||
|> assign(:page, page)
|
||||
|> assign(:params, params)
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
defp apply_action(socket, :edit, %{"id" => id}) do
|
||||
socket
|
||||
|> assign(:page_title, "Edit Prompt request")
|
||||
|> assign(:page_title, "Edit Prompt")
|
||||
|> assign(:prompt_request, Generator.get_prompt_request!(id))
|
||||
end
|
||||
|
||||
defp apply_action(socket, :new, _params) do
|
||||
socket
|
||||
|> assign(:page_title, "New Prompt request")
|
||||
|> assign(:page_title, "New Prompt")
|
||||
|> assign(:prompt_request, %PromptRequest{})
|
||||
end
|
||||
|
||||
defp apply_action(socket, :index, _params) do
|
||||
socket
|
||||
|> assign(:page_title, "Listing Prompt requests")
|
||||
|> assign(:page_title, "Listing Prompts")
|
||||
|> assign(:prompt_request, nil)
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_event("delete", %{"id" => id}, socket) do
|
||||
def handle_event("delete", %{"id" => id}, %{assigns: %{params: params}} = socket) do
|
||||
prompt_request = Generator.get_prompt_request!(id)
|
||||
{:ok, _} = Generator.delete_prompt_request(prompt_request)
|
||||
|
||||
{:noreply, assign(socket, :page, list_prompt_requests(%{"page" => "2"}))}
|
||||
{:noreply, assign(socket, :page, list_prompt_requests(params))}
|
||||
end
|
||||
|
||||
def handle_event("upvote", %{"id" => id}, %{assigns: %{user: user, params: params}} = socket) do
|
||||
prompt_request = Generator.get_prompt_request!(id)
|
||||
Diffuser.Accounts.upvote(user, prompt_request)
|
||||
|
||||
{:noreply, assign(socket, :page, list_prompt_requests(params))}
|
||||
end
|
||||
|
||||
def handle_event(
|
||||
"update_user",
|
||||
%{"user" => params},
|
||||
%{assigns: %{user: user}} = socket
|
||||
) do
|
||||
case Accounts.update_user(user, params) do
|
||||
{:ok, user} ->
|
||||
{:noreply, assign(socket, :user, user)}
|
||||
|
||||
{:error, %Ecto.Changeset{} = changeset} ->
|
||||
{:noreply, assign(socket, :user_changeset, changeset)}
|
||||
end
|
||||
end
|
||||
|
||||
def handle_event(
|
||||
"search",
|
||||
%{"search" => %{"query" => query}},
|
||||
%{assigns: %{params: params}} = socket
|
||||
) do
|
||||
params = Map.put(params, :query, query)
|
||||
page = Generator.paginate_prompt_requests(PromptRequest, params)
|
||||
{:noreply, socket |> assign(:params, params) |> assign(:page, page)}
|
||||
end
|
||||
|
||||
def handle_event("clear", _, socket) do
|
||||
page = Generator.paginate_prompt_requests(PromptRequest, %{page: 1})
|
||||
{:noreply, socket |> assign(:params, %{page: 1}) |> assign(:page, page)}
|
||||
end
|
||||
|
||||
def handle_event("order_by", %{"votes" => direction}, %{assigns: %{params: params}} = socket) do
|
||||
direction = if direction in ["asc", "desc"], do: direction, else: nil
|
||||
params = Map.put(params, :order_by, direction)
|
||||
page = Generator.paginate_prompt_requests(PromptRequest, params)
|
||||
{:noreply, socket |> assign(:params, params) |> assign(:page, page)}
|
||||
end
|
||||
|
||||
def handle_event("go_to" = event, %{"jump" => %{"page" => _page} = result}, socket),
|
||||
do: handle_event(event, result, socket)
|
||||
|
||||
def handle_event("go_to", %{"page" => page}, %{assigns: %{params: params}} = socket) do
|
||||
params = Map.put(params, :page, page)
|
||||
page = Generator.paginate_prompt_requests(PromptRequest, params)
|
||||
{:noreply, socket |> assign(:params, params) |> assign(:page, page)}
|
||||
end
|
||||
|
||||
defp has_voted(nil, _), do: false
|
||||
|
||||
defp has_voted(%{id: user_id}, %{votes: prompt_request_votes}) do
|
||||
prompt_request_votes
|
||||
|> Enum.any?(fn %{user_id: id} ->
|
||||
user_id == id
|
||||
end)
|
||||
end
|
||||
|
||||
defp display_current_filters(params) do
|
||||
query = Map.get(params, :query, nil)
|
||||
order_by = Map.get(params, :order_by, nil)
|
||||
page = Map.get(params, :page, 1)
|
||||
|
||||
query_str = if query, do: "Searching for \"#{query}\"", else: "Everything"
|
||||
order_by_str = if order_by == "desc", do: " with most votes", else: ""
|
||||
|
||||
query_str <> order_by_str <> " on page #{page}"
|
||||
end
|
||||
|
||||
defp display_name(%User{username: username}) when not is_nil(username), do: username
|
||||
|
||||
defp display_name(%User{id: id}), do: id |> String.slice(0, 8)
|
||||
|
||||
defp fake_name(), do: for(_ <- 1..8, into: "", do: <<Enum.random('0123456789abcdef')>>)
|
||||
|
||||
defp list_prompt_requests(params) do
|
||||
Generator.paginate_prompt_requests(params)
|
||||
Generator.paginate_prompt_requests(PromptRequest, params)
|
||||
end
|
||||
|
||||
defp total_time(%PromptRequest{began_at: began_at, ended_at: ended_at})
|
||||
when not is_nil(began_at) and not is_nil(ended_at) do
|
||||
"Processing Time: #{NaiveDateTime.diff(ended_at, began_at, :second)} seconds"
|
||||
end
|
||||
|
||||
defp total_time(_), do: ""
|
||||
|
||||
defp owns_prompt_request(user, %{user: %NotLoaded{} = prompt_request}),
|
||||
do: user |> owns_prompt_request(prompt_request |> Repo.preload(:user))
|
||||
|
||||
defp owns_prompt_request(nil, _), do: false
|
||||
|
||||
defp owns_prompt_request(_, %{user: nil}), do: false
|
||||
|
||||
defp owns_prompt_request(%{ip_address: their_ip_address, id: their_id}, %{
|
||||
user: %{ip_address: ip_address, id: id}
|
||||
})
|
||||
when their_ip_address == ip_address or their_id == id,
|
||||
do: true
|
||||
|
||||
defp owns_prompt_request(_, _), do: false
|
||||
|
||||
defp subscribe_to_queued_prompts(%Scrivener.Page{entries: entries} = page) do
|
||||
entries
|
||||
|> Enum.each(fn %PromptRequest{id: id, status: status} ->
|
||||
if status in ["queued", "in_progress"] do
|
||||
Endpoint.subscribe("request:#{id}")
|
||||
end
|
||||
end)
|
||||
|
||||
page
|
||||
end
|
||||
|
||||
@impl true
|
||||
def handle_info(
|
||||
%Broadcast{
|
||||
topic: _,
|
||||
event: event,
|
||||
payload: %{prompt_request: %PromptRequest{} = prompt_request}
|
||||
},
|
||||
socket
|
||||
)
|
||||
when event in ["request", "progress"],
|
||||
do: {:noreply, socket |> update_subscribed_prompt(prompt_request)}
|
||||
|
||||
defp update_subscribed_prompt(
|
||||
%{assigns: %{page: %Scrivener.Page{entries: entries} = page}} = socket,
|
||||
%PromptRequest{id: id} = prompt_request
|
||||
) do
|
||||
entries =
|
||||
entries
|
||||
|> Enum.map(
|
||||
&if &1.id === id, do: prompt_request |> Repo.preload([:votes, :user, :images]), else: &1
|
||||
)
|
||||
|
||||
page = Map.put(page, :entries, entries)
|
||||
|
||||
socket
|
||||
|> assign(:page, page)
|
||||
end
|
||||
end
|
||||
|
@@ -1,5 +1,3 @@
|
||||
<h1>Listing Prompt requests</h1>
|
||||
|
||||
<%= if @live_action in [:new, :edit] do %>
|
||||
<.modal return_to={Routes.prompt_request_index_path(@socket, :index)}>
|
||||
<.live_component
|
||||
@@ -7,52 +5,134 @@
|
||||
id={@prompt_request.id || :new}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
prompt_request={@prompt_request}}
|
||||
prompt_request={@prompt_request}
|
||||
user={@user}}
|
||||
/>
|
||||
</.modal>
|
||||
<% end %>
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Image</th>
|
||||
<th>Prompt</th>
|
||||
<%= if @user do %>
|
||||
<div class="p-4 max-w-7xl mx-auto bg-gray">
|
||||
<div class="collapse">
|
||||
<input type="checkbox" />
|
||||
<div class="collapse-title text-xl btn btn-outline">
|
||||
Info
|
||||
</div>
|
||||
<div class="collapse-content prose">
|
||||
<h3 class="pt-4">IP Address: <%= @user.ip_address %></h3>
|
||||
<p>Yes. Your server, Silas, will keep a record of which IP sent what.</p>
|
||||
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="prompt_requests">
|
||||
<%= for prompt_request <- @page.entries do %>
|
||||
<tr id={"prompt_request-#{prompt_request.id}"}>
|
||||
<td>
|
||||
<%= for result <- prompt_request.images do %>
|
||||
<img src={"#{Diffuser.Uploaders.Image.url({result.image, result})}"} />
|
||||
<% end %>
|
||||
</td>
|
||||
<td><%= prompt_request.prompt %></td>
|
||||
<h3>Username: <%= display_name(@user) %></h3>
|
||||
<.form let={f} for={@user_changeset} phx-submit="update_user">
|
||||
<div class="form-control w-full">
|
||||
<label class="label">
|
||||
<span class="label-text">Optionally set your own username. Might I recommend <%= fake_name() %>?</span>
|
||||
</label>
|
||||
<%= text_input f, :username, class: "input input-bordered input-secondary" %>
|
||||
<%= error_tag f, :username %>
|
||||
|
||||
<td>
|
||||
<span><%= live_redirect "Show", to: Routes.prompt_request_show_path(@socket, :show, prompt_request) %></span>
|
||||
<span><%= live_patch "Edit", to: Routes.prompt_request_index_path(@socket, :edit, prompt_request) %></span>
|
||||
<span><%= link "Delete", to: "#", phx_click: "delete", phx_value_id: prompt_request.id, data: [confirm: "Are you sure?"] %></span>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</tbody>
|
||||
</table>
|
||||
<%= submit "Save Username", class: "btn" %>
|
||||
</div>
|
||||
</.form>
|
||||
|
||||
<div class="pagination">
|
||||
<%= if @page.page_number > 1 do %>
|
||||
<%= live_patch "<< Prev Page",
|
||||
to: Routes.prompt_request_index_path(@socket, :index, page: @page.page_number - 1),
|
||||
class: "pagination-link" %>
|
||||
<% end %>
|
||||
|
||||
<%= if @page.page_number < @page.total_pages do %>
|
||||
<%= live_patch "Next Page >>",
|
||||
to: Routes.prompt_request_index_path(@socket, :index, page: @page.page_number + 1),
|
||||
class: "pagination-link" %>
|
||||
<% end %>
|
||||
<h3>Code: <%= if Map.get(@user, :code, nil), do: @user.code, else: "Not set" %></h3>
|
||||
<.form let={f} for={@user_changeset} phx-submit="update_user">
|
||||
<div class="form-control w-full">
|
||||
<label class="label">
|
||||
<span class="label-text">You'll need a code from Silas to use the generator.</span>
|
||||
</label>
|
||||
<%= text_input f, :code, class: "input input-bordered input-secondary" %>
|
||||
<%= error_tag f, :code %>
|
||||
<%= submit "Save Code", class: "btn" %>
|
||||
</div>
|
||||
</.form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
<div class="p-4 max-w-7xl mx-auto grid place-items-center">
|
||||
<form phx-change="search" style="width: 100%;">
|
||||
<%= text_input :search, :query, placeholder: "Search for image by prompt", "phx-debounce": "1000", class: "input w-full center-placeholder" %>
|
||||
</form>
|
||||
<div class="pt-4" style="width: 100%; text-align: center;"><%= display_current_filters(@params) %></div>
|
||||
</div>
|
||||
|
||||
<span><%= live_patch "New Prompt request", to: Routes.prompt_request_index_path(@socket, :new) %></span>
|
||||
<div class="max-w-7xl mx-auto">
|
||||
<div class="p-4 flex space-x-2 justify-center">
|
||||
<div>
|
||||
<button class="btn btn-outline btn-xs sm:btn-sm md:btn-md lg:btn-lg" style="min-height: 45px"><%= live_patch "New Prompt", to: Routes.prompt_request_index_path(@socket, :new), class: "pagination-link" %></button>
|
||||
</div>
|
||||
<div>
|
||||
<button phx-click="order_by" phx-value-votes="desc" class="btn btn-xs sm:btn-sm md:btn-md lg:btn-lg btn-outline" style="min-height: 45px;">Most Votes</button>
|
||||
</div>
|
||||
<div>
|
||||
<button phx-click="clear" class="btn btn-xs sm:btn-sm md:btn-md lg:btn-lg btn-outline" style="min-height: 45px;">Reset Filter</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-1 md:gap-4 grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
|
||||
<%= for prompt_request <- @page.entries do %>
|
||||
<div class="card w-90 bg-gray shadow-xl text-primary-content">
|
||||
<% result = if prompt_request.images |> length > 0, do: prompt_request.images |> List.first() %>
|
||||
<%= if result do %>
|
||||
<figure><img src={"#{Diffuser.Uploaders.Image.url({result.image, result})}"} /></figure>
|
||||
<% else %>
|
||||
<figure><%= prompt_request.status %>, <%= prompt_request.completed_steps %>/<%= prompt_request.steps %></figure>
|
||||
<% end %>
|
||||
<div class="card-body prose">
|
||||
<h2 class="card-title"><%= prompt_request.prompt %></h2>
|
||||
<p>Steps: <%= prompt_request.steps %>, Guidance Scale: <%= prompt_request.guidance_scale %><br />
|
||||
<%= if prompt_request.status == "finished" do %>
|
||||
<%= total_time(prompt_request) %><br />
|
||||
<% end %>
|
||||
|
||||
<%= case prompt_request.user do %>
|
||||
<%= %NotLoaded{} -> %>
|
||||
<% user -> %>
|
||||
<%= if user do %>
|
||||
Created by: <%= display_name(user) %> <%= if @is_admin, do: "(#{user.ip_address}, #{prompt_request.code})" %><br />
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
Votes: <%= prompt_request.votes |> Enum.count() %> <br />
|
||||
|
||||
<%= if has_voted(@user, prompt_request) do %>
|
||||
<% else %>
|
||||
<%= link "Upvote", to: "#", phx_click: "upvote", phx_value_id: prompt_request.id %>
|
||||
<% end %>
|
||||
|
||||
</p>
|
||||
|
||||
<%= if prompt_request.status == "finished" and (@is_admin or owns_prompt_request(@user, prompt_request)) do %>
|
||||
<div class="card-actions justify-end">
|
||||
<%= link "Delete", to: "#", phx_click: "delete", phx_value_id: prompt_request.id, data: [confirm: "Are you sure?"] %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-4 mx-auto grid place-items-center">
|
||||
<span>Total results: <%= @page.total_entries %></span>
|
||||
</div>
|
||||
|
||||
<div class="btn-group p-4 grid grid-cols-3 mx-auto pagination-btns">
|
||||
<%= if @page.total_pages > 1 do %>
|
||||
|
||||
<%= if @page.page_number > 1 do %>
|
||||
<%= link "<< Prev", to: "#", class: "btn btn-outline", phx_click: "go_to", phx_value_page: @page.page_number - 1 %>
|
||||
<% else %>
|
||||
<div class="btn btn-outline btn-disabled"></div>
|
||||
<% end %>
|
||||
|
||||
<form phx-change="go_to">
|
||||
<%= select :jump, :page, 1..@page.total_pages, class: "select w-full max-w-xs", selected: @page.page_number %>
|
||||
</form>
|
||||
|
||||
<%= if @page.page_number < @page.total_pages do %>
|
||||
<%= link "Next >>", to: "#", class: "btn btn-outline", phx_click: "go_to", phx_value_page: @page.page_number + 1 %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@@ -1,13 +1,11 @@
|
||||
defmodule DiffuserWeb.PromptRequestLive.Show do
|
||||
use DiffuserWeb, :live_view
|
||||
import Ecto.Query
|
||||
|
||||
alias Diffuser.Generator
|
||||
alias Diffuser.Generator.{Image, PromptRequest}
|
||||
alias Diffuser.Generator.PromptRequest
|
||||
alias Diffuser.Repo
|
||||
alias Phoenix.Socket.Broadcast
|
||||
alias DiffuserWeb.Endpoint
|
||||
alias Ecto.Association.NotLoaded
|
||||
|
||||
@impl true
|
||||
def mount(%{"id" => id}, _session, socket) do
|
||||
|
@@ -1,18 +1,5 @@
|
||||
<h1>Show Prompt request</h1>
|
||||
|
||||
<%= if @live_action in [:edit] do %>
|
||||
<.modal return_to={Routes.prompt_request_show_path(@socket, :show, @prompt_request)}>
|
||||
<.live_component
|
||||
module={DiffuserWeb.PromptRequestLive.FormComponent}
|
||||
id={@prompt_request.id}
|
||||
title={@page_title}
|
||||
action={@live_action}
|
||||
prompt_request={@prompt_request}
|
||||
return_to={Routes.prompt_request_show_path(@socket, :show, @prompt_request)}
|
||||
/>
|
||||
</.modal>
|
||||
<% end %>
|
||||
|
||||
<ul>
|
||||
|
||||
<li>
|
||||
@@ -42,5 +29,4 @@
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<span><%= live_patch "Edit", to: Routes.prompt_request_show_path(@socket, :edit, @prompt_request), class: "button" %></span> |
|
||||
<span><%= live_redirect "Back", to: Routes.prompt_request_index_path(@socket, :index) %></span>
|
||||
|
Reference in New Issue
Block a user