Compare commits

...

3 Commits

Author SHA1 Message Date
7990b74bf0 Add "Unite with next" button 2023-05-02 22:09:04 +02:00
4a8f1c3c80 Update add_phx_click_event making :target option optional 2023-05-02 21:59:27 +02:00
7e085f5202 Update layout 2023-03-30 14:31:10 +02:00
11 changed files with 103 additions and 55 deletions

View File

@ -9,13 +9,17 @@
.article span.tunit {
@apply hover:bg-gray-300;
padding: 5px 0;
margin: -5px 0;
}
.dark .article span.tunit {
@apply hover:bg-gray-700;
padding: 5px 0;
margin: -5px 0;
}
.article span.tunit[current="yes"] {
.article span.tunit[current="yes"], .article span.tunit[selected="yes"] {
@apply bg-amber-300 text-stone-700 hover:bg-amber-200 hover:text-red-900;
}

View File

@ -26,9 +26,12 @@ defmodule Outlook.InternalTree do
def add_phx_click_event(tree, opts) do
phx_opts = %{
"phx-click": Keyword.get(opts, :click),
"phx-target": Keyword.get(opts, :target) |> to_string,
"phx-value-nid": fn n -> n.nid end
}
phx_opts = case Keyword.has_key?(opts, :target) do
true -> Map.put(phx_opts, "phx-target", Keyword.get(opts, :target) |> to_string)
false -> phx_opts
end
options = Map.put(%{}, Keyword.get(opts, :nodes, :elements), phx_opts)
garnish(tree, options)
end
@ -74,4 +77,8 @@ defmodule Outlook.InternalTree do
def modify_tunits(tree, modifier, tu_ids) do
TunitModifications.apply_modifier(tree, modifier, tu_ids)
end
def tunit_modifiers() do
TunitModifications.modifiers()
end
end

View File

@ -8,14 +8,14 @@ defmodule Outlook.InternalTree.TunitModifications do
name: "unite_with_next",
fn: &unite_with_next/2,
label: "Unite with next",
description: "unite translation unit with next"
description: "unite selected translation unit with (unselected) next"
},
%{
name: "split_tunit",
fn: &split_tunit/2,
label: "Split Translation unit",
description: "split translation unit into two"
}
# %{
# name: "split_tunit",
# fn: &split_tunit/2,
# label: "Split Translation unit",
# description: "split translation unit into two"
# }
]
end

View File

