chore: documentation added and adapted to RuDS
This commit is contained in:
@@ -969,6 +969,8 @@ pub struct BdsApp {
|
||||
duplicates_state: DuplicatesState,
|
||||
guide_documentation: DocumentationState,
|
||||
api_documentation: DocumentationState,
|
||||
cli_documentation: DocumentationState,
|
||||
mcp_documentation: DocumentationState,
|
||||
metadata_diff_state: MetadataDiffState,
|
||||
menu_editor_state: MenuEditorState,
|
||||
translation_validation_state: crate::views::translation_validation::TranslationValidationState,
|
||||
@@ -1144,6 +1146,8 @@ impl BdsApp {
|
||||
duplicates_state: DuplicatesState::default(),
|
||||
guide_documentation: DocumentationState::new(DocumentationKind::Guide),
|
||||
api_documentation: DocumentationState::new(DocumentationKind::Api),
|
||||
cli_documentation: DocumentationState::new(DocumentationKind::Cli),
|
||||
mcp_documentation: DocumentationState::new(DocumentationKind::Mcp),
|
||||
metadata_diff_state: MetadataDiffState::default(),
|
||||
menu_editor_state: MenuEditorState::default(),
|
||||
translation_validation_state: Default::default(),
|
||||
@@ -1232,6 +1236,8 @@ impl BdsApp {
|
||||
duplicates_state: DuplicatesState::default(),
|
||||
guide_documentation: DocumentationState::new(DocumentationKind::Guide),
|
||||
api_documentation: DocumentationState::new(DocumentationKind::Api),
|
||||
cli_documentation: DocumentationState::new(DocumentationKind::Cli),
|
||||
mcp_documentation: DocumentationState::new(DocumentationKind::Mcp),
|
||||
metadata_diff_state: MetadataDiffState::default(),
|
||||
menu_editor_state: MenuEditorState::default(),
|
||||
translation_validation_state: Default::default(),
|
||||
@@ -3127,6 +3133,8 @@ impl BdsApp {
|
||||
match kind {
|
||||
DocumentationKind::Guide => &self.guide_documentation,
|
||||
DocumentationKind::Api => &self.api_documentation,
|
||||
DocumentationKind::Cli => &self.cli_documentation,
|
||||
DocumentationKind::Mcp => &self.mcp_documentation,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3134,6 +3142,8 @@ impl BdsApp {
|
||||
match kind {
|
||||
DocumentationKind::Guide => &mut self.guide_documentation,
|
||||
DocumentationKind::Api => &mut self.api_documentation,
|
||||
DocumentationKind::Cli => &mut self.cli_documentation,
|
||||
DocumentationKind::Mcp => &mut self.mcp_documentation,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3144,6 +3154,8 @@ impl BdsApp {
|
||||
tokio::task::spawn_blocking(move || match kind {
|
||||
DocumentationKind::Guide => crate::views::documentation::load_user_guide(),
|
||||
DocumentationKind::Api => crate::views::documentation::load_api_document(),
|
||||
DocumentationKind::Cli => crate::views::documentation::load_cli_guide(),
|
||||
DocumentationKind::Mcp => crate::views::documentation::load_mcp_guide(),
|
||||
})
|
||||
.await
|
||||
.unwrap_or_else(|error| DocumentLoad::Malformed {
|
||||
@@ -3160,6 +3172,8 @@ impl BdsApp {
|
||||
for (tab_type, kind) in [
|
||||
(TabType::Documentation, DocumentationKind::Guide),
|
||||
(TabType::ApiDocumentation, DocumentationKind::Api),
|
||||
(TabType::CliDocumentation, DocumentationKind::Cli),
|
||||
(TabType::McpDocumentation, DocumentationKind::Mcp),
|
||||
] {
|
||||
if !self.tabs.iter().any(|tab| tab.tab_type == tab_type) {
|
||||
continue;
|
||||
@@ -3413,6 +3427,8 @@ impl BdsApp {
|
||||
&self.duplicates_state,
|
||||
&self.guide_documentation,
|
||||
&self.api_documentation,
|
||||
&self.cli_documentation,
|
||||
&self.mcp_documentation,
|
||||
&self.metadata_diff_state,
|
||||
&self.menu_editor_state,
|
||||
&self.translation_validation_state,
|
||||
@@ -4349,6 +4365,14 @@ impl BdsApp {
|
||||
self.open_singleton_tab(TabType::ApiDocumentation, "tabBar.apiDocumentation");
|
||||
self.start_documentation_load(DocumentationKind::Api)
|
||||
}
|
||||
MenuAction::OpenCliDocumentation => {
|
||||
self.open_singleton_tab(TabType::CliDocumentation, "tabBar.cliDocumentation");
|
||||
self.start_documentation_load(DocumentationKind::Cli)
|
||||
}
|
||||
MenuAction::OpenMcpDocumentation => {
|
||||
self.open_singleton_tab(TabType::McpDocumentation, "tabBar.mcpDocumentation");
|
||||
self.start_documentation_load(DocumentationKind::Mcp)
|
||||
}
|
||||
MenuAction::ViewOnGitHub => {
|
||||
let _ = open::that("https://github.com/nickarumern/bds");
|
||||
Task::none()
|
||||
@@ -9164,6 +9188,34 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn help_menu_opens_cli_and_mcp_documentation_tabs() {
|
||||
let (db, project, temp) = setup();
|
||||
let mut app = BdsApp::new_for_tests(db, project, temp.path().to_path_buf());
|
||||
|
||||
let _ = app.dispatch_menu_action(MenuAction::OpenCliDocumentation);
|
||||
assert!(
|
||||
app.tabs
|
||||
.iter()
|
||||
.any(|tab| tab.tab_type == TabType::CliDocumentation)
|
||||
);
|
||||
assert_eq!(
|
||||
app.cli_documentation.status,
|
||||
crate::views::documentation::DocumentStatus::Loading
|
||||
);
|
||||
|
||||
let _ = app.dispatch_menu_action(MenuAction::OpenMcpDocumentation);
|
||||
assert!(
|
||||
app.tabs
|
||||
.iter()
|
||||
.any(|tab| tab.tab_type == TabType::McpDocumentation)
|
||||
);
|
||||
assert_eq!(
|
||||
app.mcp_documentation.status,
|
||||
crate::views::documentation::DocumentStatus::Loading
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn project_switch_keeps_global_documentation_loaded() {
|
||||
let (db, project, temp) = setup();
|
||||
|
||||
@@ -57,6 +57,8 @@ pub enum MenuAction {
|
||||
About,
|
||||
OpenDocumentation,
|
||||
OpenApiDocumentation,
|
||||
OpenCliDocumentation,
|
||||
OpenMcpDocumentation,
|
||||
ViewOnGitHub,
|
||||
ReportIssue,
|
||||
}
|
||||
@@ -101,6 +103,8 @@ impl MenuAction {
|
||||
MenuAction::About,
|
||||
MenuAction::OpenDocumentation,
|
||||
MenuAction::OpenApiDocumentation,
|
||||
MenuAction::OpenCliDocumentation,
|
||||
MenuAction::OpenMcpDocumentation,
|
||||
MenuAction::ViewOnGitHub,
|
||||
MenuAction::ReportIssue,
|
||||
];
|
||||
@@ -190,6 +194,8 @@ impl MenuAction {
|
||||
Self::About => "menu.item.about",
|
||||
Self::OpenDocumentation => "menu.item.openDocumentation",
|
||||
Self::OpenApiDocumentation => "menu.item.openApiDocumentation",
|
||||
Self::OpenCliDocumentation => "menu.item.openCliDocumentation",
|
||||
Self::OpenMcpDocumentation => "menu.item.openMcpDocumentation",
|
||||
Self::ViewOnGitHub => "menu.item.viewOnGitHub",
|
||||
Self::ReportIssue => "menu.item.reportIssue",
|
||||
}
|
||||
@@ -562,6 +568,18 @@ pub fn build_menu_bar(locale: UiLocale) -> (Menu, MenuRegistry) {
|
||||
locale,
|
||||
None,
|
||||
));
|
||||
let _ = help_menu.append(&item(
|
||||
&mut reg,
|
||||
MenuAction::OpenCliDocumentation,
|
||||
locale,
|
||||
None,
|
||||
));
|
||||
let _ = help_menu.append(&item(
|
||||
&mut reg,
|
||||
MenuAction::OpenMcpDocumentation,
|
||||
locale,
|
||||
None,
|
||||
));
|
||||
let _ = help_menu.append(&item(&mut reg, MenuAction::ViewOnGitHub, locale, None));
|
||||
let _ = help_menu.append(&item(&mut reg, MenuAction::ReportIssue, locale, None));
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ pub enum TabType {
|
||||
Templates,
|
||||
Documentation,
|
||||
ApiDocumentation,
|
||||
CliDocumentation,
|
||||
McpDocumentation,
|
||||
SiteValidation,
|
||||
TranslationValidation,
|
||||
FindDuplicates,
|
||||
@@ -25,9 +27,9 @@ pub enum TabType {
|
||||
impl TabType {
|
||||
/// Singleton tool tabs per tabs.allium: always one instance, id = type name.
|
||||
///
|
||||
/// Singleton types (10): settings, tags, style, menu_editor,
|
||||
/// documentation, api_documentation, metadata_diff, site_validation,
|
||||
/// translation_validation, find_duplicates.
|
||||
/// Singleton types (12): settings, tags, style, menu_editor,
|
||||
/// documentation, api_documentation, cli_documentation, mcp_documentation,
|
||||
/// metadata_diff, site_validation, translation_validation, find_duplicates.
|
||||
///
|
||||
/// Entity types (keyed by external ID): post, media, scripts (keyed),
|
||||
/// templates (keyed), chat, import, git_diff.
|
||||
@@ -41,6 +43,8 @@ impl TabType {
|
||||
| Self::MetadataDiff
|
||||
| Self::Documentation
|
||||
| Self::ApiDocumentation
|
||||
| Self::CliDocumentation
|
||||
| Self::McpDocumentation
|
||||
| Self::SiteValidation
|
||||
| Self::TranslationValidation
|
||||
| Self::FindDuplicates
|
||||
@@ -57,6 +61,8 @@ impl TabType {
|
||||
Self::MetadataDiff => "metadata_diff",
|
||||
Self::Documentation => "documentation",
|
||||
Self::ApiDocumentation => "api_documentation",
|
||||
Self::CliDocumentation => "cli_documentation",
|
||||
Self::McpDocumentation => "mcp_documentation",
|
||||
Self::SiteValidation => "site_validation",
|
||||
Self::TranslationValidation => "translation_validation",
|
||||
Self::FindDuplicates => "find_duplicates",
|
||||
@@ -76,6 +82,8 @@ impl TabType {
|
||||
Self::MetadataDiff => Some("tabBar.metadataDiff"),
|
||||
Self::Documentation => Some("tabBar.documentation"),
|
||||
Self::ApiDocumentation => Some("tabBar.apiDocumentation"),
|
||||
Self::CliDocumentation => Some("tabBar.cliDocumentation"),
|
||||
Self::McpDocumentation => Some("tabBar.mcpDocumentation"),
|
||||
Self::SiteValidation => Some("tabBar.siteValidation"),
|
||||
Self::TranslationValidation => Some("tabBar.translationValidation"),
|
||||
Self::FindDuplicates => Some("tabBar.findDuplicates"),
|
||||
|
||||
@@ -15,6 +15,8 @@ use crate::i18n::t;
|
||||
const API_REFERENCE: &str = include_str!("../../../../docs/scripting/API_REFERENCE.md");
|
||||
const API_TYPES: &str = include_str!("../../../../docs/scripting/TYPES.md");
|
||||
const USER_GUIDE: &str = include_str!("../../../../DOCUMENTATION.md");
|
||||
const CLI_GUIDE: &str = include_str!("../../../../CLI.md");
|
||||
const MCP_GUIDE: &str = include_str!("../../../../MCP.md");
|
||||
const UTILITY_EXAMPLE: &str = include_str!("../../../../docs/scripting/examples/utility.lua");
|
||||
const MACRO_EXAMPLE: &str = include_str!("../../../../docs/scripting/examples/macro.lua");
|
||||
const TRANSFORM_EXAMPLE: &str = include_str!("../../../../docs/scripting/examples/transform.lua");
|
||||
@@ -24,6 +26,8 @@ pub const API_DOCUMENTATION_URL: &str = "https://ruds.invalid/api-documentation"
|
||||
pub enum DocumentationKind {
|
||||
Guide,
|
||||
Api,
|
||||
Cli,
|
||||
Mcp,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -136,6 +140,8 @@ pub fn scroll_id(kind: DocumentationKind) -> scrollable::Id {
|
||||
scrollable::Id::new(match kind {
|
||||
DocumentationKind::Guide => "user-documentation",
|
||||
DocumentationKind::Api => "api-documentation",
|
||||
DocumentationKind::Cli => "cli-documentation",
|
||||
DocumentationKind::Mcp => "mcp-documentation",
|
||||
})
|
||||
}
|
||||
|
||||
@@ -143,10 +149,14 @@ pub fn view(state: &DocumentationState, locale: UiLocale) -> Element<'_, Message
|
||||
let title_key = match state.kind {
|
||||
DocumentationKind::Guide => "documentation.title",
|
||||
DocumentationKind::Api => "documentation.apiTitle",
|
||||
DocumentationKind::Cli => "documentation.cliTitle",
|
||||
DocumentationKind::Mcp => "documentation.mcpTitle",
|
||||
};
|
||||
let subtitle_key = match state.kind {
|
||||
DocumentationKind::Guide => "documentation.subtitle",
|
||||
DocumentationKind::Api => "documentation.apiSubtitle",
|
||||
DocumentationKind::Cli => "documentation.cliSubtitle",
|
||||
DocumentationKind::Mcp => "documentation.mcpSubtitle",
|
||||
};
|
||||
let toolbar = inputs::toolbar(
|
||||
vec![
|
||||
@@ -244,10 +254,21 @@ fn table_row<'a>(values: &'a [String], header: bool) -> Element<'a, Message> {
|
||||
}
|
||||
|
||||
pub fn load_user_guide() -> DocumentLoad {
|
||||
let path = user_guide_path();
|
||||
match load_document_file(&path) {
|
||||
load_embedded_document(&user_guide_path(), USER_GUIDE)
|
||||
}
|
||||
|
||||
pub fn load_cli_guide() -> DocumentLoad {
|
||||
load_embedded_document(&root_document_path("CLI.md"), CLI_GUIDE)
|
||||
}
|
||||
|
||||
pub fn load_mcp_guide() -> DocumentLoad {
|
||||
load_embedded_document(&root_document_path("MCP.md"), MCP_GUIDE)
|
||||
}
|
||||
|
||||
fn load_embedded_document(path: &Path, embedded: &str) -> DocumentLoad {
|
||||
match load_document_file(path) {
|
||||
DocumentLoad::Missing { signature } => DocumentLoad::Ready {
|
||||
source: USER_GUIDE.to_string(),
|
||||
source: embedded.to_string(),
|
||||
signature,
|
||||
},
|
||||
load => load,
|
||||
@@ -308,6 +329,8 @@ pub fn load_api_document() -> DocumentLoad {
|
||||
pub fn current_signature(kind: DocumentationKind) -> u64 {
|
||||
match kind {
|
||||
DocumentationKind::Guide => file_signature(&user_guide_path()),
|
||||
DocumentationKind::Cli => file_signature(&root_document_path("CLI.md")),
|
||||
DocumentationKind::Mcp => file_signature(&root_document_path("MCP.md")),
|
||||
DocumentationKind::Api => {
|
||||
let root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../docs/scripting");
|
||||
paths_signature(
|
||||
@@ -325,7 +348,11 @@ pub fn current_signature(kind: DocumentationKind) -> u64 {
|
||||
}
|
||||
|
||||
fn user_guide_path() -> PathBuf {
|
||||
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../DOCUMENTATION.md")
|
||||
root_document_path("DOCUMENTATION.md")
|
||||
}
|
||||
|
||||
fn root_document_path(name: &str) -> PathBuf {
|
||||
Path::new(env!("CARGO_MANIFEST_DIR")).join("../..").join(name)
|
||||
}
|
||||
|
||||
pub fn parse_document(source: &str) -> ParsedDocument {
|
||||
|
||||
@@ -134,6 +134,8 @@ pub fn view<'a>(
|
||||
duplicates_state: &'a DuplicatesState,
|
||||
guide_documentation: &'a DocumentationState,
|
||||
api_documentation: &'a DocumentationState,
|
||||
cli_documentation: &'a DocumentationState,
|
||||
mcp_documentation: &'a DocumentationState,
|
||||
metadata_diff_state: &'a MetadataDiffState,
|
||||
menu_editor_state: &'a MenuEditorState,
|
||||
translation_validation_state: &'a TranslationValidationState,
|
||||
@@ -168,6 +170,8 @@ pub fn view<'a>(
|
||||
duplicates_state,
|
||||
guide_documentation,
|
||||
api_documentation,
|
||||
cli_documentation,
|
||||
mcp_documentation,
|
||||
metadata_diff_state,
|
||||
menu_editor_state,
|
||||
translation_validation_state,
|
||||
@@ -414,6 +418,8 @@ fn route_content_area<'a>(
|
||||
duplicates_state: &'a DuplicatesState,
|
||||
guide_documentation: &'a DocumentationState,
|
||||
api_documentation: &'a DocumentationState,
|
||||
cli_documentation: &'a DocumentationState,
|
||||
mcp_documentation: &'a DocumentationState,
|
||||
metadata_diff_state: &'a MetadataDiffState,
|
||||
menu_editor_state: &'a MenuEditorState,
|
||||
translation_validation_state: &'a TranslationValidationState,
|
||||
@@ -507,6 +513,8 @@ fn route_content_area<'a>(
|
||||
ContentRoute::FindDuplicates => duplicates::view(duplicates_state, locale),
|
||||
ContentRoute::Documentation => documentation::view(guide_documentation, locale),
|
||||
ContentRoute::ApiDocumentation => documentation::view(api_documentation, locale),
|
||||
ContentRoute::CliDocumentation => documentation::view(cli_documentation, locale),
|
||||
ContentRoute::McpDocumentation => documentation::view(mcp_documentation, locale),
|
||||
ContentRoute::MetadataDiff => metadata_diff::view(metadata_diff_state, locale),
|
||||
ContentRoute::MenuEditor => menu_editor::view(menu_editor_state, locale),
|
||||
ContentRoute::TranslationValidation => {
|
||||
@@ -546,6 +554,8 @@ enum ContentRoute<'a> {
|
||||
FindDuplicates,
|
||||
Documentation,
|
||||
ApiDocumentation,
|
||||
CliDocumentation,
|
||||
McpDocumentation,
|
||||
MetadataDiff,
|
||||
MenuEditor,
|
||||
TranslationValidation,
|
||||
@@ -638,6 +648,8 @@ fn route_kind<'a>(
|
||||
TabType::FindDuplicates => ContentRoute::FindDuplicates,
|
||||
TabType::Documentation => ContentRoute::Documentation,
|
||||
TabType::ApiDocumentation => ContentRoute::ApiDocumentation,
|
||||
TabType::CliDocumentation => ContentRoute::CliDocumentation,
|
||||
TabType::McpDocumentation => ContentRoute::McpDocumentation,
|
||||
TabType::MenuEditor => ContentRoute::MenuEditor,
|
||||
TabType::Style => ContentRoute::Placeholder(&tab.title),
|
||||
TabType::TranslationValidation => ContentRoute::TranslationValidation,
|
||||
|
||||
Reference in New Issue
Block a user