mirror of
https://github.com/YunoHost/yunohost.git
synced 2024-09-03 20:06:10 +02:00
form: add translating method
This commit is contained in:
parent
3ff6e6ed96
commit
582b1ed311
2 changed files with 33 additions and 18 deletions
|
@ -447,7 +447,7 @@ class BaseTest:
|
|||
assert isinstance(option, OPTIONS[raw_option["type"]])
|
||||
assert option.type == raw_option["type"]
|
||||
assert option.id == id_
|
||||
assert option.ask == {"en": id_}
|
||||
assert option.ask == id_
|
||||
assert option.readonly is (True if is_special_readonly_option else False)
|
||||
assert option.visible is True
|
||||
# assert option.bind is None
|
||||
|
@ -493,7 +493,7 @@ class BaseTest:
|
|||
)
|
||||
option, value = _fill_or_prompt_one_option(raw_option, None)
|
||||
|
||||
expected_message = option.ask["en"]
|
||||
expected_message = option.ask
|
||||
choices = []
|
||||
|
||||
if isinstance(option, BaseChoicesOption):
|
||||
|
@ -510,7 +510,7 @@ class BaseTest:
|
|||
prefill=prefill,
|
||||
is_multiline=option.type == "text",
|
||||
autocomplete=choices,
|
||||
help=option.help["en"],
|
||||
help=option.help,
|
||||
)
|
||||
|
||||
def test_scenarios(self, intake, expected_output, raw_option, data):
|
||||
|
@ -558,7 +558,7 @@ class TestDisplayText(BaseTest):
|
|||
options, form = ask_questions_and_parse_answers(
|
||||
{_id: raw_option}, answers
|
||||
)
|
||||
assert stdout.getvalue() == f"{options[0].ask['en']}\n"
|
||||
assert stdout.getvalue() == f"{options[0].ask}\n"
|
||||
|
||||
|
||||
# ╭───────────────────────────────────────────────────────╮
|
||||
|
@ -609,7 +609,7 @@ class TestAlert(TestDisplayText):
|
|||
options, form = ask_questions_and_parse_answers(
|
||||
{"display_text_id": raw_option}, answers
|
||||
)
|
||||
ask = options[0].ask["en"]
|
||||
ask = options[0].ask
|
||||
if style in colors:
|
||||
color = colors[style]
|
||||
title = style.title() + (":" if style != "success" else "!")
|
||||
|
|
|
@ -297,15 +297,6 @@ class BaseOption(BaseModel):
|
|||
del schema["description"]
|
||||
schema["additionalProperties"] = False
|
||||
|
||||
@validator("ask", always=True)
|
||||
def parse_or_set_default_ask(
|
||||
cls, value: Union[Translation, None], values: Values
|
||||
) -> Translation:
|
||||
if value is None:
|
||||
return {"en": values["id"]}
|
||||
if isinstance(value, str):
|
||||
return {"en": value}
|
||||
return value
|
||||
|
||||
@validator("readonly", pre=True)
|
||||
def can_be_readonly(cls, value: bool, values: Values) -> bool:
|
||||
|
@ -327,7 +318,9 @@ class BaseOption(BaseModel):
|
|||
return evaluate_simple_js_expression(self.visible, context=context)
|
||||
|
||||
def _get_prompt_message(self, value: None) -> str:
|
||||
return _value_for_locale(self.ask)
|
||||
# force type to str
|
||||
# `OptionsModel.translate_options()` should have been called before calling this method
|
||||
return cast(str, self.ask)
|
||||
|
||||
|
||||
# ╭───────────────────────────────────────────────────────╮
|
||||
|
@ -367,7 +360,7 @@ class AlertOption(BaseReadonlyOption):
|
|||
State.danger: "red",
|
||||
}
|
||||
message = m18n.g(self.style) if self.style != State.danger else m18n.n("danger")
|
||||
return f"{colorize(message, colors[self.style])} {_value_for_locale(self.ask)}"
|
||||
return f"{colorize(message, colors[self.style])} {self.ask}"
|
||||
|
||||
|
||||
class ButtonOption(BaseReadonlyOption):
|
||||
|
@ -624,6 +617,7 @@ class NumberOption(BaseInputOption):
|
|||
max: Union[int, None] = None
|
||||
step: Union[int, None] = None
|
||||
_annotation = int
|
||||
_none_as_empty_str = False
|
||||
|
||||
@staticmethod
|
||||
def normalize(value, option={}):
|
||||
|
@ -1274,6 +1268,26 @@ class OptionsModel(BaseModel):
|
|||
def __init__(self, **kwargs) -> None:
|
||||
super().__init__(options=self.options_dict_to_list(kwargs))
|
||||
|
||||
def translate_options(self, i18n_key: Union[str, None] = None):
|
||||
"""
|
||||
Mutate in place translatable attributes of options to their translations
|
||||
"""
|
||||
for option in self.options:
|
||||
for key in ("ask", "help"):
|
||||
if not hasattr(option, key):
|
||||
continue
|
||||
|
||||
value = getattr(option, key)
|
||||
if value:
|
||||
setattr(option, key, _value_for_locale(value))
|
||||
elif key == "ask" and m18n.key_exists(f"{i18n_key}_{option.id}"):
|
||||
setattr(option, key, m18n.n(f"{i18n_key}_{option.id}"))
|
||||
elif key == "help" and m18n.key_exists(f"{i18n_key}_{option.id}_help"):
|
||||
setattr(option, key, m18n.n(f"{i18n_key}_{option.id}_help"))
|
||||
elif key == "ask":
|
||||
# FIXME warn?
|
||||
option.ask = option.id
|
||||
|
||||
|
||||
class FormModel(BaseModel):
|
||||
"""
|
||||
|
@ -1384,7 +1398,7 @@ def prompt_or_validate_form(
|
|||
raise YunohostValidationError(
|
||||
"config_action_disabled",
|
||||
action=option.id,
|
||||
help=_value_for_locale(option.help),
|
||||
help=option.help,
|
||||
)
|
||||
|
||||
if not option.is_visible(context):
|
||||
|
@ -1433,7 +1447,7 @@ def prompt_or_validate_form(
|
|||
prefill=value,
|
||||
is_multiline=isinstance(option, TextOption),
|
||||
autocomplete=choices,
|
||||
help=_value_for_locale(option.help),
|
||||
help=option.help,
|
||||
)
|
||||
|
||||
# Apply default value if none
|
||||
|
@ -1512,6 +1526,7 @@ def ask_questions_and_parse_answers(
|
|||
# FIXME use YunohostError instead since it is not really a user mistake?
|
||||
raise YunohostValidationError(error, raw_msg=True)
|
||||
|
||||
model.translate_options()
|
||||
# Build the form from those questions and instantiate it without
|
||||
# parsing/validation (construct) since it may contains required questions.
|
||||
form = build_form(model.options).construct()
|
||||
|
|
Loading…
Add table
Reference in a new issue