@ -41,7 +41,7 @@ defmodule OutlookWeb.DarkModeComponent do
def breakpoint_indicator(assigns) do
~H"""
<div class="absolute p-1 bg-white text-black dark:bg-black dark:text-white">
<div class="absolute mt-5 ml-40 bg-white text-black dark:bg-black dark:text-white">
<span class="sm:hidden">xs</span>
<span class="hidden sm:inline md:hidden">sm</span>
<span class="hidden md:inline lg:hidden">md</span>

View File

@ -1,43 +1,9 @@
<header class="px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between border-b border-zinc-100 py-3">
<div class="flex items-center gap-4">
<a href="/">
<svg viewBox="0 0 71 48" class="h-6" aria-hidden="true">
<path
d="m26.371 33.477-.552-.1c-3.92-.729-6.397-3.1-7.57-6.829-.733-2.324.597-4.035 3.035-4.148 1.995-.092 3.362 1.055 4.57 2.39 1.557 1.72 2.984 3.558 4.514 5.305 2.202 2.515 4.797 4.134 8.347 3.634 3.183-.448 5.958-1.725 8.371-3.828.363-.316.761-.592 1.144-.886l-.241-.284c-2.027.63-4.093.841-6.205.735-3.195-.16-6.24-.828-8.964-2.582-2.486-1.601-4.319-3.746-5.19-6.611-.704-2.315.736-3.934 3.135-3.6.948.133 1.746.56 2.463 1.165.583.493 1.143 1.015 1.738 1.493 2.8 2.25 6.712 2.375 10.265-.068-5.842-.026-9.817-3.24-13.308-7.313-1.366-1.594-2.7-3.216-4.095-4.785-2.698-3.036-5.692-5.71-9.79-6.623C12.8-.623 7.745.14 2.893 2.361 1.926 2.804.997 3.319 0 4.149c.494 0 .763.006 1.032 0 2.446-.064 4.28 1.023 5.602 3.024.962 1.457 1.415 3.104 1.761 4.798.513 2.515.247 5.078.544 7.605.761 6.494 4.08 11.026 10.26 13.346 2.267.852 4.591 1.135 7.172.555ZM10.751 3.852c-.976.246-1.756-.148-2.56-.962 1.377-.343 2.592-.476 3.897-.528-.107.848-.607 1.306-1.336 1.49Zm32.002 37.924c-.085-.626-.62-.901-1.04-1.228-1.857-1.446-4.03-1.958-6.333-2-1.375-.026-2.735-.128-4.031-.61-.595-.22-1.26-.505-1.244-1.272.015-.78.693-1 1.31-1.184.505-.15 1.026-.247 1.6-.382-1.46-.936-2.886-1.065-4.787-.3-2.993 1.202-5.943 1.06-8.926-.017-1.684-.608-3.179-1.563-4.735-2.408l-.043.03a2.96 2.96 0 0 0 .04-.029c-.038-.117-.107-.12-.197-.054l.122.107c1.29 2.115 3.034 3.817 5.004 5.271 3.793 2.8 7.936 4.471 12.784 3.73A66.714 66.714 0 0 1 37 40.877c1.98-.16 3.866.398 5.753.899Zm-9.14-30.345c-.105-.076-.206-.266-.42-.069 1.745 2.36 3.985 4.098 6.683 5.193 4.354 1.767 8.773 2.07 13.293.51 3.51-1.21 6.033-.028 7.343 3.38.19-3.955-2.137-6.837-5.843-7.401-2.084-.318-4.01.373-5.962.94-5.434 1.575-10.485.798-15.094-2.553Zm27.085 15.425c.708.059 1.416.123 2.124.185-1.6-1.405-3.55-1.517-5.523-1.404-3.003.17-5.167 1.903-7.14 3.972-1.739 1.824-3.31 3.87-5.903 4.604.043.078.054.117.066.117.35.005.699.021 1.047.005 3.768-.17 7.317-.965 10.14-3.7.89-.86 1.685-1.817 2.544-2.71.716-.746 1.584-1.159 2.645-1.07Zm-8.753-4.67c-2.812.246-5.254 1.409-7.548 2.943-1.766 1.18-3.654 1.738-5.776 1.37-.374-.066-.75-.114-1.124-.17l-.013.156c.135.07.265.151.405.207.354.14.702.308 1.07.395 4.083.971 7.992.474 11.516-1.803 2.221-1.435 4.521-1.707 7.013-1.336.252.038.503.083.756.107.234.022.479.255.795.003-2.179-1.574-4.526-2.096-7.094-1.872Zm-10.049-9.544c1.475.051 2.943-.142 4.486-1.059-.452.04-.643.04-.827.076-2.126.424-4.033-.04-5.733-1.383-.623-.493-1.257-.974-1.889-1.457-2.503-1.914-5.374-2.555-8.514-2.5.05.154.054.26.108.315 3.417 3.455 7.371 5.836 12.369 6.008Zm24.727 17.731c-2.114-2.097-4.952-2.367-7.578-.537 1.738.078 3.043.632 4.101 1.728.374.388.763.768 1.182 1.106 1.6 1.29 4.311 1.352 5.896.155-1.861-.726-1.861-.726-3.601-2.452Zm-21.058 16.06c-1.858-3.46-4.981-4.24-8.59-4.008a9.667 9.667 0 0 1 2.977 1.39c.84.586 1.547 1.311 2.243 2.055 1.38 1.473 3.534 2.376 4.962 2.07-.656-.412-1.238-.848-1.592-1.507Zm17.29-19.32c0-.023.001-.045.003-.068l-.006.006.006-.006-.036-.004.021.018.012.053Zm-20 14.744a7.61 7.61 0 0 0-.072-.041.127.127 0 0 0 .015.043c.005.008.038 0 .058-.002Zm-.072-.041-.008-.034-.008.01.008-.01-.022-.006.005.026.024.014Z"
fill="#FD4F00"
/>
</svg>
</a>
<p class="rounded-full bg-brand/5 px-2 text-[0.8125rem] font-medium leading-6 text-brand">
v1.7
</p>
</div>
<div class="flex items-center gap-4">
<a
href="https://twitter.com/elixirphoenix"
class="text-[0.8125rem] font-semibold leading-6 text-zinc-900 hover:text-zinc-700"
>
@elixirphoenix
</a>
<a
href="https://github.com/phoenixframework/phoenix"
class="text-[0.8125rem] font-semibold leading-6 text-zinc-900 hover:text-zinc-700"
>
GitHub
</a>
<a
href="https://hexdocs.pm/phoenix/overview.html"
class="rounded-lg bg-zinc-100 px-2 py-1 text-[0.8125rem] font-semibold leading-6 text-zinc-900 hover:bg-zinc-200/80 active:text-zinc-900/70"
>
Get Started <span aria-hidden="true">&rarr;</span>
</a>
</div>
</div>
<header class="">
<.breakpoint_indicator :if={Mix.env == :dev} />
<.dark_mode_widget />
</header>
<main class="px-4 py-20 sm:px-6 lg:px-8">
<div class="mx-auto max-w-4xl">
<main class="px-4 sm:px-6 lg:px-8 lg:mx-auto h-screen">
<div class="mx-auto max-w-4xl h-fit">
<.flash kind={:info} title="Success!" flash={@flash} />
<.flash kind={:error} title="Error!" flash={@flash} />
<.flash

View File

@ -13,7 +13,7 @@
</script>
</head>
<body class="bg-white text-stone-900 dark:bg-stone-900 dark:text-stone-100 antialiased max-h-screen">
<ul>
<ul class="absolute">
<%= if @current_user do %>
<li>
<%= @current_user.email %>

View File

@ -9,12 +9,12 @@ defmodule OutlookWeb.TunitEditorComponent do
def tunit_editor(assigns) do
~H"""
<div id="translation-unit-editor" phx-nohook="tunit_editor">
<div id="translation-unit-editor" phx-no-hook="tunit_editor" phx-target={@target}>
<%!-- <div class="h-48 p-2 border border-slate-500 rounded" contenteditable phx-no-change="update_current_tunit">
<%= @current_tunit.content |> raw %>
</div> --%>
<form phx-change="update_current_tunit" phx-target={@target}>
<textarea id="tunit-editor-content" name="content" class="h-48 rounded border-slate-500 resize-none bg-transparent w-full"
<textarea id="tunit-editor-content" name="content" class="h-96 rounded border-slate-500 resize-none bg-transparent w-full"
disabled={!@current_tunit.status}><%= @current_tunit.content %></textarea>
</form>
<.status_selector target={@target} disabled={!@current_tunit.status} tunit={@current_tunit} />
@ -24,7 +24,7 @@ defmodule OutlookWeb.TunitEditorComponent do
defp statuses() do
[ {:untranslated, "bg-red-800"},
{:passable, "bg-amber-500"},
{:passable, "bg-amber-500/70"},
{:done, "bg-green-700"} ]
end

