feat: added doc rendering
This commit is contained in:
12
lib/bds/desktop/external_links.ex
Normal file
12
lib/bds/desktop/external_links.ex
Normal file
@@ -0,0 +1,12 @@
|
||||
defmodule BDS.Desktop.ExternalLinks do
|
||||
@moduledoc false
|
||||
|
||||
@github_url "https://github.com/rfc1437/bDS2"
|
||||
@github_issues_url "#{@github_url}/issues"
|
||||
|
||||
@spec github_url() :: String.t()
|
||||
def github_url, do: @github_url
|
||||
|
||||
@spec github_issues_url() :: String.t()
|
||||
def github_issues_url, do: @github_issues_url
|
||||
end
|
||||
@@ -2,7 +2,7 @@ defmodule BDS.Desktop.MenuBar do
|
||||
@moduledoc false
|
||||
|
||||
use BDS.Desktop.MenuCompat
|
||||
alias BDS.Desktop.{ShellData, Shutdown, UILocale}
|
||||
alias BDS.Desktop.{ExternalLinks, ShellData, Shutdown, UILocale}
|
||||
alias BDS.UI.Commands
|
||||
alias BDS.UI.MenuBar, as: ShellMenuBar
|
||||
alias Desktop.OS
|
||||
@@ -59,7 +59,7 @@ defmodule BDS.Desktop.MenuBar do
|
||||
end
|
||||
|
||||
def handle_event("view_on_github", menu) do
|
||||
OS.launch_default_browser("https://github.com/rfc1437/bDS")
|
||||
OS.launch_default_browser(ExternalLinks.github_url())
|
||||
{:noreply, menu}
|
||||
end
|
||||
|
||||
@@ -78,7 +78,7 @@ defmodule BDS.Desktop.MenuBar do
|
||||
end
|
||||
|
||||
def handle_event("report_issue", menu) do
|
||||
OS.launch_default_browser("https://github.com/rfc1437/bDS/issues")
|
||||
OS.launch_default_browser(ExternalLinks.github_issues_url())
|
||||
{:noreply, menu}
|
||||
end
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ defmodule BDS.Desktop.ShellLive do
|
||||
|
||||
alias BDS.{AI, BoundedAtoms}
|
||||
alias BDS.CliSync.Watcher
|
||||
alias BDS.Desktop.{FolderPicker, ShellData, UILocale}
|
||||
alias BDS.Desktop.{ExternalLinks, FolderPicker, ShellData, UILocale}
|
||||
|
||||
alias BDS.Desktop.ShellLive.{
|
||||
Bridges,
|
||||
@@ -786,12 +786,12 @@ defmodule BDS.Desktop.ShellLive do
|
||||
end
|
||||
|
||||
defp handle_socket_menu_action(socket, :view_on_github) do
|
||||
OS.launch_default_browser("https://github.com/rfc1437/bDS")
|
||||
OS.launch_default_browser(ExternalLinks.github_url())
|
||||
socket
|
||||
end
|
||||
|
||||
defp handle_socket_menu_action(socket, :report_issue) do
|
||||
OS.launch_default_browser("https://github.com/rfc1437/bDS/issues")
|
||||
OS.launch_default_browser(ExternalLinks.github_issues_url())
|
||||
socket
|
||||
end
|
||||
|
||||
|
||||
@@ -421,7 +421,7 @@
|
||||
<% @current_tab.type == :import -> %>
|
||||
<.live_component module={ImportEditor} id={"import-editor-#{@current_tab.id}"} current_tab={@current_tab} offline_mode={@offline_mode} project_id={@projects.active_project_id} />
|
||||
|
||||
<% @current_tab.type in [:site_validation, :metadata_diff, :translation_validation, :find_duplicates, :git_diff] -> %>
|
||||
<% @current_tab.type in [:site_validation, :metadata_diff, :translation_validation, :find_duplicates, :git_diff, :documentation, :api_documentation] -> %>
|
||||
<.live_component module={MiscEditor} id={"misc-editor-#{@current_tab.type}-#{@current_tab.id}"} current_tab={@current_tab} tab_meta={@tab_meta} project_id={@projects.active_project_id} />
|
||||
|
||||
<% true -> %>
|
||||
|
||||
@@ -3,9 +3,10 @@ defmodule BDS.Desktop.ShellLive.MiscEditor do
|
||||
|
||||
use Phoenix.LiveComponent
|
||||
|
||||
import Phoenix.HTML, only: [raw: 1]
|
||||
import Ecto.Query
|
||||
|
||||
alias BDS.{Embeddings, Generation, Git, Posts, Repo}
|
||||
alias BDS.{Embeddings, Generation, Git, HelpDocs, Posts, Repo}
|
||||
alias BDS.MapUtils
|
||||
alias BDS.Settings.Setting
|
||||
use Gettext, backend: BDS.Gettext
|
||||
@@ -13,6 +14,8 @@ defmodule BDS.Desktop.ShellLive.MiscEditor do
|
||||
embed_templates("misc_editor_html/*")
|
||||
|
||||
@misc_routes [
|
||||
:documentation,
|
||||
:api_documentation,
|
||||
:site_validation,
|
||||
:metadata_diff,
|
||||
:translation_validation,
|
||||
@@ -264,12 +267,28 @@ defmodule BDS.Desktop.ShellLive.MiscEditor do
|
||||
# ── Public helper functions (used by template) ─────────────────────────────
|
||||
|
||||
@spec misc_class(atom()) :: String.t()
|
||||
def misc_class(:documentation), do: "help-doc-view"
|
||||
def misc_class(:api_documentation), do: "help-doc-view"
|
||||
def misc_class(:site_validation), do: "site-validation-view"
|
||||
def misc_class(:metadata_diff), do: "metadata-diff-view"
|
||||
def misc_class(:translation_validation), do: "translation-validation-view"
|
||||
def misc_class(:find_duplicates), do: "duplicates-view"
|
||||
def misc_class(:git_diff), do: "git-diff-view"
|
||||
|
||||
@spec markdown_html(String.t()) :: Phoenix.HTML.safe()
|
||||
def markdown_html(content) do
|
||||
html =
|
||||
case Earmark.as_html(content || "", escape: true) do
|
||||
{:ok, rendered, _messages} -> rendered
|
||||
{:error, rendered, _messages} -> rendered
|
||||
end
|
||||
|
||||
raw(html)
|
||||
end
|
||||
|
||||
@spec refreshable?(atom()) :: boolean()
|
||||
def refreshable?(kind), do: kind not in [:documentation, :api_documentation]
|
||||
|
||||
@spec summary_items(map()) :: [{String.t(), any()}]
|
||||
def summary_items(%{summary: summary}) when is_map(summary), do: Enum.to_list(summary)
|
||||
def summary_items(_misc), do: []
|
||||
@@ -369,6 +388,8 @@ defmodule BDS.Desktop.ShellLive.MiscEditor do
|
||||
payload = Map.get(meta, :payload, %{})
|
||||
|
||||
case type do
|
||||
:documentation -> build_help_doc(type, meta)
|
||||
:api_documentation -> build_help_doc(type, meta)
|
||||
:site_validation -> build_site_validation(meta, payload)
|
||||
:metadata_diff -> build_metadata_diff(assigns, meta, payload)
|
||||
:translation_validation -> build_translation_validation(meta, payload)
|
||||
@@ -379,6 +400,18 @@ defmodule BDS.Desktop.ShellLive.MiscEditor do
|
||||
|
||||
defp do_build(_assigns), do: nil
|
||||
|
||||
defp build_help_doc(type, meta) do
|
||||
help_doc = HelpDocs.fetch(type)
|
||||
|
||||
%{
|
||||
kind: type,
|
||||
title: Map.get(meta, :title, help_doc.title),
|
||||
subtitle: Map.get(meta, :subtitle, help_doc.subtitle),
|
||||
summary: %{},
|
||||
markdown: help_doc.markdown
|
||||
}
|
||||
end
|
||||
|
||||
defp build_site_validation(meta, payload) do
|
||||
summary = Map.get(payload, :summary, %{})
|
||||
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
<p><%= @misc_editor.subtitle %></p>
|
||||
</div>
|
||||
<div class="misc-editor-actions">
|
||||
<button class="secondary" type="button" phx-click="rerun_misc_editor" phx-target={@myself}><%= dgettext("ui", "Refresh") %></button>
|
||||
<%= if refreshable?(@misc_editor.kind) do %>
|
||||
<button class="secondary" type="button" phx-click="rerun_misc_editor" phx-target={@myself}><%= dgettext("ui", "Refresh") %></button>
|
||||
<% end %>
|
||||
<%= if @misc_editor.kind == :site_validation do %>
|
||||
<button class="primary" type="button" phx-click="apply_site_validation" phx-target={@myself} disabled={Enum.empty?(@misc_editor.missing_url_paths) and Enum.empty?(@misc_editor.extra_url_paths) and Enum.empty?(@misc_editor.updated_post_url_paths)}><%= dgettext("ui", "Apply") %></button>
|
||||
<% end %>
|
||||
@@ -23,6 +25,16 @@
|
||||
|
||||
<div class="misc-editor-content">
|
||||
<%= case @misc_editor.kind do %>
|
||||
<% :documentation -> %>
|
||||
<article class="misc-card help-doc-markdown" data-testid="help-documentation">
|
||||
<%= markdown_html(@misc_editor.markdown) %>
|
||||
</article>
|
||||
|
||||
<% :api_documentation -> %>
|
||||
<article class="misc-card help-doc-markdown" data-testid="help-api-documentation">
|
||||
<%= markdown_html(@misc_editor.markdown) %>
|
||||
</article>
|
||||
|
||||
<% :site_validation -> %>
|
||||
<div class="misc-columns">
|
||||
<section class="misc-card"><h3><%= dgettext("ui", "Missing URLs") %></h3><%= if Enum.empty?(@misc_editor.missing_url_paths) do %><p><%= dgettext("ui", "None found") %></p><% end %><ul><%= for path <- @misc_editor.missing_url_paths do %><li><%= path %></li><% end %></ul></section>
|
||||
|
||||
54
lib/bds/help_docs.ex
Normal file
54
lib/bds/help_docs.ex
Normal file
@@ -0,0 +1,54 @@
|
||||
defmodule BDS.HelpDocs do
|
||||
@moduledoc false
|
||||
|
||||
alias BDS.Scripting.ApiDocs
|
||||
use Gettext, backend: BDS.Gettext
|
||||
|
||||
@documentation_path Path.expand("../../DOCUMENTATION.md", __DIR__)
|
||||
|
||||
@type help_kind :: :documentation | :api_documentation
|
||||
|
||||
@spec fetch(help_kind()) :: %{title: String.t(), subtitle: String.t(), markdown: String.t()}
|
||||
def fetch(:documentation) do
|
||||
%{
|
||||
title: dgettext("ui", "Documentation"),
|
||||
subtitle:
|
||||
dgettext(
|
||||
"ui",
|
||||
"End-user guidance for editorial workflows, media, templates, translation, and publishing in bDS2."
|
||||
),
|
||||
markdown: documentation_markdown()
|
||||
}
|
||||
end
|
||||
|
||||
def fetch(:api_documentation) do
|
||||
%{
|
||||
title: dgettext("ui", "API"),
|
||||
subtitle:
|
||||
dgettext(
|
||||
"ui",
|
||||
"Current Lua scripting contract rendered from the live bDS2 runtime."
|
||||
),
|
||||
markdown: ApiDocs.render()
|
||||
}
|
||||
end
|
||||
|
||||
@spec documentation_markdown() :: String.t()
|
||||
def documentation_markdown do
|
||||
case File.read(@documentation_path) do
|
||||
{:ok, contents} -> contents
|
||||
{:error, _reason} -> fallback_documentation()
|
||||
end
|
||||
end
|
||||
|
||||
defp fallback_documentation do
|
||||
[
|
||||
"# bDS2 User Guide",
|
||||
"",
|
||||
"The project-level DOCUMENTATION.md file is missing.",
|
||||
"",
|
||||
"Use the repository root documentation file to provide the in-app user guide."
|
||||
]
|
||||
|> Enum.join("\n")
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user