mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-09-25 18:59:04 +02:00
DashletForm: Add support for the new dashboards and make use of ipl form
This commit is contained in:
parent
051c33b5df
commit
aea82b5942
@ -1,171 +1,305 @@
|
||||
<?php
|
||||
/* Icinga Web 2 | (c) 2013 Icinga Development Team | GPLv2+ */
|
||||
|
||||
/* Icinga Web 2 | (c) 2013-2022 Icinga GmbH | GPLv2+ */
|
||||
|
||||
namespace Icinga\Forms\Dashboard;
|
||||
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Form\Validator\InternalUrlValidator;
|
||||
use Icinga\Web\Form\Validator\UrlValidator;
|
||||
use Icinga\Web\Url;
|
||||
use Icinga\Web\Widget\Dashboard;
|
||||
use Icinga\Web\Widget\Dashboard\Dashlet;
|
||||
use Icinga\Application\Logger;
|
||||
use Icinga\Web\Dashboard\Dashboard;
|
||||
use Icinga\Web\Navigation\DashboardHome;
|
||||
use Icinga\Web\Notification;
|
||||
use Icinga\Web\Dashboard\Dashlet;
|
||||
use Icinga\Web\Dashboard\Pane;
|
||||
use ipl\Html\HtmlElement;
|
||||
use ipl\Web\Compat\CompatForm;
|
||||
use ipl\Web\Url;
|
||||
|
||||
/**
|
||||
* Form to add an url a dashboard pane
|
||||
*/
|
||||
class DashletForm extends Form
|
||||
class DashletForm extends CompatForm
|
||||
{
|
||||
/**
|
||||
* @var Dashboard
|
||||
*/
|
||||
private $dashboard;
|
||||
|
||||
/**
|
||||
* Initialize this form
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setName('form_dashboard_addurl');
|
||||
if (! $this->getSubmitLabel()) {
|
||||
$this->setSubmitLabel($this->translate('Add To Dashboard'));
|
||||
}
|
||||
$this->setAction(Url::fromRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* Build AddUrl form elements
|
||||
*
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$groupElements = array();
|
||||
$panes = array();
|
||||
|
||||
if ($this->dashboard) {
|
||||
$panes = $this->dashboard->getPaneKeyTitleArray();
|
||||
}
|
||||
|
||||
$sectionNameValidator = ['Callback', true, [
|
||||
'callback' => function ($value) {
|
||||
if (strpos($value, '[') === false && strpos($value, ']') === false) {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
'messages' => [
|
||||
'callbackValue' => $this->translate('Brackets ([, ]) cannot be used here')
|
||||
]
|
||||
]];
|
||||
|
||||
$this->addElement(
|
||||
'hidden',
|
||||
'org_pane',
|
||||
array(
|
||||
'required' => false
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'hidden',
|
||||
'org_dashlet',
|
||||
array(
|
||||
'required' => false
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'textarea',
|
||||
'url',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => $this->translate('Url'),
|
||||
'description' => $this->translate(
|
||||
'Enter url to be loaded in the dashlet. You can paste the full URL, including filters.'
|
||||
),
|
||||
'validators' => array(new UrlValidator(), new InternalUrlValidator())
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'text',
|
||||
'dashlet',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => $this->translate('Dashlet Title'),
|
||||
'description' => $this->translate('Enter a title for the dashlet.'),
|
||||
'validators' => [$sectionNameValidator]
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'note',
|
||||
'note',
|
||||
array(
|
||||
'decorators' => array(
|
||||
array('HtmlTag', array('tag' => 'hr'))
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'create_new_pane',
|
||||
array(
|
||||
'autosubmit' => true,
|
||||
'required' => false,
|
||||
'label' => $this->translate('New dashboard'),
|
||||
'description' => $this->translate('Check this box if you want to add the dashlet to a new dashboard')
|
||||
)
|
||||
);
|
||||
if (empty($panes) || ((isset($formData['create_new_pane']) && $formData['create_new_pane'] != false))) {
|
||||
$this->addElement(
|
||||
'text',
|
||||
'pane',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => $this->translate('New Dashboard Title'),
|
||||
'description' => $this->translate('Enter a title for the new dashboard'),
|
||||
'validators' => [$sectionNameValidator]
|
||||
)
|
||||
);
|
||||
} else {
|
||||
$this->addElement(
|
||||
'select',
|
||||
'pane',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => $this->translate('Dashboard'),
|
||||
'multiOptions' => $panes,
|
||||
'description' => $this->translate('Select a dashboard you want to add the dashlet to')
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Icinga\Web\Widget\Dashboard $dashboard
|
||||
*/
|
||||
public function setDashboard(Dashboard $dashboard)
|
||||
public function __construct(Dashboard $dashboard)
|
||||
{
|
||||
$this->dashboard = $dashboard;
|
||||
|
||||
$this->setAction((string) Url::fromRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Icinga\Web\Widget\Dashboard
|
||||
*/
|
||||
public function getDashboard()
|
||||
public function hasBeenSubmitted()
|
||||
{
|
||||
return $this->dashboard;
|
||||
return $this->hasBeenSent() && $this->getPopulatedValue('submit');
|
||||
}
|
||||
|
||||
protected function assemble()
|
||||
{
|
||||
$requestUrl = Url::fromRequest();
|
||||
|
||||
$homes = $this->dashboard->getHomeKeyTitleArr();
|
||||
$activeHome = $this->dashboard->getActiveHome();
|
||||
$currentHome = $requestUrl->getParam('home', reset($homes));
|
||||
$populatedHome = $this->getPopulatedValue('home', $currentHome);
|
||||
|
||||
$panes = [];
|
||||
if ($currentHome === $populatedHome && $this->getPopulatedValue('create_new_home') !== 'y') {
|
||||
if (! $currentHome || ! $activeHome) {
|
||||
// Home param isn't passed through, so let's try to load based on the first home
|
||||
$firstHome = $this->dashboard->rewindHomes();
|
||||
if ($firstHome) {
|
||||
$this->dashboard->loadDashboards($firstHome->getName());
|
||||
|
||||
$panes = $firstHome->getPaneKeyTitleArr();
|
||||
}
|
||||
} else {
|
||||
$panes = $activeHome->getPaneKeyTitleArr();
|
||||
}
|
||||
} elseif ($this->dashboard->hasHome($populatedHome)) {
|
||||
$this->dashboard->loadDashboards($populatedHome);
|
||||
|
||||
$panes = $this->dashboard->getActiveHome()->getPaneKeyTitleArr();
|
||||
}
|
||||
|
||||
$this->addElement('hidden', 'org_pane', ['required' => false]);
|
||||
$this->addElement('hidden', 'org_home', ['required' => false]);
|
||||
$this->addElement('hidden', 'org_dashlet', ['required' => false]);
|
||||
|
||||
$this->addElement('checkbox', 'create_new_home', [
|
||||
'class' => 'autosubmit',
|
||||
'required' => false,
|
||||
'disabled' => empty($homes) ?: null,
|
||||
'label' => t('New Dashboard Home'),
|
||||
'description' => t('Check this box if you want to add the dashboard to a new dashboard home.'),
|
||||
]);
|
||||
|
||||
if (empty($homes) || $this->getPopulatedValue('create_new_home') === 'y') {
|
||||
// $el->attrs->set() has no effect here anymore, so we need to register a proper callback
|
||||
$this->getElement('create_new_home')
|
||||
->getAttributes()
|
||||
->registerAttributeCallback('checked', function () { return true; });
|
||||
|
||||
$this->addElement('text', 'home', [
|
||||
'required' => true,
|
||||
'label' => t('Dashboard Home'),
|
||||
'description' => t('Enter a title for the new dashboard home.')
|
||||
]);
|
||||
} else {
|
||||
$this->addElement('select', 'home', [
|
||||
'required' => true,
|
||||
'class' => 'autosubmit',
|
||||
'value' => $currentHome,
|
||||
'multiOptions' => $homes,
|
||||
'label' => t('Dashboard Home'),
|
||||
'descriptions' => t('Select a home you want to add the dashboard pane to.')
|
||||
]);
|
||||
}
|
||||
|
||||
$disable = empty($panes) || $this->getPopulatedValue('create_new_home') === 'y';
|
||||
$this->addElement('checkbox', 'create_new_pane', [
|
||||
'required' => false,
|
||||
'class' => 'autosubmit',
|
||||
'disabled' => $disable ?: null,
|
||||
'label' => t('New Dashboard'),
|
||||
'description' => t('Check this box if you want to add the dashlet to a new dashboard.'),
|
||||
]);
|
||||
|
||||
// Pane element's values are depending on the home element's value
|
||||
if (! in_array($this->getPopulatedValue('pane'), $panes)) {
|
||||
$this->clearPopulatedValue('pane');
|
||||
}
|
||||
|
||||
if ($disable || $this->getValue('create_new_pane') === 'y') {
|
||||
// $el->attrs->set() has no effect here anymore, so we need to register a proper callback
|
||||
$this->getElement('create_new_pane')
|
||||
->getAttributes()
|
||||
->registerAttributeCallback('checked', function () { return true; });
|
||||
|
||||
$this->addElement('text', 'pane', [
|
||||
'required' => true,
|
||||
'label' => t('New Dashboard Title'),
|
||||
'description' => t('Enter a title for the new dashboard.'),
|
||||
]);
|
||||
} else {
|
||||
$this->addElement('select', 'pane', [
|
||||
'required' => true,
|
||||
'value' => reset($panes),
|
||||
'multiOptions' => $panes,
|
||||
'label' => t('Dashboard'),
|
||||
'description' => t('Select a dashboard you want to add the dashlet to.'),
|
||||
]);
|
||||
}
|
||||
|
||||
$this->addHtml(new HtmlElement('hr'));
|
||||
|
||||
$this->addElement('textarea', 'url', [
|
||||
'required' => true,
|
||||
'label' => t('Url'),
|
||||
'description' => t(
|
||||
'Enter url to be loaded in the dashlet. You can paste the full URL, including filters.'
|
||||
),
|
||||
]);
|
||||
|
||||
$this->addElement('text', 'dashlet', [
|
||||
'required' => true,
|
||||
'label' => t('Dashlet Title'),
|
||||
'description' => t('Enter a title for the dashlet.'),
|
||||
]);
|
||||
|
||||
$url = (string) Url::fromPath(Dashboard::BASE_ROUTE . '/browse');
|
||||
|
||||
$element = $this->createElement('submit', 'submit', ['label' => t('Add to Dashboard')]);
|
||||
$this->registerElement($element)->decorate($element);
|
||||
|
||||
// We might need this later to allow the user to browse dashlets when creating a dashlet
|
||||
$this->addElement('submit', 'btn_browse', [
|
||||
'label' => t('Browse Dashlets'),
|
||||
'href' => $url,
|
||||
'formaction' => $url,
|
||||
]);
|
||||
|
||||
$this->getElement('btn_browse')->setWrapper($element->getWrapper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate form data from config
|
||||
*
|
||||
* @param Dashlet $dashlet
|
||||
*/
|
||||
public function load(Dashlet $dashlet)
|
||||
{
|
||||
$home = Url::fromRequest()->getParam('home');
|
||||
$this->populate(array(
|
||||
'pane' => $dashlet->getPane()->getTitle(),
|
||||
'org_home' => $home,
|
||||
'org_pane' => $dashlet->getPane()->getName(),
|
||||
'dashlet' => $dashlet->getTitle(),
|
||||
'pane' => $dashlet->getPane()->getTitle(),
|
||||
'org_dashlet' => $dashlet->getName(),
|
||||
'dashlet' => $dashlet->getTitle(),
|
||||
'url' => $dashlet->getUrl()->getRelativeUrl()
|
||||
));
|
||||
}
|
||||
|
||||
protected function onSuccess()
|
||||
{
|
||||
$conn = Dashboard::getConn();
|
||||
$dashboard = $this->dashboard;
|
||||
|
||||
if (Url::fromRequest()->getPath() === Dashboard::BASE_ROUTE . '/new-dashlet') {
|
||||
$home = new DashboardHome($this->getValue('home'));
|
||||
if ($dashboard->hasHome($home->getName())) {
|
||||
$home = $dashboard->getHome($home->getName());
|
||||
if ($home->getName() !== $dashboard->getActiveHome()->getName()) {
|
||||
$home->setActive();
|
||||
$home->loadDashboardsFromDB();
|
||||
}
|
||||
}
|
||||
|
||||
$pane = new Pane($this->getValue('pane'));
|
||||
if ($home->hasPane($pane->getName())) {
|
||||
$pane = $home->getPane($pane->getName());
|
||||
}
|
||||
|
||||
$dashlet = new Dashlet($this->getValue('dashlet'), $this->getValue('url'), $pane);
|
||||
if ($pane->hasDashlet($dashlet->getName())) {
|
||||
Notification::error(sprintf(
|
||||
t('Dashlet "%s" already exists within the "%s" dashboard pane'),
|
||||
$dashlet->getTitle(),
|
||||
$pane->getTitle()
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$conn->beginTransaction();
|
||||
|
||||
try {
|
||||
$dashboard->manageHome($home);
|
||||
$home->managePanes($pane);
|
||||
$pane->manageDashlets($dashlet);
|
||||
|
||||
$conn->commitTransaction();
|
||||
} catch (\Exception $err) { // This error handling is just for debugging purpose! Will be removed!
|
||||
Logger::error($err);
|
||||
$conn->rollBackTransaction();
|
||||
|
||||
throw $err;
|
||||
}
|
||||
|
||||
Notification::success(sprintf(t('Created dashlet "%s" successfully'), $dashlet->getTitle()));
|
||||
} else {
|
||||
$orgHome = $dashboard->getHome($this->getValue('org_home'));
|
||||
$orgPane = $orgHome->getPane($this->getValue('org_pane'));
|
||||
$orgDashlet = $orgPane->getDashlet($this->getValue('org_dashlet'));
|
||||
|
||||
$currentHome = new DashboardHome($this->getValue('home'));
|
||||
if ($dashboard->hasHome($currentHome->getName())) {
|
||||
$currentHome = $dashboard->getHome($currentHome->getName());
|
||||
$activeHome = $dashboard->getActiveHome();
|
||||
if ($currentHome->getName() !== $activeHome->getName()) {
|
||||
$currentHome->setActive();
|
||||
$currentHome->loadDashboardsFromDB();
|
||||
}
|
||||
}
|
||||
|
||||
$currentPane = new Pane($this->getValue('pane'));
|
||||
if ($currentHome->hasPane($currentPane->getName())) {
|
||||
$currentPane = $currentHome->getPane($currentPane->getName());
|
||||
}
|
||||
|
||||
$currentPane->setHome($currentHome);
|
||||
|
||||
$currentDashlet = clone $orgDashlet;
|
||||
$currentDashlet
|
||||
->setPane($currentPane)
|
||||
->setUrl($this->getValue('url'))
|
||||
->setTitle($this->getValue('dashlet'));
|
||||
|
||||
if (
|
||||
$orgPane->getName() !== $currentPane->getName()
|
||||
&& $currentPane->hasDashlet($currentDashlet->getName())
|
||||
) {
|
||||
Notification::error(sprintf(
|
||||
t('Failed to move dashlet "%s": Dashlet already exists within the "%s" dashboard pane'),
|
||||
$currentDashlet->getTitle(),
|
||||
$currentPane->getTitle()
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$paneDiff = array_filter(array_diff_assoc($currentPane->toArray(), $orgPane->toArray()));
|
||||
$dashletDiff = array_filter(
|
||||
array_diff_assoc($currentDashlet->toArray(), $orgDashlet->toArray()),
|
||||
function ($val) {
|
||||
return $val !== null;
|
||||
}
|
||||
);
|
||||
|
||||
// Prevent meaningless updates when there weren't any changes,
|
||||
// e.g. when the user just presses the update button without changing anything
|
||||
if (empty($dashletDiff) && empty($paneDiff)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$conn->beginTransaction();
|
||||
|
||||
try {
|
||||
$dashboard->manageHome($currentHome);
|
||||
$currentHome->managePanes($currentPane, $orgHome);
|
||||
$currentPane->manageDashlets($currentDashlet, $orgPane);
|
||||
|
||||
$conn->commitTransaction();
|
||||
} catch (\Exception $err) {
|
||||
Logger::error($err);
|
||||
$conn->rollBackTransaction();
|
||||
|
||||
throw $err;
|
||||
}
|
||||
|
||||
Notification::success(sprintf(t('Updated dashlet "%s" successfully'), $currentDashlet->getTitle()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user