View File

@ -0,0 +1,24 @@
defmodule OutlookWeb.ArticleLive.MenuComponent do
use OutlookWeb, :live_component
attr :entries, :list
# attr :target, :integer, default: 0 # @myself of the Live(View|Component) where the handlers reside
attr :handler, :string
@impl true
def render(assigns) do
~H"""
<div>
<.menu_item :for={entry <- @entries} entry={entry} handler={@handler} />
</div>
"""
end
def menu_item(assigns) do
~H"""
<div title={@entry.description} phx-click={@handler} phx-value-modifier={@entry.name}>
<%= @entry.label %>
</div>
"""
end
end

View File

@ -17,6 +17,7 @@ defmodule OutlookWeb.ArticleLive.New do
|> assign(:raw_html_input, %RawHtmlInput{})
|> assign(:changeset, Articles.change_raw_html_input(%RawHtmlInput{}))
|> assign(:selected_els, [])
|> assign(:selected_tunits, [])
|> assign(:step, :import_raw_html)}
end
@ -26,6 +27,7 @@ defmodule OutlookWeb.ArticleLive.New do
article = %Article{author_id: author.id}
{:noreply,
socket
|> assign(:menu_entries, InternalTree.tunit_modifiers()) # REMOVE ME!
|> assign(:author, author)
|> assign(:article, article)}
end
@ -43,7 +45,9 @@ defmodule OutlookWeb.ArticleLive.New do
{:noreply,
socket
|> assign(:raw_internal_tree,
HtmlPreparations.convert_raw_html_input(raw_html_input_params["content"]))
HtmlPreparations.convert_raw_html_input(raw_html_input_params["content"])
|> InternalTree.garnish(%{})
)
|> assign(:step, :review_raw_internaltree)}
false ->
{:noreply, assign(socket, :changeset, changeset)}
@ -54,10 +58,42 @@ defmodule OutlookWeb.ArticleLive.New do
def handle_event("approve_raw_internaltree", _, socket) do
socket = socket
|> assign(:raw_internal_tree,
InternalTree.partition_text(socket.assigns.raw_internal_tree))
InternalTree.partition_text(socket.assigns.raw_internal_tree)
|> InternalTree.garnish(%{tunits: %{class: :tunit}})
|> InternalTree.add_phx_click_event(
nodes: :tunits,
click: "toggle_selected_tunit")
)
|> assign(:menu_entries, InternalTree.tunit_modifiers())
{:noreply, socket |> assign(:step, :review_translation_units)}
end
@impl true
def handle_event("toggle_selected_tunit", %{"nid" => tunit_id}, socket) do
{:noreply, toggle_selected_tunit(socket, tunit_id)}
end
defp toggle_selected_tunit(socket, tunit_id) do
before = socket.assigns.selected_tunits
selected_tunits = case Enum.member?(before, tunit_id) do
false -> List.insert_at(before, -1, tunit_id)
true -> List.delete(before, tunit_id)
end
fun = fn n -> n.nid in selected_tunits && "yes" || "no" end
socket
|> assign(:raw_internal_tree, InternalTree.garnish(socket.assigns.raw_internal_tree, %{tunits: %{selected: fun}}))
|> assign(:selected_tunits, selected_tunits)
end
@impl true
def handle_event("modify_tunits", %{"modifier" => modifier}, socket) do
{:noreply,
socket
|> assign(:raw_internal_tree,
InternalTree.modify_tunits(socket.assigns.raw_internal_tree, modifier, socket.assigns.selected_tunits)
)}
end
@impl true
def handle_event("approve_translation_units", _, socket) do
{:noreply, socket |> assign(:step, :final_form)}

