mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-09-11 20:18:09 +02:00
338 lines
12 KiB
PHP
338 lines
12 KiB
PHP
<?php
|
|
|
|
/* Icinga Web 2 | (c) 2022 Icinga GmbH | GPLv2+ */
|
|
|
|
namespace Icinga\Forms\Dashboard;
|
|
|
|
use Icinga\Application\Logger;
|
|
use Icinga\Application\Modules;
|
|
use Icinga\Web\Dashboard\Dashboard;
|
|
use Icinga\Web\Dashboard\DashboardHome;
|
|
use Icinga\Web\Dashboard\Dashlet;
|
|
use Icinga\Web\Dashboard\ItemList\DashletListMultiSelect;
|
|
use Icinga\Web\Dashboard\ItemList\EmptyDashlet;
|
|
use Icinga\Web\Dashboard\Pane;
|
|
use Icinga\Util\DBUtils;
|
|
use Icinga\Web\Notification;
|
|
use ipl\Html\HtmlElement;
|
|
use ipl\Html\Text;
|
|
use ipl\Html\ValidHtml;
|
|
use ipl\Web\Url;
|
|
use ipl\Web\Widget\Icon;
|
|
|
|
class SetupNewDashboardForm extends BaseDashboardForm
|
|
{
|
|
/**
|
|
* Caches all module dashlets
|
|
*
|
|
* @var array
|
|
*/
|
|
protected $moduleDashlets = [];
|
|
|
|
/** @var bool Whether the created custom dashlets with custom url & filter already exists */
|
|
protected $customDashletAlreadyExists = false;
|
|
|
|
protected function init(): void
|
|
{
|
|
parent::init();
|
|
|
|
$this->moduleDashlets = Modules\DashletManager::getDashlets();
|
|
|
|
$this->setRedirectUrl((string) Url::fromPath(Dashboard::BASE_ROUTE));
|
|
$this->setAction($this->getRedirectUrl() . '/setup-dashboard');
|
|
}
|
|
|
|
/**
|
|
* Dump all module dashlets which are not selected by the user
|
|
*
|
|
* @param bool $strict Whether to match the populated value of the dashlet against a 'y'
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function dumpArbitaryDashlets(bool $strict = true): void
|
|
{
|
|
$chosenDashlets = [];
|
|
foreach ($this->moduleDashlets as $module => $dashlets) {
|
|
/** @var Dashlet $dashlet */
|
|
foreach ($dashlets as $dashlet) {
|
|
$element = bin2hex($dashlet->getUuid());
|
|
if ($this->getPopulatedValue($element) === 'y' || (! $strict && $this->getPopulatedValue($element))) {
|
|
$title = $this->getPopulatedValue($element);
|
|
$url = $this->getPopulatedValue($element . '_url');
|
|
$description = $this->getPopulatedValue($element . '_description');
|
|
|
|
if (! $strict && $title && $url) {
|
|
$dashlet
|
|
->setUrl($url)
|
|
->setName($title . '(' . $module . ')')
|
|
->setTitle($title)
|
|
->setDescription($description);
|
|
}
|
|
|
|
$chosenDashlets[$module][$dashlet->getName()] = $dashlet;
|
|
}
|
|
}
|
|
|
|
if (isset($chosenDashlets[$module]) && ! $this->customDashletAlreadyExists) {
|
|
// This should never ever happen, but hey, it never harms to play it save!!
|
|
$this->customDashletAlreadyExists = array_key_exists(
|
|
$this->getPopulatedValue('dashlet'),
|
|
$chosenDashlets[$module]
|
|
);
|
|
}
|
|
}
|
|
|
|
$this->moduleDashlets = $chosenDashlets;
|
|
}
|
|
|
|
/**
|
|
* Assemble the next page of the modal view
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function assembleNextPage()
|
|
{
|
|
$strict = $this->isUpdating() || $this->getPopulatedValue('btn_next') || ! $this->hasBeenSent();
|
|
$this->dumpArbitaryDashlets($strict);
|
|
|
|
$this->assembleNextPageDashboardPart();
|
|
$this->assembleNexPageDashletPart();
|
|
}
|
|
|
|
/**
|
|
* Assemble the browsed module dashlets on the initial view
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function assembleSelectDashletView()
|
|
{
|
|
if ($this->getPopulatedValue('btn_next')) {
|
|
return;
|
|
}
|
|
|
|
$emptyDashlet = new EmptyDashlet();
|
|
$emptyDashlet->setCheckBox($this->createElement('checkbox', 'custom_url', ['class' => 'sr-only']));
|
|
$emptyList = HtmlElement::create('ul', ['class' => 'dashlet-item-list'], $emptyDashlet);
|
|
|
|
$listControl = $this->createFormListControls();
|
|
$listControl->addHtml($emptyList);
|
|
|
|
$this->addHtml($listControl);
|
|
|
|
foreach ($this->moduleDashlets as $module => $dashlets) {
|
|
$listControl = $this->createFormListControls(ucfirst($module));
|
|
$list = HtmlElement::create('ul', ['class' => 'dashlet-item-list']);
|
|
|
|
/** @var Dashlet $dashlet */
|
|
foreach ($dashlets as $dashlet) {
|
|
$multi = new DashletListMultiSelect($dashlet);
|
|
$multi->setCheckBox($this->createElement(
|
|
'checkbox',
|
|
bin2hex($dashlet->getUuid()),
|
|
['class' => 'sr-only']
|
|
));
|
|
|
|
$list->addHtml($multi);
|
|
}
|
|
|
|
$this->addHtml($listControl->addHtml($list));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Assemble the dashboard part of elements on the next page
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function assembleNextPageDashboardPart()
|
|
{
|
|
$this->addElement('text', 'pane', [
|
|
'required' => true,
|
|
'label' => t('Dashboard Title'),
|
|
'description' => t('Enter a title for the new dashboard you want to add the dashlets to.')
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Assemble the dashlet part of elements on the next page
|
|
*
|
|
* @return void
|
|
*/
|
|
protected function assembleNexPageDashletPart()
|
|
{
|
|
if ((empty($this->moduleDashlets) || $this->getPopulatedValue('custom_url') === 'y') && ! $this->isUpdating()) {
|
|
$this->addHtml(HtmlElement::create('hr'));
|
|
$this->assembleDashletElements();
|
|
}
|
|
|
|
foreach ($this->moduleDashlets as $_ => $dashlets) {
|
|
/** @var Dashlet $dashlet */
|
|
foreach ($dashlets as $dashlet) {
|
|
$this->addHtml(HtmlElement::create('h3', null, t($dashlet->getTitle())));
|
|
|
|
$elementId = bin2hex($dashlet->getUuid());
|
|
if ($this->getPopulatedValue('btn_next')) {
|
|
$this->clearPopulatedValue($elementId);
|
|
}
|
|
|
|
$this->addElement('text', $elementId, [
|
|
'required' => true,
|
|
'label' => t('Dashlet Title'),
|
|
'value' => $dashlet->getTitle(),
|
|
'description' => t('Enter a title for the dashlet'),
|
|
]);
|
|
|
|
$this->addElement('textarea', $elementId . '_url', [
|
|
'required' => true,
|
|
'label' => t('Url'),
|
|
'value' => $dashlet->getUrl()->getRelativeUrl(),
|
|
'description' => t(
|
|
'Enter url to be loaded in the dashlet. You can paste the full URL, including filters.'
|
|
)
|
|
]);
|
|
|
|
$this->addElement('textarea', $elementId . '_description', [
|
|
'label' => t('Description'),
|
|
'value' => $dashlet->getDescription(),
|
|
'description' => t('Enter description for the dashlet.')
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function assembleDashletElements()
|
|
{
|
|
$this->addElement('hidden', 'custom_url', ['required' => false, 'value' => 'y']);
|
|
$this->addElement('text', 'dashlet', [
|
|
'required' => true,
|
|
'label' => t('Dashlet Title'),
|
|
'placeholder' => t('Enter a dashlet title'),
|
|
'description' => t('Enter a title for the dashlet.'),
|
|
]);
|
|
|
|
$this->addElement('textarea', 'url', [
|
|
'required' => true,
|
|
'label' => t('Url'),
|
|
'placeholder' => t('Enter dashlet url'),
|
|
'description' => t(
|
|
'Enter url to be loaded in the dashlet. You can paste the full URL, including filters.'
|
|
),
|
|
]);
|
|
|
|
$this->addElement('textarea', 'description', [
|
|
'label' => t('Description'),
|
|
'placeholder' => t('Enter dashlet description'),
|
|
'description' => t('Enter description for the dashlet.'),
|
|
]);
|
|
}
|
|
|
|
protected function assemble()
|
|
{
|
|
if ($this->getPopulatedValue('btn_next')) { // Configure Dashlets
|
|
$submitButtonLabel = t('Add Dashlets');
|
|
$this->assembleNextPage();
|
|
} else {
|
|
$submitButtonLabel = t('Next');
|
|
$this->assembleSelectDashletView();
|
|
}
|
|
|
|
$submitButton = $this->registerSubmitButton($submitButtonLabel);
|
|
if (! $this->getPopulatedValue('btn_next')) {
|
|
$submitButton
|
|
->setName('btn_next')
|
|
->getAttributes()->add('class', 'autosubmit');
|
|
}
|
|
|
|
$formControls = $this->createFormControls();
|
|
$formControls->addHtml($submitButton, $this->createCancelButton());
|
|
|
|
$this->addHtml($formControls);
|
|
}
|
|
|
|
protected function onSuccess()
|
|
{
|
|
if ($this->getPopulatedValue('submit')) {
|
|
$conn = DBUtils::getConn();
|
|
$pane = new Pane($this->getPopulatedValue('pane'));
|
|
$home = $this->dashboard->getEntry(DashboardHome::DEFAULT_HOME);
|
|
|
|
$conn->beginTransaction();
|
|
|
|
try {
|
|
$this->dashboard->manageEntry($home);
|
|
$home->manageEntry($pane);
|
|
|
|
$this->dumpArbitaryDashlets(false);
|
|
|
|
if (($name = $this->getPopulatedValue('dashlet')) && ($url = $this->getPopulatedValue('url'))) {
|
|
if ($this->customDashletAlreadyExists) {
|
|
Notification::error(sprintf(
|
|
t('Failed to create custom Dashlet! The selected module Dashlet(s) contains Dashlet "%s"'),
|
|
$name
|
|
));
|
|
|
|
return;
|
|
}
|
|
|
|
$dashlet = new Dashlet($name, $url, $pane);
|
|
$pane->manageEntry($dashlet);
|
|
}
|
|
|
|
$pane->manageEntry($this->moduleDashlets);
|
|
|
|
$conn->commitTransaction();
|
|
} catch (\Exception $err) {
|
|
$conn->rollBackTransaction();
|
|
|
|
Logger::error('Unable to create new Dashlet(s). An unexpected error occurred: %s', $err);
|
|
|
|
Notification::error(t('Failed to create new Dashlet(s). Please check the logs for details!'));
|
|
|
|
return;
|
|
}
|
|
|
|
$this->requestSucceeded = true;
|
|
|
|
$count = $pane->countEntries();
|
|
$dashlet = $pane->getEntries();
|
|
$dashlet = end($dashlet);
|
|
|
|
Notification::success(sprintf(
|
|
tp('Added Dashlet %s successfully', 'Added %d Dashlets successfully', $count),
|
|
$count === 1 ? $dashlet->getTitle() : $count
|
|
));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create form list controls (can be collapsible if you want)
|
|
*
|
|
* @param ?string $title
|
|
*
|
|
* @return ValidHtml
|
|
*/
|
|
protected function createFormListControls(string $title = null): ValidHtml
|
|
{
|
|
$controlGroup = HtmlElement::create('div', ['class' => 'control-group']);
|
|
if ($title === null) {
|
|
return $controlGroup;
|
|
}
|
|
|
|
$details = HtmlElement::create('details', [
|
|
'class' => ['dashboard-list-control', 'collapsible'],
|
|
'data-no-persistence' => true
|
|
]);
|
|
$summary = HtmlElement::create('summary', ['class' => 'collapsible-header']);
|
|
$summary->addHtml(
|
|
new Icon('angle-right', ['class' => 'expand-icon', 'title' => t('Expand')]),
|
|
new Icon('angle-down', ['class' => 'collapse-icon', 'title' => t('Collapse')]),
|
|
Text::create($title)
|
|
);
|
|
|
|
$details->addHtml($summary);
|
|
$details->prependWrapper($controlGroup);
|
|
|
|
return $details;
|
|
}
|
|
}
|