|
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 -> |
|
|
|
|
|
|
|
|
|
case [] do |
|
[] -> false |
|
[{_pid, _}] -> true |
|
end |
|
end) |
|
|
|
|
|
~H""" |
|
<div id={@id} class="flex gap-12 py-12 border-b border-[ |
|
<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 |
|
|