medicode / lib /medicode_web /components /transcription_text_component.ex
timgremore's picture
chore: Move audio recording state to sidebar button
6ee6b5e
defmodule MedicodeWeb.Components.TranscriptionTextComponent do
@moduledoc """
Represents a portion of transcribed text.
"""
use MedicodeWeb, :live_component
import MedicodeWeb.Components.KeywordHighlighter
alias Medicode.Transcriptions
alias MedicodeWeb.Components.CodeSelect
alias MedicodeWeb.Components.TranscriptionTextCodingsComponent
@impl Phoenix.LiveComponent
def mount(socket) do
{:ok, assign(socket, :code_vectors, [])}
end
@impl Phoenix.LiveComponent
def update_many(assigns_sockets) do
list_of_ids = Enum.map(assigns_sockets, fn {assigns, _sockets} -> assigns.chunk_id end)
chunks =
list_of_ids
|> Transcriptions.list_transcription_chunks()
|> Map.new()
Enum.map(assigns_sockets, fn {assigns, socket} ->
chunk = chunks[assigns.chunk_id]
socket
|> assign(:id, assigns.id)
|> assign(:current_user, assigns.current_user)
|> assign(:chunk, chunk)
|> assign(:on_feedback, assigns.on_feedback)
|> assign(:on_remove_code, assigns.on_remove_code)
|> assign(:on_finalize_code, assigns.on_finalize_code)
end)
end
@impl Phoenix.LiveComponent
def render(assigns) do
assigns =
assigns
|> assign_new(:classification_loading, fn ->
# NOTE: This assumes that if a process matches by transcription chunk ID that
# the chunk is in the process of loading. Specific state inspection could happen
# with the :sys module (ie :sys.get_state/1)
# case Registry.lookup({:via, :gproc, {:n, :l, {:transcription, transcription_id}}}) do
case [] do
[] -> false
[{_pid, _}] -> true
end
end)
# TODO: Adjust the blue border when editing
~H"""
<div id={@id} class="flex gap-12 py-12 border-b border-[#444444]/20">
<div class="flex-1 flex flex-col gap-4 w-1/2">
<p
:if={!is_nil(@chunk.start_mark) && !is_nil(@chunk.end_mark)}
class="px-2 text-[32px] leading-normal font-semibold"
>
<%= @chunk.start_mark %> - <%= @chunk.end_mark %>
</p>
<div class="flex-1 w-full text-[28px] leading-normal text-type-black-tertiary">
<!-- <p class="h-full min-h-full rounded p-2"><%= @chunk.text %></p> -->
<p
id={"#{@id}-transcription-text"}
contenteditable
role="textbox"
class="rounded p-2"
phx-hook="ContentEditor"
phx-target={@myself}
phx-event-name="reclassify_transcription"
>
<.highlight text={@chunk.text} keywords={@chunk.keywords} />
</p>
</div>
</div>
<div class="flex-1 flex flex-col items-stretch gap-3">
<img
:if={@classification_loading}
src={~p"/images/loading.svg"}
width="36"
class="m-4 animate-spin"
/>
<.live_component
module={TranscriptionTextCodingsComponent}
id={"#{@id}-codings"}
chunk_id={@chunk.id}
text={@chunk.text}
current_user={@current_user}
on_feedback={@on_feedback}
on_remove_code={@on_remove_code}
on_finalize_code={@on_finalize_code}
/>
<.live_component
:if={!@classification_loading}
module={CodeSelect}
id={"#{@id}-code-select"}
text={@chunk.text}
current_user={@current_user}
chunk={@chunk}
/>
</div>
</div>
"""
end
@impl Phoenix.LiveComponent
def handle_event("reclassify_transcription", %{"value" => new_chunk_text} = _params, socket) do
new_chunk_text_trimmed = String.trim(new_chunk_text)
if socket.assigns.chunk.text == new_chunk_text_trimmed do
{:noreply, socket}
else
{:ok, chunk} =
Transcriptions.update_transcription_chunk(socket.assigns.chunk, %{
text: new_chunk_text_trimmed,
text_vector: Medicode.Coding.compute_vector_as_list(new_chunk_text_trimmed)
})
Medicode.ClassificationSupervisor.start_classification(chunk)
{:noreply, assign(socket, :chunk, chunk)}
end
end
end