Restore translation actions and flags after launch.

This commit is contained in:
2026-08-01 10:34:32 +02:00
parent 45f68422ed
commit 81382b45ce
5 changed files with 34 additions and 2 deletions

View File

@@ -25,7 +25,7 @@ The project is under active development. Core blogging workflows are broadly ava
- `bds-cli server` hosting the shared application engines over a loopback-by-default, public-key-only SSH service, with restrictive private key material, live authorization updates, terminal-session transport, CLI-change synchronization, ordered domain/task events, and native desktop remote-project selection. - `bds-cli server` hosting the shared application engines over a loopback-by-default, public-key-only SSH service, with restrictive private key material, live authorization updates, terminal-session transport, CLI-change synchronization, ordered domain/task events, and native desktop remote-project selection.
- bDS2-compatible Markdown/Liquid rendering with built-in macros rendered from bundled Liquid templates in isolated scopes (customizable with `macros/*` partial-template slugs), project-description homepage headings, category-controlled list title visibility, descriptive category archive titles, canonical multilingual and flat page routes for every configured blog language, recursive menus, calendar archives, feeds, a root hreflang sitemap, Pagefind, shared cached multicore full-site rendering, change-aware and forced full renders from the native Blog menu/CLI/TUI, and fast route/mtime-based incremental validation whose targeted repair refreshes affected aggregate pages through cancellable section task groups with bDS2-style per-URL progress. - bDS2-compatible Markdown/Liquid rendering with built-in macros rendered from bundled Liquid templates in isolated scopes (customizable with `macros/*` partial-template slugs), project-description homepage headings, category-controlled list title visibility, descriptive category archive titles, canonical multilingual and flat page routes for every configured blog language, recursive menus, calendar archives, feeds, a root hreflang sitemap, Pagefind, shared cached multicore full-site rendering, change-aware and forced full renders from the native Blog menu/CLI/TUI, and fast route/mtime-based incremental validation whose targeted repair refreshes affected aggregate pages through cancellable section task groups with bDS2-style per-URL progress.
- Navigable generated-route preview in the app or system browser, with draft database overlays and published filesystem content. - Navigable generated-route preview in the app or system browser, with draft database overlays and published filesystem content.
- Optional one-shot AI translation, description, analysis, taxonomy, and language-detection operations run in background tasks with editor-level waiting indicators, using provider-portable JSON-only requests through independent online and local OpenAI-compatible profiles. Each profile has secure credentials, persistently discovered chat/title/image model selections, explicit tool/vision overrides, chat testing, and restart-persistent status-bar airplane-mode routing. - Optional one-shot AI translation, description, analysis, taxonomy, and language-detection operations are available immediately after restart and run in background tasks with editor-level waiting indicators, using provider-portable JSON-only requests through independent online and local OpenAI-compatible profiles. Each profile has secure credentials, persistently discovered chat/title/image model selections, explicit tool/vision overrides, chat testing, and restart-persistent status-bar airplane-mode routing.
- Persistent conversational AI with safe Markdown, streamed and cancellable responses, model/session/token tracking, bounded project-aware blog tools, and localized conversation management in the Chat workspace. Allowlisted render tools add persistent native cards, charts, forms, lists, metrics, mind maps, tables, and tabs without executing assistant-provided HTML or JavaScript. - Persistent conversational AI with safe Markdown, streamed and cancellable responses, model/session/token tracking, bounded project-aware blog tools, and localized conversation management in the Chat workspace. Allowlisted render tools add persistent native cards, charts, forms, lists, metrics, mind maps, tables, and tabs without executing assistant-provided HTML or JavaScript.
- SSH-agent-based SCP or rsync publishing. - SSH-agent-based SCP or rsync publishing.
- Integrated Git workflow for each blog project's current repository, with repository initialization, read-only origin discovery, Git LFS image tracking, status and diffs, branch/file history with bDS2-compatible sync-status colors, commits, cancellable fetch/pull/push, and post-pull filesystem reconciliation; network actions respect airplane mode. - Integrated Git workflow for each blog project's current repository, with repository initialization, read-only origin discovery, Git LFS image tracking, status and diffs, branch/file history with bDS2-compatible sync-status colors, commits, cancellable fetch/pull/push, and post-pull filesystem reconciliation; network actions respect airplane mode.

