1515use Icinga \Web \Session ;
1616use ipl \Html \Attributes ;
1717use ipl \Html \Contract \FormSubmitElement ;
18- use ipl \Html \FormElement \FieldsetElement ;
18+ use ipl \Html \FormDecoration \DescriptionDecorator ;
19+ use ipl \Html \HtmlDocument ;
1920use ipl \Html \HtmlElement ;
2021use ipl \Html \Text ;
2122use ipl \Sql \Connection ;
2526use ipl \Validator \StringLengthValidator ;
2627use ipl \Web \Common \CsrfCounterMeasure ;
2728use ipl \Web \Compat \CompatForm ;
28- use ipl \Web \FormElement \SuggestionElement ;
2929use ipl \Web \Url ;
3030
3131class ContactForm extends CompatForm
@@ -44,6 +44,7 @@ class ContactForm extends CompatForm
4444 public function __construct (Connection $ db )
4545 {
4646 $ this ->db = $ db ;
47+ $ this ->applyDefaultElementDecorators ();
4748
4849 $ this ->on (self ::ON_SENT , function () {
4950 if ($ this ->hasBeenRemoved ()) {
@@ -80,14 +81,8 @@ protected function assemble()
8081 $ this ->addCsrfCounterMeasure (Session::getSession ()->getId ());
8182
8283 // Fieldset for contact full name and username
83- $ contact = (new FieldsetElement (
84- 'contact ' ,
85- [
86- 'label ' => $ this ->translate ('Contact ' ),
87- ]
88- ));
89-
90- $ this ->addElement ($ contact );
84+ $ this ->addElement ('fieldset ' , 'contact ' , ['label ' => $ this ->translate ('Contact ' )]);
85+ $ contact = $ this ->getElement ('contact ' );
9186
9287 $ contact ->addElement (
9388 'text ' ,
@@ -98,49 +93,48 @@ protected function assemble()
9893 ]
9994 );
10095
96+ // TODO: remove this once https://github.com/Icinga/ipl-html/issues/178 is fixed
97+ $ contact ->addElementLoader ('ipl \\Web \\FormElement ' , 'Element ' );
98+
99+ $ contact ->addElement (
100+ 'suggestion ' ,
101+ 'username ' ,
102+ [
103+ 'label ' => $ this ->translate ('Icinga Web User ' ),
104+ 'description ' => $ this ->translate (
105+ 'Use this to associate actions in the UI, such as incident management, with this contact. '
106+ . ' To successfully receive desktop notifications, this is also required. '
107+ ),
108+ 'suggestionsUrl ' => Url::fromPath (
109+ 'notifications/contact/suggest-icinga-web-user ' ,
110+ ['showCompact ' => true , '_disableLayout ' => 1 ]
111+ ),
112+ 'validators ' => [
113+ new StringLengthValidator (['max ' => 254 ]),
114+ new CallbackValidator (function ($ value , $ validator ) {
115+ $ contact = Contact::on ($ this ->db )
116+ ->filter (Filter::equal ('username ' , $ value ));
117+ if ($ this ->contactId ) {
118+ $ contact ->filter (Filter::unequal ('id ' , $ this ->contactId ));
119+ }
120+
121+ if ($ contact ->first () !== null ) {
122+ $ validator ->addMessage ($ this ->translate (
123+ 'A contact with the same username already exists. '
124+ ));
125+
126+ return false ;
127+ }
128+
129+ return true ;
130+ })
131+ ]
132+ ]
133+ );
101134 $ contact
102- ->addElement (
103- new SuggestionElement (
104- 'username ' ,
105- Url::fromPath (
106- 'notifications/contact/suggest-icinga-web-user ' ,
107- ['showCompact ' => true , '_disableLayout ' => 1 ]
108- ),
109- [
110- 'label ' => $ this ->translate ('Icinga Web User ' ),
111- 'validators ' => [
112- new StringLengthValidator (['max ' => 254 ]),
113- new CallbackValidator (function ($ value , $ validator ) {
114- $ contact = Contact::on ($ this ->db )
115- ->filter (Filter::equal ('username ' , $ value ));
116- if ($ this ->contactId ) {
117- $ contact ->filter (Filter::unequal ('id ' , $ this ->contactId ));
118- }
119-
120- if ($ contact ->first () !== null ) {
121- $ validator ->addMessage ($ this ->translate (
122- 'A contact with the same username already exists. '
123- ));
124-
125- return false ;
126- }
127-
128- return true ;
129- })
130- ]
131- ]
132- )
133- )
134- ->addHtml (
135- new HtmlElement (
136- 'p ' ,
137- new Attributes (['class ' => 'description ' ]),
138- new Text ($ this ->translate (
139- 'Use this to associate actions in the UI, such as incident management, with this contact. '
140- . ' To successfully receive desktop notifications, this is also required. '
141- ))
142- )
143- );
135+ ->getElement ('username ' )
136+ ->getDecorators ()
137+ ->replaceDecorator ('Description ' , DescriptionDecorator::class, ['class ' => 'description ' ]);
144138
145139 $ channelQuery = Channel::on ($ this ->db )
146140 ->columns (['id ' , 'name ' , 'type ' ]);
@@ -157,6 +151,10 @@ protected function assemble()
157151 'default_channel_id ' ,
158152 [
159153 'label ' => $ this ->translate ('Default Channel ' ),
154+ 'description ' => $ this ->translate (
155+ "Contact will be notified via the default channel, when no specific channel is configured "
156+ . " in an event rule. "
157+ ),
160158 'required ' => true ,
161159 'class ' => 'autosubmit ' ,
162160 'disabledOptions ' => ['' ],
@@ -166,22 +164,18 @@ protected function assemble()
166164 ]
167165 );
168166
167+ $ defaultChannel
168+ ->getDecorators ()
169+ ->replaceDecorator ('Description ' , DescriptionDecorator::class, ['class ' => 'description ' ]);
170+ $ this ->decorate ($ defaultChannel );
171+
169172 $ contact ->registerElement ($ defaultChannel );
170173
171174 $ this ->addAddressElements ($ channelTypes [$ defaultChannel ->getValue ()] ?? null );
172175
173176 $ this ->addHtml (new HtmlElement ('hr ' ));
174177
175- $ this ->decorate ($ defaultChannel );
176178 $ this ->addHtml ($ defaultChannel );
177- $ this ->addHtml (new HtmlElement (
178- 'p ' ,
179- new Attributes (['class ' => 'description ' ]),
180- new Text ($ this ->translate (
181- "Contact will be notified via the default channel, when no specific channel is configured "
182- . " in an event rule. "
183- ))
184- ));
185179
186180 $ this ->addElement (
187181 'submit ' ,
@@ -205,9 +199,7 @@ protected function assemble()
205199 );
206200
207201 $ this ->registerElement ($ deleteButton );
208- $ this ->getElement ('submit ' )
209- ->getWrapper ()
210- ->prepend ($ deleteButton );
202+ $ this ->getElement ('submit ' )->prependWrapper ((new HtmlDocument ())->addHtml ($ deleteButton ));
211203 }
212204 }
213205
@@ -466,15 +458,15 @@ private function addAddressElements(?string $defaultType): void
466458 return ;
467459 }
468460
469- $ address = new FieldsetElement ('contact_address ' , ['label ' => $ this ->translate ('Channels ' )]);
461+ $ address = $ this ->createElement ('fieldset ' , 'contact_address ' , ['label ' => $ this ->translate ('Channels ' )]);
462+ $ this ->addElement ($ address );
463+
470464 $ address ->addHtml (new HtmlElement (
471465 'p ' ,
472466 new Attributes (['class ' => 'description ' ]),
473467 new Text ($ this ->translate ('Configure the channels available for this contact here. ' ))
474468 ));
475469
476- $ this ->addElement ($ address );
477-
478470 foreach ($ plugins as $ type => $ name ) {
479471 $ element = $ this ->createElement ('text ' , $ type , [
480472 'label ' => $ name ,
0 commit comments