Skip to content

Commit 3fd52c6

Browse files
authored
Merge pull request #178 from Icinga/drop-flatpickr-from-timeframe
Drop usage of `flatpickr` in `TimeframeForm`
2 parents 3fc93d3 + fe451bf commit 3fd52c6

File tree

3 files changed

+152
-42
lines changed

3 files changed

+152
-42
lines changed

application/controllers/TimeframeController.php

+7-6
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44

55
namespace Icinga\Module\Reporting\Controllers;
66

7-
use GuzzleHttp\Psr7\ServerRequest;
87
use Icinga\Module\Reporting\Database;
98
use Icinga\Module\Reporting\Timeframe;
109
use Icinga\Module\Reporting\Web\Controller;
1110
use Icinga\Module\Reporting\Web\Forms\TimeframeForm;
11+
use ipl\Web\Url;
1212

1313
class TimeframeController extends Controller
1414
{
@@ -33,13 +33,14 @@ public function editAction()
3333
'end' => $this->timeframe->getEnd()
3434
];
3535

36-
3736
$form = TimeframeForm::fromId($this->timeframe->getId())
38-
->on(TimeframeForm::ON_SUCCESS, function () {
39-
$this->redirectNow('reporting/timeframes');
40-
})
37+
->setAction((string) Url::fromRequest())
4138
->populate($values)
42-
->handleRequest(ServerRequest::fromGlobals());
39+
->on(TimeframeForm::ON_SUCCESS, function () {
40+
$this->getResponse()->setHeader('X-Icinga-Container', 'modal-content', true);
41+
42+
$this->redirectNow('__CLOSE__');
43+
})->handleRequest($this->getServerRequest());
4344

4445
$this->addContent($form);
4546
}

application/controllers/TimeframesController.php

+23-11
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
namespace Icinga\Module\Reporting\Controllers;
66

7-
use GuzzleHttp\Psr7\ServerRequest;
87
use Icinga\Module\Reporting\Database;
98
use Icinga\Module\Reporting\Web\Controller;
109
use Icinga\Module\Reporting\Web\Forms\TimeframeForm;
@@ -30,7 +29,11 @@ public function indexAction()
3029
$this->addControl(new ButtonLink(
3130
$this->translate('New Timeframe'),
3231
Url::fromPath('reporting/timeframes/new'),
33-
'plus'
32+
'plus',
33+
[
34+
'data-icinga-modal' => true,
35+
'data-no-icinga-ajax' => true
36+
]
3437
));
3538
}
3639

@@ -44,13 +47,20 @@ public function indexAction()
4447
$subject = $timeframe->name;
4548

4649
if ($canManage) {
47-
$subject = new Link($timeframe->name, Url::fromPath(
48-
'reporting/timeframe/edit',
49-
['id' => $timeframe->id]
50-
));
50+
$subject = new Link(
51+
$timeframe->name,
52+
Url::fromPath('reporting/timeframe/edit', ['id' => $timeframe->id]),
53+
[
54+
'data-icinga-modal' => true,
55+
'data-no-icinga-ajax' => true
56+
]
57+
);
5158
}
5259

