1818use  Icinga \Web \Session ;
1919use  ipl \Html \Attributes ;
2020use  ipl \Html \DeferredText ;
21+ use  ipl \Html \FormDecoration \DescriptionDecorator ;
2122use  ipl \Html \FormElement \FieldsetElement ;
2223use  ipl \Html \HtmlDocument ;
2324use  ipl \Html \HtmlElement ;
@@ -602,7 +603,9 @@ protected function assembleModeSelection(): string
602603            '24-7 '  => $ this translate ('24/7 ' )
603604        ];
604605
605-         $ modeListnew  HtmlElement ('ul ' );
606+         $ modeListnew  HtmlElement ('ul ' , Attributes::create ([
607+             'class '  => ['rotation-mode ' , $ this disableModeSelection  ? 'disabled '  : '' ]
608+         ]));
606609        foreach  ($ modesas  $ mode$ label
607610            $ radio$ this createElement ('input ' , 'mode ' , [
608611                'type '  => 'radio ' ,
@@ -684,8 +687,14 @@ protected function assembleModeSelection(): string
684687
685688        $ this addHtml (new  HtmlElement (
686689            'div ' ,
687-             Attributes::create (['class '  => ['rotation-mode ' , $ this disableModeSelection  ? 'disabled '  : '' ]]),
688-             new  HtmlElement ('h2 ' , null , Text::create ($ this translate ('Mode ' ))),
690+             Attributes::create ([
691+                 'class '  => ['control-group ' ]
692+             ]),
693+             new  HtmlElement (
694+                 'div ' ,
695+                 Attributes::create (['class '  => 'control-label-group ' ]),
696+                 Text::create ($ this translate ('Rotation Mode ' ))
697+             ),
689698            $ modeList
690699        ));
691700
@@ -704,12 +713,15 @@ protected function assembleTwentyFourSevenOptions(FieldsetElement $options): Dat
704713        $ optionsaddElement ('number ' , 'interval ' , [
705714            'required '  => true ,
706715            'label '  => $ this translate ('Handoff every ' ),
716+             'description '  => $ this translate ('Have multiple rotation members take turns after this interval. ' ),
707717            'step '  => 1 ,
708718            'min '  => 1 ,
709719            'value '  => 1 ,
710720            'validators '  => [new  GreaterThanValidator ()]
711721        ]);
712722        $ interval$ optionsgetElement ('interval ' );
723+         $ intervalgetDecorators ()
724+             ->replaceDecorator ('Description ' , DescriptionDecorator::class, ['class '  => 'description ' ]);
713725
714726        $ frequency$ optionscreateElement ('select ' , 'frequency ' , [
715727            'required '  => true ,
@@ -796,11 +808,15 @@ protected function assemblePartialDayOptions(FieldsetElement $options): DateTime
796808        $ optionsaddElement ('number ' , 'interval ' , [
797809            'required '  => true ,
798810            'label '  => $ this translate ('Handoff every ' ),
811+             'description '  => $ this translate ('Have multiple rotation members take turns after this interval. ' ),
799812            'step '  => 1 ,
800813            'min '  => 1 ,
801814            'value '  => 1 ,
802815            'validators '  => [new  GreaterThanValidator ()]
803816        ]);
817+         $ interval$ optionsgetElement ('interval ' );
818+         $ intervalgetDecorators ()
819+             ->replaceDecorator ('Description ' , DescriptionDecorator::class, ['class '  => 'description ' ]);
804820
805821        $ selectedFromTime$ fromgetValue ();
806822        foreach  ($ timeOptionsas  $ key$ value
@@ -830,7 +846,6 @@ protected function assemblePartialDayOptions(FieldsetElement $options): DateTime
830846            )
831847        );
832848
833-         $ interval$ optionsgetElement ('interval ' );
834849        $ intervalprependWrapper (
835850            (new  HtmlDocument ())->addHtml (
836851                $ interval
@@ -912,8 +927,12 @@ protected function assembleMultiDayOptions(FieldsetElement $options): DateTime
912927            'step '  => 1 ,
913928            'min '  => 1 ,
914929            'value '  => 1 ,
915-             'label '  => $ this translate ('Handoff every ' )
930+             'label '  => $ this translate ('Handoff every ' ),
931+             'description '  => $ this translate ('Have multiple rotation members take turns after this interval. ' )
916932        ]);
933+         $ interval$ optionsgetElement ('interval ' );
934+         $ intervalgetDecorators ()
935+             ->replaceDecorator ('Description ' , DescriptionDecorator::class, ['class '  => 'description ' ]);
917936
918937        $ timeOptions$ this getTimeOptions ();
919938        $ fromAt$ optionscreateElement ('select ' , 'from_at ' , [
@@ -988,7 +1007,6 @@ protected function assembleMultiDayOptions(FieldsetElement $options): DateTime
9881007            )
9891008        );
9901009
991-         $ interval$ optionsgetElement ('interval ' );
9921010        $ intervalprependWrapper (
9931011            (new  HtmlDocument ())->addHtml (
9941012                $ interval
@@ -1029,17 +1047,9 @@ protected function assemble()
10291047
10301048        $ this addElement ('hidden ' , 'priority ' , ['ignore '  => true ]);
10311049
1032-         $ mode$ this assembleModeSelection ();
1033- 
1034-         $ autoSubmittedBy$ this getRequest ()->getHeader ('X-Icinga-Autosubmittedby ' )[0 ] ?? '' ;
1035-         if  ($ autoSubmittedBy'mode ' ) {
1036-             $ this clearPopulatedValue ('options ' );
1037-             $ this clearPopulatedValue ('first_handoff ' );
1038-         }
1039- 
10401050        $ this addElement ('text ' , 'name ' , [
10411051            'required '  => true ,
1042-             'label '  => $ this translate ('Title ' ),
1052+             'label '  => $ this translate ('Rotation Name ' ),
10431053            'validators '  => [
10441054                new  CallbackValidator (function  ($ value$ validator
10451055                    $ rotationson ($ this db )
@@ -1051,7 +1061,7 @@ protected function assemble()
10511061                    }
10521062
10531063                    if  ($ rotationsfirst () !== null ) {
1054-                         $ validatoraddMessage ($ this translate ('A rotation with this title  already exists ' ));
1064+                         $ validatoraddMessage ($ this translate ('A rotation with this name  already exists ' ));
10551065
10561066                        return  false ;
10571067                    }
@@ -1061,6 +1071,73 @@ protected function assemble()
10611071            ]
10621072        ]);
10631073
1074+         $ termValidatorfunction  (array  $ terms
1075+             $ contactTerms
1076+             $ groupTerms
1077+             foreach  ($ termsas  $ term
1078+                 /** @var TermInput\Term $term */ 
1079+                 if  (strpos ($ termgetSearchValue (), ': ' ) === false ) {
1080+                     // TODO: Auto-correct this to a valid type:id pair, if possible 
1081+                     $ termsetMessage ($ this translate ('Is not a contact nor a group of contacts ' ));
1082+                     continue ;
1083+                 }
1084+ 
1085+                 list ($ type$ idexplode (': ' , $ termgetSearchValue (), 2 );
1086+                 if  ($ type'contact ' ) {
1087+                     $ contactTerms$ id$ term
1088+                 } elseif  ($ type'group ' ) {
1089+                     $ groupTerms$ id$ term
1090+                 }
1091+             }
1092+ 
1093+             if  (! empty ($ contactTerms
1094+                 $ contactson (Database::get ()))
1095+                     ->filter (Filter::equal ('id ' , array_keys ($ contactTerms
1096+                 foreach  ($ contactsas  $ contact
1097+                     $ contactTerms$ contactid ]
1098+                         ->setLabel ($ contactfull_name )
1099+                         ->setClass ('contact ' );
1100+                 }
1101+             }
1102+ 
1103+             if  (! empty ($ groupTerms
1104+                 $ groupson (Database::get ()))
1105+                     ->filter (Filter::equal ('id ' , array_keys ($ groupTerms
1106+                 foreach  ($ groupsas  $ group
1107+                     $ groupTerms$ groupid ]
1108+                         ->setLabel ($ groupname )
1109+                         ->setClass ('group ' );
1110+                 }
1111+             }
1112+         };
1113+ 
1114+         $ membersnew  TermInput ('members ' ))
1115+             ->setIgnored ()
1116+             ->setRequired ()
1117+             ->setOrdered ()
1118+             ->setReadOnly ()
1119+             ->setVerticalTermDirection ()
1120+             ->setLabel ($ this translate ('Rotation Members ' ))
1121+             ->setSuggestionUrl ($ this suggestionUrl ->with (['showCompact '  => true , '_disableLayout '  => 1 ]))
1122+             ->on (TermInput::ON_ENRICH , $ termValidator
1123+             ->on (TermInput::ON_ADD , $ termValidator
1124+             ->on (TermInput::ON_SAVE , $ termValidator
1125+             ->on (TermInput::ON_PASTE , $ termValidator
1126+         $ this addElement ($ members
1127+ 
1128+         // TODO: TermInput is not compatible with the new decorators yet: https://github.com/Icinga/ipl-web/pull/317 
1129+         $ legacyDecoratornew  IcingaFormDecorator ();
1130+         $ memberssetDefaultElementDecorator ($ legacyDecorator
1131+         $ legacyDecoratordecorate ($ members
1132+ 
1133+         $ mode$ this assembleModeSelection ();
1134+ 
1135+         $ autoSubmittedBy$ this getRequest ()->getHeader ('X-Icinga-Autosubmittedby ' )[0 ] ?? '' ;
1136+         if  ($ autoSubmittedBy'mode ' ) {
1137+             $ this clearPopulatedValue ('options ' );
1138+             $ this clearPopulatedValue ('first_handoff ' );
1139+         }
1140+ 
10641141        $ this addElement ('fieldset ' , 'options ' );
10651142        /** @var FieldsetElement $options */ 
10661143        $ options$ this getElement ('options ' );
@@ -1098,7 +1175,7 @@ protected function assemble()
10981175            'aria-describedby '  => 'first-handoff-description ' ,
10991176            'min '  => $ earliestHandoffnull  ? $ earliestHandoffformat ('Y-m-d ' ) : null ,
11001177            'max '  => $ latestHandoffformat ('Y-m-d ' ),
1101-             'label '  => $ this translate ('First Handoff ' ),
1178+             'label '  => $ this translate ('Rotation Start ' ),
11021179            'value '  => $ firstHandoffDefault
11031180            'validators '  => [
11041181                new  CallbackValidator (
@@ -1110,14 +1187,14 @@ function ($value, $validator) use ($earliestHandoff, $firstHandoff, $latestHando
11101187                        );
11111188                        if  ($ earliestHandoffnull  && $ chosenHandoff$ earliestHandoff
11121189                            $ validatoraddMessage (sprintf (
1113-                                 $ this translate ('The first handoff  can only happen  after %s ' ),
1190+                                 $ this translate ('The rotation  can only start  after %s ' ),
11141191                                $ earliestHandoffformat ('Y-m-d ' ) // TODO: Use intl here 
11151192                            ));
11161193
11171194                            return  false ;
11181195                        } elseif  ($ chosenHandoff$ latestHandoff
11191196                            $ validatoraddMessage (sprintf (
1120-                                 $ this translate ('The first handoff  can only happen  before %s ' ),
1197+                                 $ this translate ('The rotation  can only start  before %s ' ),
11211198                                $ latestHandoffformat ('Y-m-d ' ) // TODO: Use intl here 
11221199                            ));
11231200
@@ -1142,10 +1219,10 @@ function ($value, $validator) use ($earliestHandoff, $firstHandoff, $latestHando
11421219
11431220                    $ actualFirstHandoff$ ruleGeneratorcurrent ()[0 ]->getStartDate ();
11441221                    if  ($ actualFirstHandoffnew  DateTime ()) {
1145-                         return  $ this translate ('The first handoff  will happen  immediately ' );
1222+                         return  $ this translate ('The rotation  will start  immediately ' );
11461223                    } else  {
11471224                        return  sprintf (
1148-                             $ this translate ('The first handoff  will happen  on %s ' ),
1225+                             $ this translate ('The rotation  will start  on %s ' ),
11491226                            (new  \IntlDateFormatter (
11501227                                \Locale::getDefault (),
11511228                                \IntlDateFormatter::MEDIUM ,
@@ -1157,65 +1234,6 @@ function ($value, $validator) use ($earliestHandoff, $firstHandoff, $latestHando
11571234            ));
11581235        }
11591236
1160-         $ termValidatorfunction  (array  $ terms
1161-             $ contactTerms
1162-             $ groupTerms
1163-             foreach  ($ termsas  $ term
1164-                 /** @var TermInput\Term $term */ 
1165-                 if  (strpos ($ termgetSearchValue (), ': ' ) === false ) {
1166-                     // TODO: Auto-correct this to a valid type:id pair, if possible 
1167-                     $ termsetMessage ($ this translate ('Is not a contact nor a group of contacts ' ));
1168-                     continue ;
1169-                 }
1170- 
1171-                 list ($ type$ idexplode (': ' , $ termgetSearchValue (), 2 );
1172-                 if  ($ type'contact ' ) {
1173-                     $ contactTerms$ id$ term
1174-                 } elseif  ($ type'group ' ) {
1175-                     $ groupTerms$ id$ term
1176-                 }
1177-             }
1178- 
1179-             if  (! empty ($ contactTerms
1180-                 $ contactson (Database::get ()))
1181-                     ->filter (Filter::equal ('id ' , array_keys ($ contactTerms
1182-                 foreach  ($ contactsas  $ contact
1183-                     $ contactTerms$ contactid ]
1184-                         ->setLabel ($ contactfull_name )
1185-                         ->setClass ('contact ' );
1186-                 }
1187-             }
1188- 
1189-             if  (! empty ($ groupTerms
1190-                 $ groupson (Database::get ()))
1191-                     ->filter (Filter::equal ('id ' , array_keys ($ groupTerms
1192-                 foreach  ($ groupsas  $ group
1193-                     $ groupTerms$ groupid ]
1194-                         ->setLabel ($ groupname )
1195-                         ->setClass ('group ' );
1196-                 }
1197-             }
1198-         };
1199- 
1200-         $ membersnew  TermInput ('members ' ))
1201-             ->setIgnored ()
1202-             ->setRequired ()
1203-             ->setOrdered ()
1204-             ->setReadOnly ()
1205-             ->setVerticalTermDirection ()
1206-             ->setLabel ($ this translate ('Members ' ))
1207-             ->setSuggestionUrl ($ this suggestionUrl ->with (['showCompact '  => true , '_disableLayout '  => 1 ]))
1208-             ->on (TermInput::ON_ENRICH , $ termValidator
1209-             ->on (TermInput::ON_ADD , $ termValidator
1210-             ->on (TermInput::ON_SAVE , $ termValidator
1211-             ->on (TermInput::ON_PASTE , $ termValidator
1212-         $ this addElement ($ members
1213- 
1214-         // TODO: TermInput is not compatible with the new decorators yet: https://github.com/Icinga/ipl-web/pull/317 
1215-         $ legacyDecoratornew  IcingaFormDecorator ();
1216-         $ memberssetDefaultElementDecorator ($ legacyDecorator
1217-         $ legacyDecoratordecorate ($ members
1218- 
12191237        $ this addElement ('submit ' , 'submit ' , [
12201238            'label '  => $ this getSubmitLabel ()
12211239        ]);
@@ -1243,7 +1261,7 @@ function ($value, $validator) use ($earliestHandoff, $firstHandoff, $latestHando
12431261            $ this getElement ('submit ' )->prependWrapper ((new  HtmlDocument ())->setHtmlContent (...$ removeButtons
12441262        }
12451263
1246-         $ this addElement ( $ this -> createCsrfCounterMeasure ( Session::getSession ()->getId () ));
1264+         $ this addCsrfCounterMeasure ( Session::getSession ()->getId ());
12471265    }
12481266
12491267    /** 
0 commit comments