View File

@ -4,7 +4,7 @@
<.import_raw_html :if={@step == :import_raw_html} changeset={@changeset} />
<.review_raw_internaltree :if={@step == :review_raw_internaltree} raw_internal_tree={@raw_internal_tree} />
<.review_translation_units :if={@step == :review_translation_units} />
<.review_translation_units :if={@step == :review_translation_units} raw_internal_tree={@raw_internal_tree} menu_entries={@menu_entries} />
<.live_component
:if={@step == :final_form}
module={OutlookWeb.ArticleLive.FormComponent}

View File

@ -44,6 +44,17 @@ defmodule OutlookWeb.ArticleLive.NewComponents do
def review_translation_units(assigns) do
~H"""
<div>Review Translation Units</div>
<div class="flex gap-4">
<div id="html-tree" class="w-96 overflow-auto whitespace-nowrap">
<.render_tree tree={@raw_internal_tree} ></.render_tree>
</div>
<div id="partition-preview" class="article show-boundary overflow-auto h-full">
<.render_doc tree={@raw_internal_tree} ></.render_doc>
</div>
<div>
<.live_component module={OutlookWeb.ArticleLive.MenuComponent} entries={@menu_entries} handler="modify_tunits" id={:review_tunits} />
</div>
</div>
<.button phx-click="approve_translation_units">Continue</.button>
"""
end