diff --git a/application/controllers/ReportController.php b/application/controllers/ReportController.php index c400ded8..2d03f18d 100644 --- a/application/controllers/ReportController.php +++ b/application/controllers/ReportController.php @@ -15,6 +15,7 @@ use Icinga\Module\Reporting\Web\Forms\SendForm; use Icinga\Module\Reporting\Web\Widget\CompatDropdown; use ipl\Html\Error; +use ipl\Html\Form; use ipl\Web\Url; use ipl\Web\Widget\ActionBar; use Icinga\Util\Environment; @@ -59,12 +60,12 @@ public function editAction() 'timeframe' => (string) $this->report->getTimeframe()->getId(), ]; - $reportlet = $this->report->getReportlets()[0]; + foreach ($this->report->getReportlets() as $key => $reportlet) { + $values['reportlet'][$key]['reportlet_class'] = $reportlet->getClass(); - $values['reportlet'] = $reportlet->getClass(); - - foreach ($reportlet->getConfig() as $name => $value) { - $values[$name] = $value; + foreach ($reportlet->getConfig() as $name => $value) { + $values['reportlet'][$key][$name] = $value; + } } $form = ReportForm::fromId($this->report->getId()) diff --git a/library/Reporting/Report.php b/library/Reporting/Report.php index cecc4ec7..fe496c7c 100644 --- a/library/Reporting/Report.php +++ b/library/Reporting/Report.php @@ -72,37 +72,41 @@ public static function fromDb($id) ->columns('*') ->where(['report_id = ?' => $id]); - $row = $db->select($select)->fetch(); + $row = $db->select($select)->fetchAll(); if ($row === false) { throw new Exception('No reportlets configured.'); } - $reportlet = new Reportlet(); + $reportlets = []; + foreach ($row as $reportletRow) { + $reportlet = new Reportlet(); - $reportlet - ->setId($row->id) - ->setClass($row->class); + $reportlet + ->setId($reportletRow->id) + ->setClass($reportletRow->class); - $select = (new Sql\Select()) - ->from('config') - ->columns('*') - ->where(['reportlet_id = ?' => $row->id]); + $select = (new Sql\Select()) + ->from('config') + ->columns('*') + ->where(['reportlet_id = ?' => $reportletRow->id]); - $rows = $db->select($select)->fetchAll(); + $rows = $db->select($select)->fetchAll(); - $config = [ - 'name' => $report->getName(), - 'id' => $report->getId() - ]; + $config = [ + 'name' => $report->getName(), + 'id' => $report->getId() + ]; - foreach ($rows as $row) { - $config[$row->name] = $row->value; - } + foreach ($rows as $row) { + $config[$row->name] = $row->value; + } - $reportlet->setConfig($config); + $reportlet->setConfig($config); - $report->setReportlets([$reportlet]); + $reportlets[] = $reportlet; + } + $report->setReportlets($reportlets); $select = (new Sql\Select()) ->from('schedule') diff --git a/library/Reporting/Web/Forms/ReportForm.php b/library/Reporting/Web/Forms/ReportForm.php index 7be7bad6..98bbc656 100644 --- a/library/Reporting/Web/Forms/ReportForm.php +++ b/library/Reporting/Web/Forms/ReportForm.php @@ -6,11 +6,15 @@ use Icinga\Authentication\Auth; use Icinga\Module\Reporting\Database; +use Icinga\Module\Reporting\Hook\ReportHook; use Icinga\Module\Reporting\ProvidedReports; use Icinga\Module\Reporting\Web\Forms\Decorator\CompatDecorator; use ipl\Html\Contract\FormSubmitElement; use ipl\Html\Form; +use ipl\Html\FormElement\Collection; use ipl\Web\Compat\CompatForm; +use ipl\Web\FormDecorator\IcingaFormDecorator; +use ipl\Web\Widget\Icon; class ReportForm extends CompatForm { @@ -39,6 +43,15 @@ public function hasBeenSubmitted(): bool return $this->hasBeenSent() && ($this->getPopulatedValue('submit') || $this->getPopulatedValue('remove')); } + public function __construct() + { + $this->on(static::ON_SENT, function () { + if ($this->getPressedSubmitElement() && $this->getPressedSubmitElement()->getName() === 'remove') { + $this->getDb()->delete('report', ['id = ?' => $this->id]); + } + }); + } + protected function assemble() { $this->setDefaultElementDecorator(new CompatDecorator()); @@ -70,38 +83,63 @@ protected function assemble() ) ]); - $this->addElement('select', 'reportlet', [ - 'required' => true, - 'class' => 'autosubmit', - 'label' => $this->translate('Report'), - 'options' => [null => $this->translate('Please choose')] + $this->listReports(), - 'description' => $this->translate('Specifies the type of the reportlet to be generated') - ]); + $collection = (new Collection('reportlet')) + ->setLabel('Reportlets') + ->setAddElement('select', 'reportlet_class', [ + 'required' => false, + 'label' => 'Reportlet', + 'options' => [null => 'Please choose'] + $this->listReports(), + 'class' => 'autosubmit' + ]) + ->setRemoveElement('submitButton', 'remove_reportlet', [ + 'label' => new Icon('trash'), + 'class' => 'btn-remove-reportlet', + 'formnovalidate' => true, + 'title' => 'Remove Reportlet' + ]); - $values = $this->getValues(); + $collection->onAssembleGroup(function ($group, $addElement, $removeElement) { + $group->setDefaultElementDecorator(new IcingaFormDecorator()); + + $this->decorate($addElement); + + $group + ->registerElement($addElement) + ->addHtml($addElement) + ->registerElement($removeElement); + + $addElement->getWrapper()->ensureAssembled()->add($removeElement); - if (isset($values['reportlet'])) { - $config = new Form(); -// $config->populate($this->getValues()); + $reportletClass = $group->getPopulatedValue('reportlet_class'); + if (! empty($reportletClass)) { + $config = new Form(); - /** @var \Icinga\Module\Reporting\Hook\ReportHook $reportlet */ - $reportlet = new $values['reportlet'](); + /** @var ReportHook $reportlet */ + $reportlet = new $reportletClass(); + $reportlet->initConfigForm($config); - $reportlet->initConfigForm($config); + foreach ($config->getElements() as $element) { + $this->decorate($element); - foreach ($config->getElements() as $element) { - $this->addElement($element); + $group + ->registerElement($element) + ->addHtml($element); + } } - } + }); + + $this->registerElement($collection); + $this->add($collection); $this->addElement('submit', 'submit', [ - 'label' => $this->id === null ? $this->translate('Create Report') : $this->translate('Update Report') + 'label' => $this->id === null ? 'Create Report' : 'Update Report' ]); + $this->setSubmitButton($this->getElement('submit')); if ($this->id !== null) { /** @var FormSubmitElement $removeButton */ $removeButton = $this->createElement('submit', 'remove', [ - 'label' => $this->translate('Remove Report'), + 'label' => 'Remove Report', 'class' => 'btn-remove', 'formnovalidate' => true ]); @@ -148,32 +186,43 @@ public function onSuccess() $reportId = $this->id; } - unset($values['name']); - unset($values['timeframe']); - if ($this->id !== null) { $db->delete('reportlet', ['report_id = ?' => $reportId]); } - $db->insert('reportlet', [ - 'report_id' => $reportId, - 'class' => $values['reportlet'], - 'ctime' => $now, - 'mtime' => $now - ]); - - $reportletId = $db->lastInsertId(); + foreach ($this->getPopulatedValue('reportlet') as $reportlet) { + array_walk($reportlet, function (&$value) { + if ($value === '') { + $value = null; + } + }); - unset($values['reportlet']); + if (empty($reportlet['reportlet_class'])) { + continue; + } - foreach ($values as $name => $value) { - $db->insert('config', [ - 'reportlet_id' => $reportletId, - 'name' => $name, - 'value' => $value, - 'ctime' => $now, - 'mtime' => $now + $db->insert('reportlet', [ + 'report_id' => $reportId, + 'class' => $reportlet['reportlet_class'], + 'ctime' => $now, + 'mtime' => $now ]); + + $reportletId = $db->lastInsertId(); + + foreach ($reportlet as $key => $value) { + if ($key === 'reportlet_class') { + continue; + } + + $db->insert('config', [ + 'reportlet_id' => $reportletId, + 'name' => $key, + 'value' => $value, + 'ctime' => $now, + 'mtime' => $now + ]); + } } $db->commitTransaction(); diff --git a/public/css/module.less b/public/css/module.less index 49cc4e5c..a5ac6d53 100644 --- a/public/css/module.less +++ b/public/css/module.less @@ -76,7 +76,7 @@ &:hover > .dropdown-menu { display: block; - box-shadow: 0 0 2em 0 rgba(0,0,0,.2); + box-shadow: 0 0 2em 0 rgba(0, 0, 0, .2); } .dropdown-item { @@ -110,7 +110,7 @@ .page-size-a4 { background-color: white; - box-shadow: 0 0 0.25cm rgba(0,0,0,0.5); + box-shadow: 0 0 0.25cm rgba(0, 0, 0, 0.5); display: block; margin: 0 auto 0.5cm; font-family: @font-family-print; @@ -213,3 +213,32 @@ form.icinga-form { } /* Form fallback styles end */ + +.collection { + legend { + width: 100%; + border-bottom: 1px solid @gray-lighter; + } + + .form-element-collection { + border-bottom: 1px solid @gray-lighter; + + .btn-remove-reportlet { + background-color: @low-sat-blue !important; + color: @color-critical !important; + border: 0; + height: 27px; + width: 27px; + padding: 8px; + + &:hover { + background-color: @low-sat-blue-dark !important; + } + } + + &:last-child { + border-bottom: 0; + } + } +} +