fix: quick action translate and validate apply now use tasks
This commit is contained in:
@@ -262,6 +262,30 @@ defmodule BDS.Desktop.ShellCommands do
|
|||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp dispatch("apply_site_validation", project, params) do
|
||||||
|
report = normalize_apply_validation_report(BDS.MapUtils.attr(params, :report, %{}))
|
||||||
|
|
||||||
|
queue_task(
|
||||||
|
project,
|
||||||
|
"apply_site_validation",
|
||||||
|
"Apply Site Validation",
|
||||||
|
"Generation",
|
||||||
|
fn report_fn ->
|
||||||
|
{:ok, _apply} =
|
||||||
|
Generation.apply_validation(project.id, report,
|
||||||
|
on_progress: scaled_progress_reporter(report_fn, 0.0, 0.85)
|
||||||
|
)
|
||||||
|
|
||||||
|
{:ok, validation} =
|
||||||
|
Generation.validate_site(project.id, @site_sections,
|
||||||
|
on_progress: scaled_progress_reporter(report_fn, 0.85, 1.0)
|
||||||
|
)
|
||||||
|
|
||||||
|
site_validation_result(project.id, validation)
|
||||||
|
end
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
defp dispatch("metadata_diff", project, _params) do
|
defp dispatch("metadata_diff", project, _params) do
|
||||||
queue_task(project, "metadata_diff", "Metadata Diff", "Maintenance", fn report ->
|
queue_task(project, "metadata_diff", "Metadata Diff", "Maintenance", fn report ->
|
||||||
{:ok, metadata_diff} = Maintenance.metadata_diff(project.id, on_progress: report)
|
{:ok, metadata_diff} = Maintenance.metadata_diff(project.id, on_progress: report)
|
||||||
@@ -640,6 +664,20 @@ defmodule BDS.Desktop.ShellCommands do
|
|||||||
"http://#{server.host}:#{server.port}/"
|
"http://#{server.host}:#{server.port}/"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp normalize_apply_validation_report(report) when is_map(report) do
|
||||||
|
%{
|
||||||
|
sitemap_path: BDS.MapUtils.attr(report, :sitemap_path),
|
||||||
|
sitemap_changed: BDS.MapUtils.attr(report, :sitemap_changed, false),
|
||||||
|
missing_url_paths: BDS.MapUtils.attr(report, :missing_url_paths, []),
|
||||||
|
extra_url_paths: BDS.MapUtils.attr(report, :extra_url_paths, []),
|
||||||
|
updated_post_url_paths: BDS.MapUtils.attr(report, :updated_post_url_paths, []),
|
||||||
|
expected_url_count: BDS.MapUtils.attr(report, :expected_url_count, 0),
|
||||||
|
existing_html_url_count: BDS.MapUtils.attr(report, :existing_html_url_count, 0)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp normalize_apply_validation_report(_report), do: %{}
|
||||||
|
|
||||||
defp normalize_site_validation(report) do
|
defp normalize_site_validation(report) do
|
||||||
%{
|
%{
|
||||||
sitemap_path: report.sitemap_path,
|
sitemap_path: report.sitemap_path,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ defmodule BDS.Desktop.ShellLive.Bridges do
|
|||||||
import Phoenix.LiveView, only: [connected?: 1, send_update: 2]
|
import Phoenix.LiveView, only: [connected?: 1, send_update: 2]
|
||||||
|
|
||||||
alias BDS.Desktop.ShellData
|
alias BDS.Desktop.ShellData
|
||||||
alias BDS.Desktop.ShellLive.{ChatEditor, PostEditor}
|
alias BDS.Desktop.ShellLive.{ChatEditor, MediaEditor, PostEditor}
|
||||||
alias BDS.Desktop.ShellLive.{CliSync, SessionUtil}
|
alias BDS.Desktop.ShellLive.{CliSync, SessionUtil}
|
||||||
alias BDS.UI.Workbench
|
alias BDS.UI.Workbench
|
||||||
|
|
||||||
@@ -216,6 +216,26 @@ defmodule BDS.Desktop.ShellLive.Bridges do
|
|||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def handle_info({:editor_translation_completed, :post, post_id, language}, socket, _callbacks) do
|
||||||
|
send_update(PostEditor,
|
||||||
|
id: "post-editor-#{post_id}",
|
||||||
|
action: :translation_completed,
|
||||||
|
language: language
|
||||||
|
)
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
|
def handle_info({:editor_translation_completed, :media, media_id, language}, socket, _callbacks) do
|
||||||
|
send_update(MediaEditor,
|
||||||
|
id: "media-editor-#{media_id}",
|
||||||
|
action: :translation_completed,
|
||||||
|
language: language
|
||||||
|
)
|
||||||
|
|
||||||
|
{:noreply, socket}
|
||||||
|
end
|
||||||
|
|
||||||
def handle_info({:post_editor_apply_ai_suggestions, post_id, fields}, socket, _callbacks) do
|
def handle_info({:post_editor_apply_ai_suggestions, post_id, fields}, socket, _callbacks) do
|
||||||
send_update(PostEditor,
|
send_update(PostEditor,
|
||||||
id: "post-editor-#{post_id}",
|
id: "post-editor-#{post_id}",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ defmodule BDS.Desktop.ShellLive.MediaEditor do
|
|||||||
|
|
||||||
alias BDS.Desktop.{FilePicker}
|
alias BDS.Desktop.{FilePicker}
|
||||||
alias BDS.Desktop.ShellLive.Notify
|
alias BDS.Desktop.ShellLive.Notify
|
||||||
alias BDS.{AI, I18n, Media}
|
alias BDS.{AI, I18n, Media, Tasks}
|
||||||
alias BDS.Media.Media, as: MediaRecord
|
alias BDS.Media.Media, as: MediaRecord
|
||||||
alias BDS.Media.Translation
|
alias BDS.Media.Translation
|
||||||
alias BDS.Posts.Post
|
alias BDS.Posts.Post
|
||||||
@@ -57,6 +57,17 @@ defmodule BDS.Desktop.ShellLive.MediaEditor do
|
|||||||
{:ok, socket}
|
{:ok, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update(%{action: :translation_completed} = assigns, socket) do
|
||||||
|
socket =
|
||||||
|
socket
|
||||||
|
|> assign(Map.drop(assigns, [:action, :language]))
|
||||||
|
|> assign(:quick_actions_open?, false)
|
||||||
|
|> assign(:editing_translation, nil)
|
||||||
|
|> build_data()
|
||||||
|
|
||||||
|
{:ok, socket}
|
||||||
|
end
|
||||||
|
|
||||||
def update(assigns, socket) do
|
def update(assigns, socket) do
|
||||||
socket =
|
socket =
|
||||||
socket
|
socket
|
||||||
@@ -552,25 +563,34 @@ defmodule BDS.Desktop.ShellLive.MediaEditor do
|
|||||||
media = socket.assigns.media
|
media = socket.assigns.media
|
||||||
normalized_language = normalize_language(language)
|
normalized_language = normalize_language(language)
|
||||||
source_language = normalize_language(media.language)
|
source_language = normalize_language(media.language)
|
||||||
|
parent = self()
|
||||||
|
|
||||||
case AI.translate_media(media.id, normalized_language, source_language: source_language) do
|
{:ok, _task} =
|
||||||
{:ok, translation} ->
|
Tasks.submit_task(
|
||||||
case Media.upsert_media_translation(media.id, normalized_language, translation) do
|
"Translate Media to #{normalized_language}",
|
||||||
{:ok, _saved_translation} ->
|
fn report ->
|
||||||
socket
|
report.(0.1, "Translating media to #{normalized_language}")
|
||||||
|> assign(:quick_actions_open?, false)
|
|
||||||
|> assign(:editing_translation, nil)
|
|
||||||
|> build_data()
|
|
||||||
|
|
||||||
{:error, reason} ->
|
with {:ok, translation} <-
|
||||||
notify_output(socket, dgettext("ui", "Translate"), inspect(reason), "error")
|
AI.translate_media(media.id, normalized_language,
|
||||||
|> build_data()
|
source_language: source_language
|
||||||
end
|
),
|
||||||
|
{:ok, _saved_translation} <-
|
||||||
|
Media.upsert_media_translation(media.id, normalized_language, translation) do
|
||||||
|
report.(1.0, "Media translation complete")
|
||||||
|
send(parent, {:editor_translation_completed, :media, media.id, normalized_language})
|
||||||
|
%{media_id: media.id, language: normalized_language}
|
||||||
|
else
|
||||||
|
{:error, reason} -> {:error, reason}
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
%{group_id: media.project_id, group_name: "AI"}
|
||||||
|
)
|
||||||
|
|
||||||
{:error, reason} ->
|
socket
|
||||||
notify_output(socket, dgettext("ui", "Translate"), inspect(reason), "error")
|
|> assign(:quick_actions_open?, false)
|
||||||
|> build_data()
|
|> assign(:editing_translation, nil)
|
||||||
end
|
|> build_data()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ defmodule BDS.Desktop.ShellLive.MiscEditor do
|
|||||||
import Phoenix.HTML, only: [raw: 1]
|
import Phoenix.HTML, only: [raw: 1]
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
alias BDS.{Embeddings, Generation, Git, HelpDocs, Posts, Repo}
|
alias BDS.{Embeddings, Git, HelpDocs, Posts, Repo}
|
||||||
alias BDS.Desktop.ShellLive.Notify
|
alias BDS.Desktop.ShellLive.Notify
|
||||||
alias BDS.MapUtils
|
alias BDS.MapUtils
|
||||||
alias BDS.Settings.Setting
|
alias BDS.Settings.Setting
|
||||||
@@ -77,7 +77,6 @@ defmodule BDS.Desktop.ShellLive.MiscEditor do
|
|||||||
def handle_event("apply_site_validation", _params, socket) do
|
def handle_event("apply_site_validation", _params, socket) do
|
||||||
meta = meta(socket.assigns)
|
meta = meta(socket.assigns)
|
||||||
payload = Map.get(meta, :payload, %{})
|
payload = Map.get(meta, :payload, %{})
|
||||||
project_id = Map.get(meta, :project_id, socket.assigns.project_id)
|
|
||||||
|
|
||||||
report = %{
|
report = %{
|
||||||
sitemap_path: Map.get(payload, :sitemap_path),
|
sitemap_path: Map.get(payload, :sitemap_path),
|
||||||
@@ -89,21 +88,8 @@ defmodule BDS.Desktop.ShellLive.MiscEditor do
|
|||||||
existing_html_url_count: Map.get(payload, :existing_html_url_count, 0)
|
existing_html_url_count: Map.get(payload, :existing_html_url_count, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
case Generation.apply_validation(project_id, report) do
|
notify_command("apply_site_validation", %{report: report})
|
||||||
{:ok, result} ->
|
{:noreply, socket}
|
||||||
notify_output(
|
|
||||||
dgettext("ui", "Site Validation"),
|
|
||||||
dgettext("ui", "Validation changes applied"),
|
|
||||||
inspect(result)
|
|
||||||
)
|
|
||||||
|
|
||||||
notify_command("validate_site")
|
|
||||||
{:noreply, socket}
|
|
||||||
end
|
|
||||||
rescue
|
|
||||||
error ->
|
|
||||||
notify_output(dgettext("ui", "Site Validation"), inspect(error), nil, "error")
|
|
||||||
{:noreply, socket}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_event("fix_translation_validation", _params, socket) do
|
def handle_event("fix_translation_validation", _params, socket) do
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
|
|
||||||
use Phoenix.LiveComponent
|
use Phoenix.LiveComponent
|
||||||
|
|
||||||
alias BDS.{AI, Embeddings, Metadata, Posts, Preview}
|
alias BDS.{AI, Embeddings, Metadata, Posts, Preview, Tasks}
|
||||||
alias BDS.Desktop.ShellData
|
alias BDS.Desktop.ShellData
|
||||||
alias BDS.Desktop.ShellLive.{EditorImageDrop, Notify}
|
alias BDS.Desktop.ShellLive.{EditorImageDrop, Notify}
|
||||||
alias BDS.Desktop.ShellLive.PostEditor.{DraftManagement, ListValues, Persistence, PostMetadata}
|
alias BDS.Desktop.ShellLive.PostEditor.{DraftManagement, ListValues, Persistence, PostMetadata}
|
||||||
@@ -131,6 +131,15 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
{:ok, socket}
|
{:ok, socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update(%{action: :translation_completed, language: language} = assigns, socket) do
|
||||||
|
socket =
|
||||||
|
socket
|
||||||
|
|> assign(Map.drop(assigns, [:action, :language]))
|
||||||
|
|> apply_translation_completed(language)
|
||||||
|
|
||||||
|
{:ok, socket}
|
||||||
|
end
|
||||||
|
|
||||||
def update(%{action: :apply_ai_suggestions, fields: fields} = assigns, socket) do
|
def update(%{action: :apply_ai_suggestions, fields: fields} = assigns, socket) do
|
||||||
socket =
|
socket =
|
||||||
socket
|
socket
|
||||||
@@ -808,34 +817,56 @@ defmodule BDS.Desktop.ShellLive.PostEditor do
|
|||||||
post_id = socket.assigns.post_id
|
post_id = socket.assigns.post_id
|
||||||
normalized_language = normalize_language(language, "")
|
normalized_language = normalize_language(language, "")
|
||||||
source_language = socket.assigns.canonical_language
|
source_language = socket.assigns.canonical_language
|
||||||
|
project_id = socket.assigns.post.project_id
|
||||||
|
parent = self()
|
||||||
|
|
||||||
case AI.translate_post(post_id, normalized_language, source_language: source_language) do
|
{:ok, _task} =
|
||||||
{:ok, translation} ->
|
Tasks.submit_task(
|
||||||
with {:ok, _saved_translation} <-
|
"Translate Post to #{normalized_language}",
|
||||||
Posts.upsert_post_translation(post_id, normalized_language, %{
|
fn report ->
|
||||||
title: translation.title,
|
report.(0.1, "Translating post to #{normalized_language}")
|
||||||
excerpt: translation.excerpt,
|
|
||||||
content: translation.content
|
|
||||||
}) do
|
|
||||||
socket =
|
|
||||||
socket
|
|
||||||
|> assign(:active_language, normalized_language)
|
|
||||||
|> assign(:drafts, Map.delete(socket.assigns.drafts, normalized_language))
|
|
||||||
|> assign(:quick_actions_open?, false)
|
|
||||||
|> build_data()
|
|
||||||
|
|
||||||
Notify.dirty(:post, post_id, false)
|
with {:ok, translation} <-
|
||||||
socket
|
AI.translate_post(post_id, normalized_language,
|
||||||
else
|
source_language: source_language
|
||||||
{:error, reason} ->
|
),
|
||||||
notify_output(socket, dgettext("ui", "Translate"), inspect(reason), "error")
|
{:ok, _saved_translation} <-
|
||||||
|> build_data()
|
Posts.upsert_post_translation(post_id, normalized_language, %{
|
||||||
end
|
title: translation.title,
|
||||||
|
excerpt: translation.excerpt,
|
||||||
|
content: translation.content
|
||||||
|
}) do
|
||||||
|
report.(1.0, "Post translation complete")
|
||||||
|
send(parent, {:editor_translation_completed, :post, post_id, normalized_language})
|
||||||
|
%{post_id: post_id, language: normalized_language}
|
||||||
|
else
|
||||||
|
{:error, reason} -> {:error, reason}
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
%{group_id: project_id, group_name: "AI"}
|
||||||
|
)
|
||||||
|
|
||||||
{:error, reason} ->
|
socket
|
||||||
notify_output(socket, dgettext("ui", "Translate"), inspect(reason), "error")
|
|> assign(:quick_actions_open?, false)
|
||||||
|
|> build_data()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp apply_translation_completed(socket, language) do
|
||||||
|
case Posts.get_post(socket.assigns.post_id) do
|
||||||
|
nil ->
|
||||||
|
build_data(socket)
|
||||||
|
|
||||||
|
%Post{} = post ->
|
||||||
|
socket =
|
||||||
|
socket
|
||||||
|
|> assign(:post, post)
|
||||||
|
|> assign(:active_language, language)
|
||||||
|
|> assign(:drafts, Map.delete(socket.assigns.drafts, language))
|
||||||
|> build_data()
|
|> build_data()
|
||||||
end
|
|
||||||
|
Notify.dirty(:post, post.id, false)
|
||||||
|
socket
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -224,6 +224,14 @@ defmodule BDS.Generation do
|
|||||||
end
|
end
|
||||||
|
|
||||||
def apply_validation(project_id, report) when is_binary(project_id) and is_map(report) do
|
def apply_validation(project_id, report) when is_binary(project_id) and is_map(report) do
|
||||||
|
apply_validation(project_id, report, [])
|
||||||
|
end
|
||||||
|
|
||||||
|
@spec apply_validation(String.t(), map(), generation_opts()) :: {:ok, map()} | {:error, term()}
|
||||||
|
def apply_validation(project_id, report, opts)
|
||||||
|
when is_binary(project_id) and is_map(report) and is_list(opts) do
|
||||||
|
on_progress = callback(opts)
|
||||||
|
|
||||||
with {:ok, plan} <- plan_generation(project_id, @core_sections) do
|
with {:ok, plan} <- plan_generation(project_id, @core_sections) do
|
||||||
expected_outputs = build_outputs(plan)
|
expected_outputs = build_outputs(plan)
|
||||||
expected_output_map = Map.new(expected_outputs)
|
expected_output_map = Map.new(expected_outputs)
|
||||||
@@ -247,11 +255,19 @@ defmodule BDS.Generation do
|
|||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Enum.each(outputs_to_render, fn {relative_path, content} ->
|
total_to_render = length(outputs_to_render)
|
||||||
|
:ok = report_generation_started(on_progress, total_to_render, "validation routes")
|
||||||
|
|
||||||
|
outputs_to_render
|
||||||
|
|> Enum.with_index(1)
|
||||||
|
|> Enum.each(fn {{relative_path, content}, index} ->
|
||||||
_ =
|
_ =
|
||||||
write_generated_file(project_id, relative_path, content,
|
write_generated_file(project_id, relative_path, content,
|
||||||
refresh_timestamp_on_unchanged: route_html_path?(relative_path)
|
refresh_timestamp_on_unchanged: route_html_path?(relative_path)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
:ok =
|
||||||
|
report_generation_progress(on_progress, index, total_to_render, "validation routes")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
{deleted_url_count, removed_empty_dir_count} =
|
{deleted_url_count, removed_empty_dir_count} =
|
||||||
|
|||||||
Reference in New Issue
Block a user