diff --git a/lib/outlook/internal_tree.ex b/lib/outlook/internal_tree.ex index 88cf60a..87a9ebb 100644 --- a/lib/outlook/internal_tree.ex +++ b/lib/outlook/internal_tree.ex @@ -1,6 +1,6 @@ defmodule Outlook.InternalTree do - alias Outlook.InternalTree.{Html,Modifiers,RawInternalBasic} + alias Outlook.InternalTree.{Html,Modifiers,RawInternalBasic,InternalTree} alias Outlook.HtmlPreparations.HtmlPreparation def render_html(tree) do @@ -26,4 +26,13 @@ defmodule Outlook.InternalTree do |> RawInternalBasic.set_split_markers() |> RawInternalBasic.partition_to_tunits() 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 diff --git a/lib/outlook/internal_tree/internal_tree.ex b/lib/outlook/internal_tree/internal_tree.ex new file mode 100644 index 0000000..cc83b96 --- /dev/null +++ b/lib/outlook/internal_tree/internal_tree.ex @@ -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 diff --git a/lib/outlook/internal_tree/translation_unit.ex b/lib/outlook/internal_tree/translation_unit.ex index e85e564..f5a36e5 100644 --- a/lib/outlook/internal_tree/translation_unit.ex +++ b/lib/outlook/internal_tree/translation_unit.ex @@ -1,4 +1,4 @@ defmodule Outlook.InternalTree.TranslationUnit do @derive Jason.Encoder - defstruct status: :atom, uuid: "", content: "" + defstruct status: :atom, uuid: "", content: "", eph: %{} end diff --git a/lib/outlook/translations/translation_units_map.ex b/lib/outlook/translations/translation_units_map.ex index 536264f..74a52be 100644 --- a/lib/outlook/translations/translation_units_map.ex +++ b/lib/outlook/translations/translation_units_map.ex @@ -23,7 +23,7 @@ defmodule Outlook.Translations.TranslationUnitsMap do def dump(tumap) when is_map(tumap) do serialized_map = for {key, val} <- tumap do - {key, Jason.encode!(val)} + {key, Jason.encode!(val |> Map.delete(:eph))} end |> Enum.into(%{}) {:ok, serialized_map} diff --git a/lib/outlook_web/components/html_doc_component.ex b/lib/outlook_web/components/html_doc_component.ex index 474e869..68c4b1e 100644 --- a/lib/outlook_web/components/html_doc_component.ex +++ b/lib/outlook_web/components/html_doc_component.ex @@ -19,15 +19,15 @@ defmodule OutlookWeb.HtmlDocComponent do def dnode(%{node: %{status: status}} = assigns) do ~H""" - + <.dynamic_tag name="span" class="tunit" uuid={@node.uuid} {Map.get(@node.eph, :attributes, %{})}> <%= @node.content |> raw %> - + """ end def dnode(assigns) when assigns.node.type == :element do ~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 %> <.dnode node={child_node} /> <% end %> diff --git a/lib/outlook_web/components/layouts/app.html.heex b/lib/outlook_web/components/layouts/app.html.heex index fa10840..679efbc 100644 --- a/lib/outlook_web/components/layouts/app.html.heex +++ b/lib/outlook_web/components/layouts/app.html.heex @@ -36,7 +36,7 @@
-
+
<.flash kind={:info} title="Success!" flash={@flash} /> <.flash kind={:error} title="Error!" flash={@flash} /> <.flash diff --git a/lib/outlook_web/components/layouts/root.html.heex b/lib/outlook_web/components/layouts/root.html.heex index 6efb609..f32ad82 100644 --- a/lib/outlook_web/components/layouts/root.html.heex +++ b/lib/outlook_web/components/layouts/root.html.heex @@ -11,7 +11,7 @@ - +
    <%= if @current_user do %>
  • diff --git a/lib/outlook_web/components/tunit_editor_component.ex b/lib/outlook_web/components/tunit_editor_component.ex index 0270b2e..e0a39e5 100644 --- a/lib/outlook_web/components/tunit_editor_component.ex +++ b/lib/outlook_web/components/tunit_editor_component.ex @@ -30,7 +30,7 @@ defmodule OutlookWeb.TunitEditorComponent do <%= @current_tunit.content |> raw %>
--%>
- +
diff --git a/lib/outlook_web/live/translation_live/form_component.ex b/lib/outlook_web/live/translation_live/form_component.ex index e8cde72..b37aac8 100644 --- a/lib/outlook_web/live/translation_live/form_component.ex +++ b/lib/outlook_web/live/translation_live/form_component.ex @@ -7,8 +7,8 @@ defmodule OutlookWeb.TranslationLive.FormComponent do @impl true def render(assigns) do ~H""" -
-
+
+
<.header> <%= @title %> <:subtitle>Use this form to manage translation records in your database. @@ -29,19 +29,21 @@ defmodule OutlookWeb.TranslationLive.FormComponent do <.input field={{f, :teaser}} type="textarea" label="teaser" class="h-28" /> <%!-- <.input field={{f, :content}} type="text" label="content" /> --%> <.input field={{f, :date}} type="datetime-local" label="date" /> - <.input field={{f, :public}} type="checkbox" label="public" /> - <.input field={{f, :unauthorized}} type="checkbox" label="unauthorized" /> +
+ <.input field={{f, :public}} type="checkbox" label="public" /> + <.input field={{f, :unauthorized}} type="checkbox" label="unauthorized" /> +
<:actions> <.button phx-disable-with="Saving...">Save Translation <.tunit_editor current_tunit={@current_tunit} 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 - <.render_doc tree={@translation.article.content} /> + <.render_doc tree={@article_tree} />
""" @@ -56,6 +58,7 @@ defmodule OutlookWeb.TranslationLive.FormComponent do |> assign(assigns) |> assign(:current_tunit, nil) |> assign(:changeset, changeset) + |> assign_article_tree(translation) |> assign(:deepl_progress, nil)} end @@ -125,6 +128,14 @@ defmodule OutlookWeb.TranslationLive.FormComponent do end 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 translation_content = if socket.assigns.current_tunit do socket.assigns.translation_content diff --git a/lib/outlook_web/live/translation_live/new_edit.ex b/lib/outlook_web/live/translation_live/new_edit.ex index 8961456..8959f35 100644 --- a/lib/outlook_web/live/translation_live/new_edit.ex +++ b/lib/outlook_web/live/translation_live/new_edit.ex @@ -11,9 +11,9 @@ defmodule OutlookWeb.TranslationLive.NewEdit do def render(assigns) do ~H""" <.live_component - module={OutlookWeb.TranslationLive.FormComponent} + module={FormComponent} id={@form_cmpnt_id} - title="New Translation" + title={@page_title} action={@live_action} translation={@translation} translation_content={@translation_content} @@ -62,4 +62,7 @@ defmodule OutlookWeb.TranslationLive.NewEdit do send_update(self(), FormComponent, deepl_translation: payload, id: @form_cmpnt_id) {:noreply, socket} end + + defp page_title(:new), do: "New Translation" + defp page_title(:edit), do: "Edit Translation" end