Skip to content

Commit

Permalink
MultipleChoiceFormSpec => DualListChoice/CheckboxListChoice
Browse files Browse the repository at this point in the history
CMK-19100

Change-Id: I11542f980361f656cd1fefea8e5e2584d5734d13
  • Loading branch information
hojjat-afsharan committed Oct 8, 2024
1 parent dc25d16 commit 2d2199a
Show file tree
Hide file tree
Showing 20 changed files with 1,052 additions and 304 deletions.
3 changes: 3 additions & 0 deletions cmk/gui/form_specs/private/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from .dictionary_extended import DictionaryExtended
from .list_extended import ListExtended
from .list_of_strings import ListOfStrings
from .multiple_choice import AdaptiveMultipleChoice, AdaptiveMultipleChoiceLayout
from .optional_choice import OptionalChoice
from .string_autocompleter import StringAutocompleter
from .validators import not_empty
Expand All @@ -32,4 +33,6 @@
"OptionalChoice",
"UnknownFormSpec",
"not_empty",
"AdaptiveMultipleChoice",
"AdaptiveMultipleChoiceLayout",
]
21 changes: 21 additions & 0 deletions cmk/gui/form_specs/private/multiple_choice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env python3
# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

from dataclasses import dataclass
from enum import Enum

from cmk.rulesets.v1.form_specs._composed import MultipleChoice


@dataclass(frozen=True, kw_only=True)
class AdaptiveMultipleChoiceLayout(str, Enum):
auto = "auto"
dual_list = "dual_list"
checkbox_list = "checkbox_list"


@dataclass(frozen=True, kw_only=True)
class AdaptiveMultipleChoice(MultipleChoice):
layout: AdaptiveMultipleChoiceLayout = AdaptiveMultipleChoiceLayout.auto
6 changes: 5 additions & 1 deletion cmk/gui/form_specs/vue/form_spec_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from cmk.gui.exceptions import MKUserError
from cmk.gui.form_specs.converter import SimplePassword, TransformForLegacyData, Tuple
from cmk.gui.form_specs.private import (
AdaptiveMultipleChoice,
Catalog,
CommentTextArea,
DictionaryExtended,
Expand All @@ -32,6 +33,7 @@
recompose_dictionary,
recompose_host_state,
recompose_list,
recompose_multiple_choice,
recompose_percentage,
recompose_regular_expression,
recompose_service_state,
Expand Down Expand Up @@ -132,14 +134,16 @@ def register_form_specs():
register_visitor_class(DataSize, DataSizeVisitor)
register_visitor_class(Catalog, CatalogVisitor)
register_visitor_class(ListExtended, ListVisitor)
register_visitor_class(MultipleChoice, MultipleChoiceVisitor)

register_visitor_class(TimeSpan, TimeSpanVisitor)
register_visitor_class(TransformForLegacyData, TransformVisitor)
register_visitor_class(Tuple, TupleVisitor)
register_visitor_class(OptionalChoice, OptionalChoiceVisitor)
register_visitor_class(SimplePassword, SimplePasswordVisitor)
register_visitor_class(StringAutocompleter, StringVisitor)
register_visitor_class(ListOfStrings, ListOfStringsVisitor)
register_visitor_class(AdaptiveMultipleChoice, MultipleChoiceVisitor)
register_visitor_class(MultipleChoice, MultipleChoiceVisitor, recompose_multiple_choice)

# Recomposed
register_visitor_class(String, StringVisitor, recompose_string)
Expand Down
29 changes: 24 additions & 5 deletions cmk/gui/form_specs/vue/shared_type_defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ class MultipleChoiceElement:
title: str


@dataclass(kw_only=True)
class DualListChoiceI18n:
add: str
remove: str
add_all: str
remove_all: str
available_options: str
selected_options: str
selected: str


class CascadingChoiceLayout(str, Enum):
vertical = "vertical"
horizontal = "horizontal"
Expand Down Expand Up @@ -269,10 +280,17 @@ class SingleChoice(FormSpec):


@dataclass(kw_only=True)
class MultipleChoice(FormSpec):
type: str = "multiple_choice"
elements: list[MultipleChoiceElement] = field(default_factory=lambda: [])
show_toggle_all: bool = False
class DualListChoice(FormSpec):
i18n: DualListChoiceI18n
elements: Optional[list[MultipleChoiceElement]] = field(default_factory=lambda: [])
show_toggle_all: Optional[bool] = False
type: str = "dual_list_choice"


@dataclass(kw_only=True)
class CheckboxListChoice(FormSpec):
type: str = "checkbox_list_choice"
elements: Optional[list[MultipleChoiceElement]] = field(default_factory=lambda: [])


@dataclass(kw_only=True)
Expand Down Expand Up @@ -398,7 +416,8 @@ class ListOfStrings(FormSpec):
Password,
DataSize,
Catalog,
MultipleChoice,
DualListChoice,
CheckboxListChoice,
TimeSpan,
Tuple,
OptionalChoice,
Expand Down
39 changes: 33 additions & 6 deletions cmk/gui/form_specs/vue/visitors/multiple_choice.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

from typing import Sequence, TypeVar

from cmk.gui.form_specs.private.multiple_choice import (
AdaptiveMultipleChoice,
AdaptiveMultipleChoiceLayout,
)
from cmk.gui.form_specs.vue import shared_type_defs
from cmk.gui.form_specs.vue.validators import build_vue_validators
from cmk.gui.form_specs.vue.visitors._base import FormSpecVisitor
Expand All @@ -16,15 +20,14 @@
get_prefill_default,
get_title_and_help,
)
from cmk.gui.i18n import translate_to_current_language
from cmk.gui.i18n import _, translate_to_current_language

