Update editing translation
This commit is contained in:
@ -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
|
||||||
|
|||||||
70
lib/outlook/internal_tree/internal_tree.ex
Normal file
70
lib/outlook/internal_tree/internal_tree.ex
Normal 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
|
||||||
@ -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
|
||||||
|
|||||||
@ -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}
|
||||||
|
|||||||
@ -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 %>
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
@ -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">
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user