Update editing translation

This commit is contained in:
Thelonius Kort
2023-01-09 21:35:35 +01:00
parent 71e6a8da60
commit 33ed533a1a
10 changed files with 111 additions and 18 deletions

View File

@ -1,6 +1,6 @@
defmodule Outlook.InternalTree do defmodule Outlook.InternalTree do
alias Outlook.InternalTree.{Html,Modifiers,RawInternalBasic} alias Outlook.InternalTree.{Html,Modifiers,RawInternalBasic,InternalTree}
alias Outlook.HtmlPreparations.HtmlPreparation alias Outlook.HtmlPreparations.HtmlPreparation
def render_html(tree) do def render_html(tree) do
@ -26,4 +26,13 @@ defmodule Outlook.InternalTree do
|> RawInternalBasic.set_split_markers() |> RawInternalBasic.set_split_markers()
|> RawInternalBasic.partition_to_tunits() |> RawInternalBasic.partition_to_tunits()
end end
def garnish(tree, options) do
options = Enum.reduce(
~w(el_ids el_names tu_ids)a,
options,
fn prop, opts -> Map.put_new(opts, prop, []) end
)
InternalTree.garnish(tree, options)
end
end end

View File

@ -0,0 +1,70 @@
defmodule Outlook.InternalTree.InternalTree do
alias Outlook.InternalTree.InternalNode
alias Outlook.InternalTree.TranslationUnit
def garnish([%TranslationUnit{} = node | rest], %{tunits: _} = options) do
[ set_attributes(node, options.tunits, options.tu_ids)
| garnish(rest, options) ]
end
def garnish([%TranslationUnit{} = node | rest], options) do
[ node | garnish(rest, options) ]
end
def garnish([%InternalNode{type: :element} = node | rest], %{elements: _} = options) do
node = set_attributes(node, options.elements, options.el_ids, options.el_names)
[ %InternalNode{node |
content: garnish(node.content, options)
} | garnish(rest, options) ]
end
def garnish([%InternalNode{type: :element} = node | rest], options) do
[ %InternalNode{node |
content: garnish(node.content, options)
} | garnish(rest, options) ]
end
def garnish([node | rest], options) do
[ node | garnish(rest, options) ]
end
def garnish([], _), do: []
defp set_attributes(node, atts, ids, []) do
set_attributes(node, atts, ids)
end
defp set_attributes(node, atts, ids, names) do
if node.name in names do
set_attributes(node, atts, [])
else
set_attributes(node, atts, ids)
end
end
defp set_attributes(node, atts, []) do
set_attributes(node, atts)
end
defp set_attributes(node, atts, ids) do
if node.uuid in ids do
set_attributes(node, atts)
else
node
end
end
defp set_attributes(node, atts) do
attributes = Map.get(atts, :atts, %{})
attributes = if Map.has_key?(atts, :phx) do
# TODO: for all keys in atts.phx create a respective entry
Map.put(attributes, "phx-click",atts.phx.click)
# TODO: only convert to string if present
|> Map.put("phx-target", atts.phx.target |> to_string)
|> Map.put("phx-value-uuid", node.uuid)
end
%{node | eph: Map.put(node.eph, :attributes, attributes)}
end
end

View File

@ -1,4 +1,4 @@
defmodule Outlook.InternalTree.TranslationUnit do defmodule Outlook.InternalTree.TranslationUnit do
@derive Jason.Encoder @derive Jason.Encoder
defstruct status: :atom, uuid: "", content: "" defstruct status: :atom, uuid: "", content: "", eph: %{}
end end

View File

@ -23,7 +23,7 @@ defmodule Outlook.Translations.TranslationUnitsMap do
def dump(tumap) when is_map(tumap) do def dump(tumap) when is_map(tumap) do
serialized_map = for {key, val} <- tumap do serialized_map = for {key, val} <- tumap do
{key, Jason.encode!(val)} {key, Jason.encode!(val |> Map.delete(:eph))}
end end
|> Enum.into(%{}) |> Enum.into(%{})
{:ok, serialized_map} {:ok, serialized_map}

View File

@ -19,15 +19,15 @@ defmodule OutlookWeb.HtmlDocComponent do
def dnode(%{node: %{status: status}} = assigns) do def dnode(%{node: %{status: status}} = assigns) do
~H""" ~H"""
<span class="tunit" uuid={@node.uuid}> <.dynamic_tag name="span" class="tunit" uuid={@node.uuid} {Map.get(@node.eph, :attributes, %{})}>
<%= @node.content |> raw %> <%= @node.content |> raw %>
</span> </.dynamic_tag>
""" """
end end
def dnode(assigns) when assigns.node.type == :element do def dnode(assigns) when assigns.node.type == :element do
~H""" ~H"""
<.dynamic_tag name={@node.name} uuid={@node.uuid}> <.dynamic_tag name={@node.name} uuid={@node.uuid} {Map.get(@node.eph, :attributes, %{})}>
<%= for child_node <- @node.content do %> <%= for child_node <- @node.content do %>
<.dnode node={child_node} /> <.dnode node={child_node} />
<% end %> <% end %>

View File

@ -36,7 +36,7 @@
</div> </div>
</header> </header>
<main class="px-4 py-20 sm:px-6 lg:px-8"> <main class="px-4 py-20 sm:px-6 lg:px-8">
<div class="mx-auto max-w-2xl"> <div class="mx-auto max-w-4xl">
<.flash kind={:info} title="Success!" flash={@flash} /> <.flash kind={:info} title="Success!" flash={@flash} />
<.flash kind={:error} title="Error!" flash={@flash} /> <.flash kind={:error} title="Error!" flash={@flash} />
<.flash <.flash

View File

