mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-24 10:46:50 -06:00
Merge PR #1998: ui: language command docs and error list every language
This commit is contained in:
@@ -175,6 +175,7 @@ pub fn handle(app: &mut SheetApp, ctx: &egui::Context, method: &str, p: &Json) -
|
||||
}
|
||||
"engine.commands" => {
|
||||
let mut v: Vec<Json> = app.session.commands().into_iter().map(|c| serde_json::to_value(c).unwrap_or_default()).collect();
|
||||
let language_params = format!("{{language: {}}} (alias: code)", crate::i18n::Language::code_list("|"));
|
||||
for (id, label, params) in [
|
||||
("ui.ribbonTab", "Ribbon Tab", ""),
|
||||
("view.collapseRibbon", "Collapse Ribbon", ""),
|
||||
@@ -195,7 +196,7 @@ pub fn handle(app: &mut SheetApp, ctx: &egui::Context, method: &str, p: &Json) -
|
||||
"Submit Print Job",
|
||||
"existing file.print sheet/pagination params → {printing,bytes,pending}; submits without opening a dialog",
|
||||
),
|
||||
("app.language.set", "Interface Language", "{language: \"en\"|\"zh\"|\"ja\"|\"ko\"|\"ru\"|\"pt\"|\"de\"|\"cs\"} (alias: code)"),
|
||||
("app.language.set", "Interface Language", language_params.as_str()),
|
||||
("app.language.english", "Interface Language: English", ""),
|
||||
("app.language.japanese", "Interface Language: Japanese", ""),
|
||||
] {
|
||||
@@ -530,4 +531,19 @@ mod tests {
|
||||
assert!(!app.printing.busy(), "discovery must not submit a job");
|
||||
assert!(app.backstage.is_none(), "discovery must not open settings");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn language_command_docs_list_every_language() {
|
||||
let mut session = gridcraft_engine::Session::new();
|
||||
session.new_workbook();
|
||||
let mut app = SheetApp::new(session, crate::Services::default());
|
||||
let Outcome::Done(reply) = handle(&mut app, &egui::Context::default(), "engine.commands", &json!({"search":"language"})) else {
|
||||
panic!("command discovery must return immediately");
|
||||
};
|
||||
let commands = reply["result"].as_array().unwrap();
|
||||
let docs = commands.iter().find(|c| c["id"] == "app.language.set").unwrap()["params"].as_str().unwrap();
|
||||
for l in crate::i18n::Language::ALL {
|
||||
assert!(docs.contains(&format!("\"{}\"", l.code())), "app.language.set docs miss {:?}: {docs}", l.code());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,12 @@ impl Language {
|
||||
Self::from_tag(code)
|
||||
}
|
||||
|
||||
/// Every code `app.language.set` takes, quoted and joined (`"en"|"es"|…`), for command docs
|
||||
/// and errors.
|
||||
pub fn code_list(separator: &str) -> String {
|
||||
Self::ALL.iter().map(|l| format!("\"{}\"", l.code())).collect::<Vec<_>>().join(separator)
|
||||
}
|
||||
|
||||
fn from_tag(tag: &str) -> Option<Self> {
|
||||
match tag.trim().split(['-', '_']).next()?.to_ascii_lowercase().as_str() {
|
||||
"en" => Some(Self::En),
|
||||
@@ -774,6 +780,10 @@ mod tests {
|
||||
app.run("app.language.set", serde_json::json!({"code": "ja"})).unwrap();
|
||||
assert_eq!(app.ui.language, Language::Ja, "`code` is an alias for `language`");
|
||||
assert!(app.run("app.language.set", serde_json::json!({})).is_err(), "no language is an error, not a dialog");
|
||||
let unknown = app.run("app.language.set", serde_json::json!({"language": "xx"})).unwrap_err().to_string();
|
||||
for l in Language::ALL {
|
||||
assert!(unknown.contains(&format!("\"{}\"", l.code())), "the error lists {:?}: {unknown}", l.code());
|
||||
}
|
||||
app.run("app.language.english", serde_json::json!({})).unwrap();
|
||||
assert_eq!(app.ui.language, Language::En);
|
||||
for l in Language::ALL {
|
||||
|
||||
@@ -658,7 +658,7 @@ impl SheetApp {
|
||||
self.ui.language = l;
|
||||
Ok(json!({"language": l}))
|
||||
}
|
||||
None => Err(format!("unknown language {code:?} (use \"en\", \"es\", \"zh\", \"ja\", \"ko\", \"ru\", \"pt\" or \"cs\")")),
|
||||
None => Err(format!("unknown language {code:?} (use one of {})", i18n::Language::code_list(", "))),
|
||||
}
|
||||
}
|
||||
"app.language.english" => {
|
||||
|
||||
Reference in New Issue
Block a user