53-
$tableRows[] = Html::tag('tr', null, [
60+
$tableRows[] = Html::tag('tr', [
61+
'data-icinga-modal' => true,
62+
'data-no-icinga-ajax' => true
63+
], [
5464
Html::tag('td', null, $subject),
5565
Html::tag('td', null, $timeframe->start),
5666
Html::tag('td', null, $timeframe->end),
@@ -62,7 +72,7 @@ public function indexAction()
6272
if (! empty($tableRows)) {
6373
$table = Html::tag(
6474
'table',
65-
['class' => 'common-table table-row-selectable', 'data-base-target' => '_next'],
75+
['class' => 'common-table table-row-selectable'],
6676
[
6777
Html::tag(
6878
'thead',
@@ -95,10 +105,12 @@ public function newAction()
95105
$this->addTitleTab($this->translate('New Timeframe'));
96106

97107
$form = (new TimeframeForm())
108+
->setAction((string) Url::fromRequest())
98109
->on(TimeframeForm::ON_SUCCESS, function () {
99-
$this->redirectNow('reporting/timeframes');
100-
})
101-
->handleRequest(ServerRequest::fromGlobals());
110+
$this->getResponse()->setHeader('X-Icinga-Container', 'modal-content', true);
111+
112+
$this->redirectNow('__CLOSE__');
113+
})->handleRequest($this->getServerRequest());
102114

103115
$this->addContent($form);
104116
}

library/Reporting/Web/Forms/TimeframeForm.php

+122-25
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@
44

55
namespace Icinga\Module\Reporting\Web\Forms;
66

7+
use DateTime;
8+
use Exception;
79
use Icinga\Module\Reporting\Database;
8-
use Icinga\Module\Reporting\Web\Flatpickr;
9-
use Icinga\Module\Reporting\Web\Forms\Decorator\CompatDecorator;
1010
use ipl\Html\Contract\FormSubmitElement;
11+
use ipl\Html\FormElement\LocalDateTimeElement;
12+
use ipl\Validator\CallbackValidator;
1113
use ipl\Web\Compat\CompatForm;
1214

1315
class TimeframeForm extends CompatForm
1416
{
1517
use Database;
16-
use DecoratedElement;
1718

1819
/** @var int */
1920
protected $id;
@@ -41,34 +42,123 @@ public function hasBeenSubmitted(): bool
4142

4243
protected function assemble()
4344
{
44-
$this->setDefaultElementDecorator(new CompatDecorator());
45-
4645
$this->addElement('text', 'name', [
47-
'required' => true,
48-
'label' => $this->translate('Name')
46+
'required' => true,
47+
'label' => $this->translate('Name'),
48+
'description' => $this->translate('A unique name of this timeframe')
4949
]);
5050

51-
$flatpickr = new Flatpickr();
51+
$default = new DateTime('00:00:00');
52+
$start = $this->getPopulatedValue('start', $default);
53+
if (! $start instanceof DateTime) {
54+
$datetime = DateTime::createFromFormat(LocalDateTimeElement::FORMAT, $start);
55+
if ($datetime) {
56+
$start = $datetime;
57+
}
58+
}
5259

53-
$this->addDecoratedElement($flatpickr, 'text', 'start', [
54-
'required' => true,
55-
'label' => $this->translate('Start'),
56-
'data-flatpickr-default-hour' => '00',
57-
'placeholder' => $this->translate(
58-
'Select a start date or provide a textual datetime description'
59-
),
60+
$relativeStart = $this->getPopulatedValue('relative-start', $start instanceof DateTime ? 'n' : 'y');
61+
$this->addElement('checkbox', 'relative-start', [
62+
'required' => false,
63+
'class' => 'autosubmit',
64+
'value' => $relativeStart,
65+
'label' => $this->translate('Relative Start')
6066
]);
6167

62-
$this->addDecoratedElement($flatpickr, 'text', 'end', [
63-
'required' => true,
64-
'label' => $this->translate('End'),
65-
'data-flatpickrDefaultHour' => '23',
66-
'data-flatpickrDefaultMinute' => '59',
67-
'data-flatpickrDefaultSeconds' => '59',
68-
'placeholder' => $this->translate(
69-
'Select a end date or provide a textual datetime description'
70-
),
71-
]);
68+
if ($relativeStart === 'n') {
69+
if (! $start instanceof DateTime) {
70+
$start = $default;
71+
$this->clearPopulatedValue('start');
72+
}
73+
74+
$this->addElement(
75+
new LocalDateTimeElement('start', [
76+
'required' => true,
77+
'value' => $start,
78+
'label' => $this->translate('Start'),
79+
'description' => $this->translate('Specifies the start time of this timeframe')
80+
])
81+
);
82+
} else {
83+
$this->addElement('text', 'start', [
84+
'required' => true,
85+
'label' => $this->translate('Start'),
86+
'placeholder' => $this->translate('First day of this month'),
87+
'description' => $this->translate('Specifies the start time of this timeframe'),
88+
'validators' => [
89+
new CallbackValidator(function ($value, CallbackValidator $validator) {
90+
if ($value !== null) {
91+
try {
92+
new DateTime($value);
93+
} catch (Exception $_) {
94+
$validator->addMessage($this->translate('Invalid textual date time'));
95+
96+
return false;
97+
}
98+
}
99+
100+
return true;
101+
})
102+
]
103+
]);
104+
}
105+
106+
$default = new DateTime('23:59:59');
107+
$end = $this->getPopulatedValue('end', $default);
108+
if (! $end instanceof DateTime) {
109+
$datetime = DateTime::createFromFormat(LocalDateTimeElement::FORMAT, $end);
110+
if ($datetime) {
111+
$end = $datetime;
112+
}
113+
}
114+
115+
$relativeEnd = $this->getPopulatedValue('relative-end', $end instanceof DateTime ? 'n' : 'y');
116+
if ($relativeStart === 'y') {
117+
$this->addElement('checkbox', 'relative-end', [
118+
'required' => false,
119+
'class' => 'autosubmit',
120+
'value' => $relativeEnd,
121+
'label' => $this->translate('Relative End')
122+
]);
123+
}
124+
125+
if ($relativeEnd === 'n' || $relativeStart === 'n') {
126+
if (! $end instanceof DateTime) {
127+
$end = $default;
128+
$this->clearPopulatedValue('end');
129+
}
130+
131+
$this->addElement(
132+
new LocalDateTimeElement('end', [
133+
'required' => true,
134+
'value' => $end,
135+
'label' => $this->translate('End'),
136+
'description' => $this->translate('Specifies the end time of this timeframe')
137+
])
138+
);
139+
} else {
140+
$this->addElement('text', 'end', [
141+
'required' => true,
142+
'label' => $this->translate('End'),
143+
'placeholder' => $this->translate('Last day of this month'),
144+
'description' => $this->translate('Specifies the end time of this timeframe'),
145+
'validators' => [
146+
new CallbackValidator(function ($value, CallbackValidator $validator) {
147+
if ($value !== null) {
148+
try {
149+
new DateTime($value);
150+
} catch (Exception $_) {
151+
$validator->addMessage($this->translate('Invalid textual date time'));
152+
153+
return false;
154+
}
155+
}
156+
157+
return true;
158+
})
159+
]
160+
]);
161+
}
72162

73163
$this->addElement('submit', 'submit', [
74164
'label' => $this->id === null
@@ -99,6 +189,13 @@ public function onSuccess()
99189
}
100190

101191
$values = $this->getValues();
192+
if ($values['start'] instanceof DateTime) {
193+
$values['start'] = $values['start']->format(LocalDateTimeElement::FORMAT);
194+
}
195+
196+
if ($values['end'] instanceof DateTime) {
197+
$values['end'] = $values['end']->format(LocalDateTimeElement::FORMAT);
198+
}
102199

103200
$now = time() * 1000;
104201

0 commit comments

Comments
 (0)