View File

@@ -6063,7 +6063,7 @@ impl BdsApp {
self.import_editors.clear(); self.import_editors.clear();
self.chat_editors.clear(); self.chat_editors.clear();
self.tags_view_state = None; self.tags_view_state = None;
self.settings_state = None; self.settings_state = Some(self.hydrate_settings_state());
self.style_view_state = None; self.style_view_state = None;
self.dashboard_state = None; self.dashboard_state = None;
self.site_validation_state = SiteValidationState::default(); self.site_validation_state = SiteValidationState::default();
@@ -10759,6 +10759,7 @@ mod tests {
let mut app = BdsApp::new_for_tests(db, project, temp.path().to_path_buf()); let mut app = BdsApp::new_for_tests(db, project, temp.path().to_path_buf());
app.sidebar_view = SidebarView::Posts; app.sidebar_view = SidebarView::Posts;
app.sidebar_visible = false; app.sidebar_visible = false;
app.settings_state = None;
let _ = app.dispatch_menu_action(MenuAction::EditPreferences); let _ = app.dispatch_menu_action(MenuAction::EditPreferences);
@@ -10773,6 +10774,33 @@ mod tests {
); );
} }
#[test]
fn fresh_workspace_hydrates_saved_ai_configuration_for_quick_actions() {
let (db, project, temp) = setup();
ai::save_endpoint(
db.conn(),
&ai::AiEndpointConfig {
kind: ai::AiEndpointKind::Airplane,
url: "http://localhost:11434/v1".to_string(),
model: "llama3.2".to_string(),
api_key: None,
},
)
.unwrap();
let app = BdsApp::new_for_tests(db, project, temp.path().to_path_buf());
let settings = app
.settings_state
.as_ref()
.expect("fresh workspace must load persisted AI configuration");
assert_eq!(
settings.airplane_ai.endpoint_url,
"http://localhost:11434/v1"
);
assert_eq!(settings.airplane_ai.chat_model, "llama3.2");
}
#[test] #[test]
fn only_transport_loss_closes_an_open_remote_session() { fn only_transport_loss_closes_an_open_remote_session() {
assert!(remote_error_closes_connection("connection_lost")); assert!(remote_error_closes_connection("connection_lost"));

View File

@@ -1275,6 +1275,7 @@ pub fn view(
row![ row![
text(format!("{} {}", language.flag_emoji, language.name)) text(format!("{} {}", language.flag_emoji, language.name))
.size(13) .size(13)
.shaping(Shaping::Advanced)
.color(Color::WHITE), .color(Color::WHITE),
Space::with_width(Length::Fill), Space::with_width(Length::Fill),
text(status) text(status)

View File

@@ -366,6 +366,8 @@ invariant EndpointModelPersistence {
-- restart. Model dropdowns (settings and chat) are populated from -- restart. Model dropdowns (settings and chat) are populated from
-- the persisted list; it is only overwritten by the next -- the persisted list; it is only overwritten by the next
-- successful RefreshEndpointModels for the same kind. -- successful RefreshEndpointModels for the same kind.
-- Editor AI actions derive availability from this persisted state during
-- initial workspace hydration; opening Settings first is never required.
} }
rule TestEndpointModels { rule TestEndpointModels {

View File

@@ -126,6 +126,7 @@ value LanguagePickerModal {
-- Shown for Translate Post and Translate Media Metadata actions. -- Shown for Translate Post and Translate Media Metadata actions.
-- Lists all configured blogLanguages except source language. -- Lists all configured blogLanguages except source language.
-- Each row: flag emoji, language name, status badge if translation exists. -- Each row: flag emoji, language name, status badge if translation exists.
-- Flag emoji use fallback-capable text shaping and never render as missing-glyph icons.
-- Existing translations show "(draft)" or "(published)" badge. -- Existing translations show "(draft)" or "(published)" badge.
-- Click selects target language and initiates translation flow. -- Click selects target language and initiates translation flow.
-- Cancel closes without action. -- Cancel closes without action.