add readonly prop for config panel arg to display a value

This commit is contained in:
axolotle 2022-10-01 20:18:32 +02:00
parent 3644937fff
commit 35bac35bb0
2 changed files with 32 additions and 4 deletions

View file

@ -142,6 +142,7 @@
"config_apply_failed": "Applying the new configuration failed: {error}", "config_apply_failed": "Applying the new configuration failed: {error}",
"config_cant_set_value_on_section": "You can't set a single value on an entire config section.", "config_cant_set_value_on_section": "You can't set a single value on an entire config section.",
"config_forbidden_keyword": "The keyword '{keyword}' is reserved, you can't create or use a config panel with a question with this id.", "config_forbidden_keyword": "The keyword '{keyword}' is reserved, you can't create or use a config panel with a question with this id.",
"config_forbidden_readonly_type": "The type '{type}' can't be set as readonly, use another type to render this value (relevant arg id: '{id}').",
"config_no_panel": "No config panel found.", "config_no_panel": "No config panel found.",
"config_unknown_filter_key": "The filter key '{filter_key}' is incorrect.", "config_unknown_filter_key": "The filter key '{filter_key}' is incorrect.",
"config_validate_color": "Should be a valid RGB hexadecimal color", "config_validate_color": "Should be a valid RGB hexadecimal color",

View file

@ -524,6 +524,7 @@ class ConfigPanel:
"accept", "accept",
"redact", "redact",
"filter", "filter",
"readonly",
], ],
"defaults": {}, "defaults": {},
}, },
@ -609,10 +610,27 @@ class ConfigPanel:
"max_progression", "max_progression",
] ]
forbidden_keywords += format_description["sections"] forbidden_keywords += format_description["sections"]
forbidden_readonly_types = [
"password",
"app",
"domain",
"user",
"file"
]
for _, _, option in self._iterate(): for _, _, option in self._iterate():
if option["id"] in forbidden_keywords: if option["id"] in forbidden_keywords:
raise YunohostError("config_forbidden_keyword", keyword=option["id"]) raise YunohostError("config_forbidden_keyword", keyword=option["id"])
if (
option.get("readonly", False) and
option.get("type", "string") in forbidden_readonly_types
):
raise YunohostError(
"config_forbidden_readonly_type",
type=option["type"],
id=option["id"]
)
return self.config return self.config
def _hydrate(self): def _hydrate(self):
@ -797,6 +815,7 @@ class Question:
self.default = question.get("default", None) self.default = question.get("default", None)
self.optional = question.get("optional", False) self.optional = question.get("optional", False)
self.visible = question.get("visible", None) self.visible = question.get("visible", None)
self.readonly = question.get("readonly", False)
# Don't restrict choices if there's none specified # Don't restrict choices if there's none specified
self.choices = question.get("choices", None) self.choices = question.get("choices", None)
self.pattern = question.get("pattern", self.pattern) self.pattern = question.get("pattern", self.pattern)
@ -857,8 +876,9 @@ class Question:
# Display question if no value filled or if it's a readonly message # Display question if no value filled or if it's a readonly message
if Moulinette.interface.type == "cli" and os.isatty(1): if Moulinette.interface.type == "cli" and os.isatty(1):
text_for_user_input_in_cli = self._format_text_for_user_input_in_cli() text_for_user_input_in_cli = self._format_text_for_user_input_in_cli()
if getattr(self, "readonly", False): if self.readonly:
Moulinette.display(text_for_user_input_in_cli) Moulinette.display(text_for_user_input_in_cli)
return {}
elif self.value is None: elif self.value is None:
self._prompt(text_for_user_input_in_cli) self._prompt(text_for_user_input_in_cli)
@ -918,7 +938,12 @@ class Question:
text_for_user_input_in_cli = _value_for_locale(self.ask) text_for_user_input_in_cli = _value_for_locale(self.ask)
if self.readonly:
text_for_user_input_in_cli = colorize(text_for_user_input_in_cli, "purple")
if self.choices: if self.choices:
return text_for_user_input_in_cli + f" {self.choices[self.current_value]}"
return text_for_user_input_in_cli + f" {self.humanize(self.current_value)}"
elif self.choices:
# Prevent displaying a shitload of choices # Prevent displaying a shitload of choices
# (e.g. 100+ available users when choosing an app admin...) # (e.g. 100+ available users when choosing an app admin...)
@ -1018,6 +1043,7 @@ class ColorQuestion(StringQuestion):
class TagsQuestion(Question): class TagsQuestion(Question):
argument_type = "tags" argument_type = "tags"
default_value = ""
@staticmethod @staticmethod
def humanize(value, option={}): def humanize(value, option={}):
@ -1189,6 +1215,7 @@ class BooleanQuestion(Question):
def _format_text_for_user_input_in_cli(self): def _format_text_for_user_input_in_cli(self):
text_for_user_input_in_cli = super()._format_text_for_user_input_in_cli() text_for_user_input_in_cli = super()._format_text_for_user_input_in_cli()
if not self.readonly:
text_for_user_input_in_cli += " [yes | no]" text_for_user_input_in_cli += " [yes | no]"
return text_for_user_input_in_cli return text_for_user_input_in_cli
@ -1342,7 +1369,6 @@ class NumberQuestion(Question):
class DisplayTextQuestion(Question): class DisplayTextQuestion(Question):
argument_type = "display_text" argument_type = "display_text"
readonly = True
def __init__( def __init__(
self, question, context: Mapping[str, Any] = {}, hooks: Dict[str, Callable] = {} self, question, context: Mapping[str, Any] = {}, hooks: Dict[str, Callable] = {}
@ -1350,6 +1376,7 @@ class DisplayTextQuestion(Question):
super().__init__(question, context, hooks) super().__init__(question, context, hooks)
self.optional = True self.optional = True
self.readonly = True
self.style = question.get( self.style = question.get(
"style", "info" if question["type"] == "alert" else "" "style", "info" if question["type"] == "alert" else ""
) )