from cmk.rulesets.v1 import Title
from cmk.rulesets.v1.form_specs import MultipleChoice

T = TypeVar("T")


class MultipleChoiceVisitor(FormSpecVisitor[MultipleChoice, Sequence[str]]):
class MultipleChoiceVisitor(FormSpecVisitor[AdaptiveMultipleChoice, Sequence[str]]):
def _is_valid_choice(self, value: str) -> bool:
return value in [x.name for x in self.form_spec.elements]

Expand All @@ -48,7 +51,9 @@ def _parse_value(self, raw_value: object) -> Sequence[str] | EmptyValue:

def _to_vue(
self, raw_value: object, parsed_value: Sequence[str] | EmptyValue
) -> tuple[shared_type_defs.MultipleChoice, Sequence[str]]:
) -> tuple[
shared_type_defs.DualListChoice | shared_type_defs.CheckboxListChoice, Sequence[str]
]:
title, help_text = get_title_and_help(self.form_spec)

elements = [
Expand All @@ -59,13 +64,35 @@ def _to_vue(
for element in self.form_spec.elements
]

if self.form_spec.layout.value == AdaptiveMultipleChoiceLayout.dual_list or (
self.form_spec.layout.value == AdaptiveMultipleChoiceLayout.auto and len(elements) > 15
):
return (
shared_type_defs.DualListChoice(
title=title,
help=help_text,
elements=elements,
validators=build_vue_validators(compute_validators(self.form_spec)),
i18n=shared_type_defs.DualListChoiceI18n(
add_all=_("Add all >>"),
remove_all=_("<< Remove all"),
add=_("Add >"),
remove=_("< Remove"),
available_options=_("Available options"),
selected_options=_("Selected options"),
selected=_("Selected"),
),
show_toggle_all=self.form_spec.show_toggle_all,
),
[] if isinstance(parsed_value, EmptyValue) else parsed_value,
)
# checkbox list or auto with <= 15 elements
return (
shared_type_defs.MultipleChoice(
shared_type_defs.CheckboxListChoice(
title=title,
help=help_text,
elements=elements,
validators=build_vue_validators(compute_validators(self.form_spec)),
show_toggle_all=self.form_spec.show_toggle_all,
),
[] if isinstance(parsed_value, EmptyValue) else parsed_value,
)
Expand Down
2 changes: 2 additions & 0 deletions cmk/gui/form_specs/vue/visitors/recomposers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .dictionary import recompose as recompose_dictionary
from .host_state import recompose as recompose_host_state
from .list import recompose as recompose_list
from .multiple_choice import recompose as recompose_multiple_choice
from .percentage import recompose as recompose_percentage
from .regular_expression import recompose as recompose_regular_expression
from .service_state import recompose as recompose_service_state
Expand All @@ -23,4 +24,5 @@
"recompose_host_state",
"recompose_service_state",
"recompose_string",
"recompose_multiple_choice",
]
32 changes: 32 additions & 0 deletions cmk/gui/form_specs/vue/visitors/recomposers/multiple_choice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/usr/bin/env python3
# Copyright (C) 2024 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.
from typing import Any

from cmk.ccc.exceptions import MKGeneralException

from cmk.gui.form_specs.private import AdaptiveMultipleChoice, AdaptiveMultipleChoiceLayout

from cmk.rulesets.v1.form_specs import FormSpec, MultipleChoice


def recompose(form_spec: FormSpec[Any]) -> AdaptiveMultipleChoice:
if not isinstance(form_spec, MultipleChoice):
raise MKGeneralException(
f"Cannot recompose form spec. Expected a MultipleChoice form spec, got {type(form_spec)}"
)

return AdaptiveMultipleChoice(
# FormSpec
title=form_spec.title,
help_text=form_spec.help_text,
custom_validate=form_spec.custom_validate,
migrate=form_spec.migrate,
# MultipleChoice
elements=form_spec.elements,
show_toggle_all=form_spec.show_toggle_all,
prefill=form_spec.prefill,
# AdaptiveMultipleChoice
layout=AdaptiveMultipleChoiceLayout.auto,
)
Loading

0 comments on commit 2d2199a

Please sign in to comment.