@ -11,7 +11,7 @@
<script defer phx-track-static type="text/javascript" src={~p"/assets/app.js"}> <script defer phx-track-static type="text/javascript" src={~p"/assets/app.js"}>
</script> </script>
</head> </head>
<body class="bg-white antialiased"> <body class="bg-white antialiased max-h-screen">
<ul> <ul>
<%= if @current_user do %> <%= if @current_user do %>
<li> <li>

View File

@ -30,7 +30,7 @@ defmodule OutlookWeb.TunitEditorComponent do
<%= @current_tunit.content |> raw %> <%= @current_tunit.content |> raw %>
</div> --%> </div> --%>
<form phx-change="update_current_tunit" phx-target={@target} disabled={@disabled}> <form phx-change="update_current_tunit" phx-target={@target} disabled={@disabled}>
<textarea name="content" class="h-48 rounded border-slate-500 resize-none"><%= @current_tunit.content %></textarea> <textarea name="content" class="h-48 rounded border-slate-500 resize-none w-full"><%= @current_tunit.content %></textarea>
</form> </form>
</div> </div>
<div class="grid grid-cols-scheise gap-3"> <div class="grid grid-cols-scheise gap-3">

View File

@ -7,8 +7,8 @@ defmodule OutlookWeb.TranslationLive.FormComponent do
@impl true @impl true
def render(assigns) do def render(assigns) do
~H""" ~H"""
<div class="flex"> <div class="flex gap-8 max-h-fit">
<div> <div class="basis-1/2 overflow-auto">
<.header> <.header>
<%= @title %> <%= @title %>
<:subtitle>Use this form to manage translation records in your database.</:subtitle> <:subtitle>Use this form to manage translation records in your database.</:subtitle>
@ -29,19 +29,21 @@ defmodule OutlookWeb.TranslationLive.FormComponent do
<.input field={{f, :teaser}} type="textarea" label="teaser" class="h-28" /> <.input field={{f, :teaser}} type="textarea" label="teaser" class="h-28" />
<%!-- <.input field={{f, :content}} type="text" label="content" /> --%> <%!-- <.input field={{f, :content}} type="text" label="content" /> --%>
<.input field={{f, :date}} type="datetime-local" label="date" /> <.input field={{f, :date}} type="datetime-local" label="date" />
<.input field={{f, :public}} type="checkbox" label="public" /> <div class="flex items-center justify-between">
<.input field={{f, :unauthorized}} type="checkbox" label="unauthorized" /> <.input field={{f, :public}} type="checkbox" label="public" />
<.input field={{f, :unauthorized}} type="checkbox" label="unauthorized" />
</div>
<:actions> <:actions>
<.button phx-disable-with="Saving...">Save Translation</.button> <.button phx-disable-with="Saving...">Save Translation</.button>
</:actions> </:actions>
</.simple_form> </.simple_form>
<.tunit_editor current_tunit={@current_tunit} target={@myself} /> <.tunit_editor current_tunit={@current_tunit} target={@myself} />
</div> </div>
<div class="article"> <div class="article basis-1/2 overflow-auto">
<.button phx-disable-with="Translating..." phx-click="translate-deepl" phx-target={@myself} <.button phx-disable-with="Translating..." phx-click="translate-deepl" phx-target={@myself}
data-confirm-not="Are you sure? All previously translated text will be lost.">Translate with Deepl</.button> data-confirm-not="Are you sure? All previously translated text will be lost.">Translate with Deepl</.button>
<progress :if={@deepl_progress} max="100" value={@deepl_progress} /> <progress :if={@deepl_progress} max="100" value={@deepl_progress} />
<.render_doc tree={@translation.article.content} /> <.render_doc tree={@article_tree} />
</div> </div>
</div> </div>
""" """
@ -56,6 +58,7 @@ defmodule OutlookWeb.TranslationLive.FormComponent do
|> assign(assigns) |> assign(assigns)
|> assign(:current_tunit, nil) |> assign(:current_tunit, nil)
|> assign(:changeset, changeset) |> assign(:changeset, changeset)
|> assign_article_tree(translation)
|> assign(:deepl_progress, nil)} |> assign(:deepl_progress, nil)}
end end
@ -125,6 +128,14 @@ defmodule OutlookWeb.TranslationLive.FormComponent do
end end
defp update_current_tunit(socket), do: socket defp update_current_tunit(socket), do: socket
defp assign_article_tree(socket, translation) do
socket
|> assign(
:article_tree,
InternalTree.garnish(translation.article.content,
%{tunits: %{phx: %{click: "select_current_tunit", target: socket.assigns.myself}}}))
end
defp update_translation_with_current_tunit(socket) do defp update_translation_with_current_tunit(socket) do
translation_content = if socket.assigns.current_tunit do translation_content = if socket.assigns.current_tunit do
socket.assigns.translation_content socket.assigns.translation_content

View File

@ -11,9 +11,9 @@ defmodule OutlookWeb.TranslationLive.NewEdit do
def render(assigns) do def render(assigns) do
~H""" ~H"""
<.live_component <.live_component
module={OutlookWeb.TranslationLive.FormComponent} module={FormComponent}
id={@form_cmpnt_id} id={@form_cmpnt_id}
title="New Translation" title={@page_title}
action={@live_action} action={@live_action}
translation={@translation} translation={@translation}
translation_content={@translation_content} translation_content={@translation_content}
@ -62,4 +62,7 @@ defmodule OutlookWeb.TranslationLive.NewEdit do
send_update(self(), FormComponent, deepl_translation: payload, id: @form_cmpnt_id) send_update(self(), FormComponent, deepl_translation: payload, id: @form_cmpnt_id)
{:noreply, socket} {:noreply, socket}
end end
defp page_title(:new), do: "New Translation"
defp page_title(:edit), do: "Edit Translation"
end end