From c24650ffa0d6205c0f0179a45a32fce31eb40df7 Mon Sep 17 00:00:00 2001 From: Hojjat Afsharan Date: Fri, 6 Sep 2024 10:21:08 +0200 Subject: [PATCH] Vue: add FormSpec MultilineExtended Change-Id: I4e9c044bdaa6981515ed16032e55725ea81500b7 --- cmk/gui/form_specs/private/__init__.py | 2 + cmk/gui/form_specs/private/definitions.py | 13 ++- cmk/gui/form_specs/vue/form_spec_visitor.py | 10 +- cmk/gui/form_specs/vue/shared_type_defs.py | 13 +++ cmk/gui/form_specs/vue/visitors/__init__.py | 2 + .../vue/visitors/comment_text_area.py | 31 ++++++ .../cmk-frontend-vue/src/assets/variables.css | 2 + .../src/form/components/FormEdit.vue | 2 + .../src/form/components/FormReadonly.vue | 7 +- .../components/forms/FormCommentTextArea.vue | 38 +++++++ .../components/forms/FormMultilineText.vue | 26 ++--- .../components/vue_formspec_components.ts | 11 +- .../forms/FormCommentTextArea.test.ts | 100 ++++++++++++++++++ .../source/vue_formspec/components.json | 75 +++++++++---- .../source/vue_formspec/postprocess.py | 2 + 15 files changed, 298 insertions(+), 36 deletions(-) create mode 100644 cmk/gui/form_specs/vue/visitors/comment_text_area.py create mode 100644 packages/cmk-frontend-vue/src/form/components/forms/FormCommentTextArea.vue create mode 100644 packages/cmk-frontend-vue/tests/form/components/forms/FormCommentTextArea.test.ts diff --git a/cmk/gui/form_specs/private/__init__.py b/cmk/gui/form_specs/private/__init__.py index 9e13e8e4621..b0d76b8db01 100644 --- a/cmk/gui/form_specs/private/__init__.py +++ b/cmk/gui/form_specs/private/__init__.py @@ -5,6 +5,7 @@ from .catalog import Catalog, Topic from .definitions import ( + CommentTextArea, LegacyValueSpec, SingleChoiceElementExtended, SingleChoiceExtended, @@ -23,6 +24,7 @@ "ListExtended", "SingleChoiceElementExtended", "SingleChoiceExtended", + "CommentTextArea", "OptionalChoice", "UnknownFormSpec", "not_empty", diff --git a/cmk/gui/form_specs/private/definitions.py b/cmk/gui/form_specs/private/definitions.py index 5c97f0edf40..516d2b2d126 100644 --- a/cmk/gui/form_specs/private/definitions.py +++ b/cmk/gui/form_specs/private/definitions.py @@ -10,7 +10,13 @@ from cmk.gui.valuespec import ValueSpec from cmk.rulesets.v1 import Help, Label, Message, Title -from cmk.rulesets.v1.form_specs import DefaultValue, FormSpec, InputHint, InvalidElementValidator +from cmk.rulesets.v1.form_specs import ( + DefaultValue, + FormSpec, + InputHint, + InvalidElementValidator, +) +from cmk.rulesets.v1.form_specs._basic import MultilineText T = TypeVar("T") @@ -58,3 +64,8 @@ class SingleChoiceExtended(Generic[T], FormSpec[T]): type: type[T] # TODO: copy the code of the post init function? + + +@dataclass(frozen=True, kw_only=True) +class CommentTextArea(MultilineText): + pass diff --git a/cmk/gui/form_specs/vue/form_spec_visitor.py b/cmk/gui/form_specs/vue/form_spec_visitor.py index 9489aa0e1ed..2cf2feba64e 100644 --- a/cmk/gui/form_specs/vue/form_spec_visitor.py +++ b/cmk/gui/form_specs/vue/form_spec_visitor.py @@ -17,6 +17,7 @@ from cmk.gui.form_specs.converter import SimplePassword, TransformForLegacyData, Tuple from cmk.gui.form_specs.private import ( Catalog, + CommentTextArea, DictionaryExtended, LegacyValueSpec, ListExtended, @@ -73,6 +74,7 @@ BooleanChoiceVisitor, CascadingSingleChoiceVisitor, CatalogVisitor, + CommentTextAreaVisitor, DataSizeVisitor, DictionaryVisitor, FixedValueVisitor, @@ -121,6 +123,7 @@ def register_form_specs(): register_visitor_class(FixedValue, FixedValueVisitor) register_visitor_class(BooleanChoice, BooleanChoiceVisitor) register_visitor_class(MultilineText, MultilineTextVisitor) + register_visitor_class(CommentTextArea, CommentTextAreaVisitor) register_visitor_class(RegularExpression, StringVisitor, recompose_regular_expression) register_visitor_class(DataSize, DataSizeVisitor) register_visitor_class(Catalog, CatalogVisitor) @@ -153,7 +156,9 @@ def register_validators(): register_validators() -def _process_validation_errors(validation_errors: list[shared_type_defs.ValidationMessage]) -> None: +def _process_validation_errors( + validation_errors: list[shared_type_defs.ValidationMessage], +) -> None: """This functions introduces validation errors from the vue-world into the CheckMK-GUI-world The CheckMK-GUI works with a global parameter user_errors. These user_errors include the field_id of the broken input field and the error text @@ -165,7 +170,8 @@ def _process_validation_errors(validation_errors: list[shared_type_defs.Validati first_error = validation_errors[0] raise MKUserError( - "" if not first_error.location else first_error.location[-1], first_error.message + "" if not first_error.location else first_error.location[-1], + first_error.message, ) diff --git a/cmk/gui/form_specs/vue/shared_type_defs.py b/cmk/gui/form_specs/vue/shared_type_defs.py index 7b05c061e84..78e1cd09f2e 100644 --- a/cmk/gui/form_specs/vue/shared_type_defs.py +++ b/cmk/gui/form_specs/vue/shared_type_defs.py @@ -94,6 +94,11 @@ class CascadingChoiceLayout(str, Enum): horizontal = "horizontal" +@dataclass(kw_only=True) +class CommentTextAreaI18n: + prefix_date_and_comment: str + + @dataclass(kw_only=True) class TimeSpanI18n: millisecond: str @@ -300,6 +305,13 @@ class MultilineText(FormSpec): input_hint: Optional[str] = None +@dataclass(kw_only=True) +class CommentTextArea(MultilineText): + user_name: str + i18n: CommentTextAreaI18n + type: str = "comment_text_area" + + @dataclass(kw_only=True) class DataSize(FormSpec): displayed_magnitudes: list[str] @@ -362,6 +374,7 @@ class SimplePassword(FormSpec): FixedValue, BooleanChoice, MultilineText, + CommentTextArea, Password, DataSize, Catalog, diff --git a/cmk/gui/form_specs/vue/visitors/__init__.py b/cmk/gui/form_specs/vue/visitors/__init__.py index 6d733c85f91..8691aed717e 100644 --- a/cmk/gui/form_specs/vue/visitors/__init__.py +++ b/cmk/gui/form_specs/vue/visitors/__init__.py @@ -7,6 +7,7 @@ from .boolean_choice import BooleanChoiceVisitor from .cascading_single_choice import CascadingSingleChoiceVisitor from .catalog import CatalogVisitor +from .comment_text_area import CommentTextAreaVisitor from .data_size import DataSizeVisitor from .dictionary import DictionaryVisitor from .fixed_value import FixedValueVisitor @@ -46,6 +47,7 @@ "OptionalChoiceVisitor", "PasswordVisitor", "SimplePasswordVisitor", + "CommentTextAreaVisitor", "SingleChoiceVisitor", "StringVisitor", "TimeSpanVisitor", diff --git a/cmk/gui/form_specs/vue/visitors/comment_text_area.py b/cmk/gui/form_specs/vue/visitors/comment_text_area.py new file mode 100644 index 00000000000..7a6fcdcd0dc --- /dev/null +++ b/cmk/gui/form_specs/vue/visitors/comment_text_area.py @@ -0,0 +1,31 @@ +#!/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 asdict + +from cmk.gui.form_specs.vue import shared_type_defs +from cmk.gui.form_specs.vue.visitors.multiline_text import MultilineTextVisitor +from cmk.gui.i18n import _ +from cmk.gui.logged_in import user + +from ._type_defs import EmptyValue, Value + + +class CommentTextAreaVisitor(MultilineTextVisitor): + def _to_vue( + self, raw_value: object, parsed_value: str | EmptyValue + ) -> tuple[shared_type_defs.CommentTextArea, Value]: + multiline_text, value = super()._to_vue(raw_value, parsed_value) + multiline_text_args = asdict(multiline_text) + multiline_text_args["type"] = "comment_text_area" + return ( + shared_type_defs.CommentTextArea( + **multiline_text_args, + user_name=user.id or "", + i18n=shared_type_defs.CommentTextAreaI18n( + prefix_date_and_comment=_("Prefix date and your name to the comment") + ), + ), + value, + ) diff --git a/packages/cmk-frontend-vue/src/assets/variables.css b/packages/cmk-frontend-vue/src/assets/variables.css index be61ca12da1..bf262802765 100644 --- a/packages/cmk-frontend-vue/src/assets/variables.css +++ b/packages/cmk-frontend-vue/src/assets/variables.css @@ -38,6 +38,7 @@ --icon-continue: url('themes/facelift/images/icon_continue.png'); --icon-main-help: url('themes/facelift/images/icon_main_help.svg'); --icon-save-to-services: url('themes/facelift/images/icon_save_to_services.svg'); + --icon-insertdate: url('themes/facelift/images/icon_insertdate.png'); /* Colors */ --default-submit-button-border-color: var(--success-dimmed); @@ -53,6 +54,7 @@ --icon-continue: url('themes/modern-dark/images/icon_continue.png'); --icon-main-help: url('themes/modern-dark/images/icon_main_help.svg'); --icon-save-to-services: url('themes/modern-dark/images/icon_save_to_services.svg'); + --icon-insertdate: url('themes/modern-dark/images/icon_insertdate.png'); /* Colors */ --default-submit-button-border-color: rgb(8 94 61); diff --git a/packages/cmk-frontend-vue/src/form/components/FormEdit.vue b/packages/cmk-frontend-vue/src/form/components/FormEdit.vue index 1687fe1681c..6ce8040daa8 100644 --- a/packages/cmk-frontend-vue/src/form/components/FormEdit.vue +++ b/packages/cmk-frontend-vue/src/form/components/FormEdit.vue @@ -22,6 +22,7 @@ import FormPassword from './forms/FormPassword.vue' import FormTuple from '@/form/components/forms/FormTuple.vue' import FormOptionalChoice from '@/form/components/forms/FormOptionalChoice.vue' import FormSimplePassword from '@/form/components/forms/FormSimplePassword.vue' +import FormCommentTextArea from './forms/FormCommentTextArea.vue' const props = defineProps<{ spec: FormSpec @@ -44,6 +45,7 @@ const components: Record = { time_span: FormTimeSpan, boolean_choice: FormBooleanChoice, multiline_text: FormMultilineText, + comment_text_area: FormCommentTextArea, multiple_choice: FormMultipleChoice, password: FormPassword, data_size: FormDataSize, diff --git a/packages/cmk-frontend-vue/src/form/components/FormReadonly.vue b/packages/cmk-frontend-vue/src/form/components/FormReadonly.vue index a6acd13d353..06630acd1ab 100644 --- a/packages/cmk-frontend-vue/src/form/components/FormReadonly.vue +++ b/packages/cmk-frontend-vue/src/form/components/FormReadonly.vue @@ -15,7 +15,8 @@ import type { MultipleChoice, Password, Tuple, - OptionalChoice + OptionalChoice, + CommentTextArea } from '@/form/components/vue_formspec_components' import { groupDictionaryValidations, @@ -68,6 +69,8 @@ function renderForm( return renderBooleanChoice(formSpec as BooleanChoice, value as boolean) case 'multiline_text': return renderMultilineText(formSpec as MultilineText, value as string) + case 'comment_text_area': + return renderMultilineText(formSpec as CommentTextArea, value as string) case 'data_size': return renderDataSize(value as [string, string]) case 'catalog': @@ -82,6 +85,8 @@ function renderForm( return renderOptionalChoice(formSpec as OptionalChoice, value as unknown[]) case 'simple_password': return renderSimplePassword() + default: + return null } } diff --git a/packages/cmk-frontend-vue/src/form/components/forms/FormCommentTextArea.vue b/packages/cmk-frontend-vue/src/form/components/forms/FormCommentTextArea.vue new file mode 100644 index 00000000000..c5762ab5b04 --- /dev/null +++ b/packages/cmk-frontend-vue/src/form/components/forms/FormCommentTextArea.vue @@ -0,0 +1,38 @@ + + + + diff --git a/packages/cmk-frontend-vue/src/form/components/forms/FormMultilineText.vue b/packages/cmk-frontend-vue/src/form/components/forms/FormMultilineText.vue index 5edd52bacd5..0b47f4801e4 100644 --- a/packages/cmk-frontend-vue/src/form/components/forms/FormMultilineText.vue +++ b/packages/cmk-frontend-vue/src/form/components/forms/FormMultilineText.vue @@ -25,17 +25,19 @@ const style = computed(() => {