Use own form class for all dashboard types & cleanup Dashlet-/SetupNewDashboardForm classes

This commit is contained in:
Yonas Habteab 2022-05-20 16:53:20 +02:00
parent c577e2f279
commit be973d29e2
7 changed files with 57 additions and 403 deletions

View File

@ -4,11 +4,12 @@
namespace Icinga\Controllers;
use Icinga\Forms\Dashboard\HomeForm;
use Icinga\Forms\Dashboard\DashletForm;
use Icinga\Forms\Dashboard\HomePaneForm;
use Icinga\Forms\Dashboard\NewHomePaneForm;
use Icinga\Forms\Dashboard\PaneForm;
use Icinga\Forms\Dashboard\RemoveHomeForm;
use Icinga\Forms\Dashboard\RemoveDashletForm;
use Icinga\Forms\Dashboard\RemoveHomePaneForm;
use Icinga\Forms\Dashboard\RemovePaneForm;
use Icinga\Forms\Dashboard\SetupNewDashboardForm;
use Icinga\Forms\Dashboard\WelcomeForm;
use Icinga\Util\Json;
@ -100,8 +101,8 @@ class DashboardsController extends CompatController
{
$this->dashboard->load();
$paneForm = (new NewHomePaneForm($this->dashboard))
->on(NewHomePaneForm::ON_SUCCESS, function () {
$paneForm = (new HomeForm($this->dashboard))
->on(HomeForm::ON_SUCCESS, function () {
$this->redirectNow(Url::fromPath(Dashboard::BASE_ROUTE . '/settings'));
})
->handleRequest($this->getServerRequest());
@ -116,8 +117,8 @@ class DashboardsController extends CompatController
$this->dashboard->load($home);
$homeForm = (new HomePaneForm($this->dashboard))
->on(HomePaneForm::ON_SUCCESS, function () {
$homeForm = (new HomeForm($this->dashboard))
->on(HomeForm::ON_SUCCESS, function () {
$this->redirectNow(Url::fromPath(Dashboard::BASE_ROUTE . '/settings'));
})
->handleRequest($this->getServerRequest());
@ -134,8 +135,8 @@ class DashboardsController extends CompatController
$this->dashboard->load($home);
$homeForm = (new RemoveHomePaneForm($this->dashboard))
->on(RemoveHomePaneForm::ON_SUCCESS, function () {
$homeForm = (new RemoveHomeForm($this->dashboard))
->on(RemoveHomeForm::ON_SUCCESS, function () {
$this->redirectNow(Url::fromPath(Dashboard::BASE_ROUTE . '/settings'));
})
->handleRequest($this->getServerRequest());
@ -148,10 +149,10 @@ class DashboardsController extends CompatController
{
$home = $this->params->getRequired('home');
$this->dashboard->load($home);
$this->dashboard->load();
$paneForm = (new NewHomePaneForm($this->dashboard))
->on(NewHomePaneForm::ON_SUCCESS, function () {
$paneForm = (new PaneForm($this->dashboard))
->on(PaneForm::ON_SUCCESS, function () {
$this->redirectNow(Url::fromPath(Dashboard::BASE_ROUTE . '/settings'));
})
->handleRequest($this->getServerRequest());
@ -165,14 +166,14 @@ class DashboardsController extends CompatController
$home = $this->params->getRequired('home');
$pane = $this->params->getRequired('pane');
$this->dashboard->load($home);
$this->dashboard->load();
if (! $this->dashboard->getActiveHome()->hasEntry($pane)) {
$this->httpNotFound(t('Pane "%s" not found'), $pane);
}
$paneForm = (new HomePaneForm($this->dashboard))
->on(HomePaneForm::ON_SUCCESS, function () {
$paneForm = (new PaneForm($this->dashboard))
->on(PaneForm::ON_SUCCESS, function () {
$this->redirectNow(Url::fromPath(Dashboard::BASE_ROUTE . '/settings'));
})
->handleRequest($this->getServerRequest());
@ -194,9 +195,9 @@ class DashboardsController extends CompatController
$this->httpNotFound(t('Pane "%s" not found'), $paneParam);
}
$paneForm = new RemoveHomePaneForm($this->dashboard);
$paneForm = new RemovePaneForm($this->dashboard);
$paneForm->populate(['org_name' => $paneParam]);
$paneForm->on(RemoveHomePaneForm::ON_SUCCESS, function () {
$paneForm->on(RemovePaneForm::ON_SUCCESS, function () {
$this->redirectNow(Url::fromPath(Dashboard::BASE_ROUTE . '/settings'));
})->handleRequest($this->getServerRequest());
@ -208,7 +209,7 @@ class DashboardsController extends CompatController
{
$home = $this->params->getRequired('home');
$this->dashboard->load($home);
$this->dashboard->load();
$dashletForm = new DashletForm($this->dashboard);
$dashletForm->populate($this->getRequest()->getPost());
@ -473,7 +474,7 @@ class DashboardsController extends CompatController
$pane = $this->params->getRequired('pane');
$dashlet = $this->params->getRequired('dashlet');
$this->dashboard->load($home);
$this->dashboard->load();
if (! $this->dashboard->getActiveHome()->hasEntry($pane)) {
$this->httpNotFound(t('Pane "%s" not found'), $pane);

View File

@ -29,6 +29,9 @@ abstract class BaseDashboardForm extends CompatForm
*/
protected $dashboard;
/** @var Url */
protected $requestUrl;
/**
* Create a new Dashboard Form
*
@ -37,6 +40,7 @@ abstract class BaseDashboardForm extends CompatForm
public function __construct(Dashboard $dashboard)
{
$this->dashboard = $dashboard;
$this->requestUrl = Url::fromRequest();
$this->init();
}
@ -49,7 +53,7 @@ abstract class BaseDashboardForm extends CompatForm
protected function init()
{
// This is needed for the modal views
$this->setAction((string) Url::fromRequest());
$this->setAction((string) $this->requestUrl);
$this->getAttributes()->add('class', 'dashboard-form');
}
@ -71,6 +75,16 @@ abstract class BaseDashboardForm extends CompatForm
{
}
/**
* Get whether we are updating an existing widget
*
* @return bool
*/
protected function isUpdating(): bool
{
return substr($this->requestUrl->getPath(), 0, 16) === Dashboard::BASE_ROUTE . DIRECTORY_SEPARATOR . 'edit-';
}
/**
* Create custom form controls
*

View File

@ -13,7 +13,6 @@ use Icinga\Web\Notification;
use Icinga\Web\Dashboard\Dashlet;
use Icinga\Web\Dashboard\Pane;
use ipl\Html\HtmlElement;
use ipl\Web\Url;
class DashletForm extends SetupNewDashboardForm
{
@ -21,15 +20,14 @@ class DashletForm extends SetupNewDashboardForm
{
parent::init();
$this->setAction((string) Url::fromRequest());
$this->setAction((string) $this->requestUrl);
}
public function load(BaseDashboard $dashboard)
{
$home = Url::fromRequest()->getParam('home');
/** @var Dashlet $dashboard */
$this->populate(array(
'org_home' => $home,
'org_home' => $this->requestUrl->getParam('home'),
'org_pane' => $dashboard->getPane()->getName(),
'org_dashlet' => $dashboard->getName(),
'dashlet' => $dashboard->getTitle(),
@ -39,11 +37,9 @@ class DashletForm extends SetupNewDashboardForm
protected function assembleNextPageDashboardPart()
{
$requestUrl = Url::fromRequest();
$homes = $this->dashboard->getEntryKeyTitleArr();
$activeHome = $this->dashboard->getActiveHome();
$currentHome = $requestUrl->getParam('home', reset($homes));
$currentHome = $this->requestUrl->getParam('home', reset($homes));
$populatedHome = $this->getPopulatedValue('home', $currentHome);
$panes = [];
@ -62,14 +58,14 @@ class DashletForm extends SetupNewDashboardForm
} elseif ($this->dashboard->hasEntry($populatedHome)) {
$this->dashboard->loadDashboardEntries($populatedHome);
$panes = $this->dashboard->getActiveHome()->getEntryKeyTitleArr();
$panes = $this->dashboard->getEntry($populatedHome)->getEntryKeyTitleArr();
}
$this->addElement('hidden', 'org_pane', ['required' => false]);
$this->addElement('hidden', 'org_home', ['required' => false]);
$this->addElement('hidden', 'org_dashlet', ['required' => false]);
if ($this->isUpdatingADashlet()) {
if ($this->isUpdating()) {
$this->assembleDashletElements();
$this->addHtml(new HtmlElement('hr'));
@ -100,7 +96,7 @@ class DashletForm extends SetupNewDashboardForm
$this->clearPopulatedValue('pane');
}
$populatedPane = $this->getPopulatedValue('pane', $requestUrl->getParam('pane', reset($panes)));
$populatedPane = $this->getPopulatedValue('pane', $this->requestUrl->getParam('pane', reset($panes)));
$disable = empty($panes) || $populatedHome === self::CREATE_NEW_HOME;
$this->addElement('select', 'pane', [
'class' => 'autosubmit',
@ -124,11 +120,11 @@ class DashletForm extends SetupNewDashboardForm
protected function assemble()
{
if ($this->isUpdatingADashlet() || $this->getPopulatedValue('btn_next') || $this->hasBeenSent()) {
if ($this->isUpdating() || $this->getPopulatedValue('btn_next') || $this->hasBeenSent()) {
$this->assembleNextPage();
if ($this->isUpdatingADashlet()) {
$targetUrl = (clone Url::fromRequest())->setPath(Dashboard::BASE_ROUTE . '/remove-dashlet');
if ($this->isUpdating()) {
$targetUrl = (clone $this->requestUrl)->setPath(Dashboard::BASE_ROUTE . '/remove-dashlet');
$removeButton = $this->createRemoveButton($targetUrl, t('Remove Dashlet'));
$formControls = $this->createFormControls();
@ -170,21 +166,20 @@ class DashletForm extends SetupNewDashboardForm
$selectedPane = $this->getPopulatedValue('new_pane');
}
if (! $this->isUpdatingADashlet()) {
$currentHome = new DashboardHome($selectedHome);
if ($dashboard->hasEntry($currentHome->getName())) {
$currentHome = clone $dashboard->getEntry($currentHome->getName());
if ($currentHome->getName() !== $dashboard->getActiveHome()->getName()) {
$currentHome->setActive();
$currentHome->loadDashboardEntries();
}
$currentHome = new DashboardHome($selectedHome);
if ($dashboard->hasEntry($currentHome->getName())) {
$currentHome = clone $dashboard->getEntry($currentHome->getName());
if ($currentHome->getName() !== $dashboard->getActiveHome()->getName()) {
$currentHome->loadDashboardEntries();
}
}
$currentPane = new Pane($selectedPane);
if ($currentHome->hasEntry($currentPane->getName())) {
$currentPane = clone $currentHome->getEntry($currentPane->getName());
}
$currentPane = new Pane($selectedPane);
if ($currentHome->hasEntry($currentPane->getName())) {
$currentPane = clone $currentHome->getEntry($currentPane->getName());
}
if (! $this->isUpdating()) {
$customDashlet = null;
if (($dashlet = $this->getPopulatedValue('dashlet')) && ($url = $this->getPopulatedValue('url'))) {
$customDashlet = new Dashlet($dashlet, $url, $currentPane);
@ -248,21 +243,6 @@ class DashletForm extends SetupNewDashboardForm
$orgPane = $orgHome->getEntry($this->getValue('org_pane'));
$orgDashlet = $orgPane->getEntry($this->getValue('org_dashlet'));
$currentHome = new DashboardHome($selectedHome);
if ($dashboard->hasEntry($currentHome->getName())) {
$currentHome = clone $dashboard->getEntry($currentHome->getName());
$activeHome = $dashboard->getActiveHome();
if ($currentHome->getName() !== $activeHome->getName()) {
$currentHome->setActive();
$currentHome->loadDashboardEntries();
}
}
$currentPane = new Pane($selectedPane);
if ($currentHome->hasEntry($currentPane->getName())) {
$currentPane = clone $currentHome->getEntry($currentPane->getName());
}
$currentPane->setHome($currentHome);
/**
* When the user wishes to create a new dashboard pane, we have to explicitly reset the dashboard panes

View File

@ -1,152 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2022 Icinga GmbH | GPLv2+ */
namespace Icinga\Forms\Dashboard;
use Icinga\Application\Logger;
use Icinga\Web\Dashboard\Common\BaseDashboard;
use Icinga\Web\Dashboard\DashboardHome;
use Icinga\Util\DBUtils;
use Icinga\Web\Notification;
use Icinga\Web\Dashboard\Dashboard;
use ipl\Web\Url;
class HomePaneForm extends BaseDashboardForm
{
protected function assemble()
{
$titleDesc = t('Edit the title of this dashboard home');
$buttonLabel = t('Update Home');
$removeButtonLabel = t('Remove Home');
$activeHome = $this->dashboard->getActiveHome();
$requestUrl = Url::fromRequest();
$removeTargetUrl = (clone $requestUrl)->setPath(Dashboard::BASE_ROUTE . '/remove-home');
$this->addElement('hidden', 'org_name', ['required' => false]);
$this->addElement('hidden', 'org_title', ['required' => false]);
if ($requestUrl->getPath() === Dashboard::BASE_ROUTE . '/edit-pane') {
$titleDesc = t('Edit the title of this dashboard pane');
$buttonLabel = t('Update Pane');
$removeButtonLabel = t('Remove Pane');
}
$this->addElement('text', 'title', [
'required' => true,
'label' => t('Title'),
'description' => $titleDesc
]);
if ($requestUrl->getPath() === Dashboard::BASE_ROUTE . '/edit-pane') {
$removeTargetUrl = (clone $requestUrl)->setPath(Dashboard::BASE_ROUTE . '/remove-pane');
$homes = $this->dashboard->getEntryKeyTitleArr();
$populatedHome = $this->getPopulatedValue('home', $activeHome->getName());
$this->addElement('select', 'home', [
'class' => 'autosubmit',
'required' => true,
'value' => $populatedHome,
'multiOptions' => array_merge([self::CREATE_NEW_HOME => self::CREATE_NEW_HOME], $homes),
'label' => t('Assign to Home'),
'description' => t('Select a dashboard home you want to move the dashboard to.'),
]);
if (empty($homes) || $this->getPopulatedValue('home') === self::CREATE_NEW_HOME) {
$this->addElement('text', 'new_home', [
'required' => true,
'label' => t('Dashboard Home'),
'placeholder' => t('Enter dashboard home title'),
'description' => t('Enter a title for the new dashboard home.'),
]);
}
}
$formControls = $this->createFormControls();
$formControls->add([
$this->registerSubmitButton($buttonLabel),
$this->createRemoveButton($removeTargetUrl, $removeButtonLabel),
$this->createCancelButton()
]);
$this->addHtml($formControls);
}
protected function onSuccess()
{
$requestUrl = Url::fromRequest();
if ($requestUrl->getPath() === Dashboard::BASE_ROUTE . '/edit-pane') {
$orgHome = $this->dashboard->getEntry($requestUrl->getParam('home'));
$selectedHome = $this->getPopulatedValue('home');
if (! $selectedHome || $selectedHome === self::CREATE_NEW_HOME) {
$selectedHome = $this->getPopulatedValue('new_home');
}
$currentHome = new DashboardHome($selectedHome);
if ($this->dashboard->hasEntry($currentHome->getName())) {
/** @var DashboardHome $currentHome */
$currentHome = clone $this->dashboard->getEntry($currentHome->getName());
$activeHome = $this->dashboard->getActiveHome();
if ($currentHome->getName() !== $activeHome->getName()) {
$currentHome->loadDashboardEntries();
}
}
$currentPane = clone $orgHome->getEntry($this->getValue('org_name'));
$currentPane
->setHome($currentHome)
->setTitle($this->getValue('title'));
if ($orgHome->getName() !== $currentHome->getName() && $currentHome->hasEntry($currentPane->getName())) {
Notification::error(sprintf(
t('Failed to move dashboard "%s": Dashbaord pane already exists within the "%s" dashboard home'),
$currentPane->getTitle(),
$currentHome->getTitle()
));
return;
}
if ($currentHome->getName() === $orgHome->getName()) {
// There is no dashboard home diff so clear all the dashboard pane
// of the org home
$orgHome->setEntries([]);
}
$conn = DBUtils::getConn();
$conn->beginTransaction();
try {
$this->dashboard->manageEntry($currentHome);
$currentHome->manageEntry($currentPane, $orgHome);
// We have to update all the dashlet ids too sha1(username + home + pane + dashlet)
$currentPane->manageEntry($currentPane->getEntries());
$conn->commitTransaction();
} catch (\Exception $err) {
Logger::error($err);
$conn->rollBackTransaction();
}
Notification::success(sprintf(t('Updated dashboard pane "%s" successfully'), $currentPane->getTitle()));
} else {
$home = $this->dashboard->getActiveHome();
$home->setTitle($this->getValue('title'));
$this->dashboard->manageEntry($home);
Notification::success(sprintf(t('Updated dashboard home "%s" successfully'), $home->getTitle()));
}
}
public function load(BaseDashboard $dashboard)
{
$this->populate([
'org_title' => $dashboard->getTitle(),
'title' => $dashboard->getTitle(),
'org_name' => $dashboard->getName()
]);
}
}

View File

@ -1,124 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2022 Icinga GmbH | GPLv2+ */
namespace Icinga\Forms\Dashboard;
use Icinga\Web\Dashboard\Dashboard;
use Icinga\Web\Dashboard\DashboardHome;
use Icinga\Web\Dashboard\Pane;
use Icinga\Util\DBUtils;
use Icinga\Web\Notification;
use ipl\Web\Url;
class NewHomePaneForm extends BaseDashboardForm
{
public function __construct(Dashboard $dashboard)
{
parent::__construct($dashboard);
$requestUrl = Url::fromRequest();
if ($requestUrl->hasParam('home')) {
$this->populate(['home' => $requestUrl->getParam('home')]);
}
}
protected function assemble()
{
$requestUrl = Url::fromRequest();
if ($requestUrl->getPath() === Dashboard::BASE_ROUTE . '/new-pane') {
$placeHolder = t('Create new Dashboard');
$description = t('Add new dashboard to this home.');
$btnLabel = t('Add Dashboard');
} else {
$placeHolder = t('Create new Dashboard Home');
$description = t('Add new dashboard home.');
$btnLabel = t('Add Home');
}
$this->addElement('text', 'title', [
'required' => true,
'label' => t('Title'),
'placeholder' => $placeHolder,
'description' => $description
]);
if ($requestUrl->getPath() === Dashboard::BASE_ROUTE . '/new-pane') {
$homes = array_merge(
[self::CREATE_NEW_HOME => self::CREATE_NEW_HOME],
$this->dashboard->getEntryKeyTitleArr()
);
$this->addElement('select', 'home', [
'required' => true,
'class' => 'autosubmit',
'value' => $requestUrl->getParam('home', reset($homes)),
'multiOptions' => $homes,
'label' => t('Assign to Home'),
'description' => t('A dashboard home you want to assign the new dashboard to.'),
]);
if ($this->getPopulatedValue('home') === self::CREATE_NEW_HOME) {
$this->addElement('text', 'new_home', [
'required' => true,
'label' => t('Dashboard Home'),
'placeholder' => t('Enter dashboard home title'),
'description' => t('Enter a title for the new dashboard home.'),
]);
}
}
$formControls = $this->createFormControls();
$formControls->add([
$this->registerSubmitButton($btnLabel),
$this->createCancelButton()
]);
$this->addHtml($formControls);
}
protected function onSuccess()
{
$requestUrl = Url::fromRequest();
$conn = DBUtils::getConn();
if ($requestUrl->getPath() === Dashboard::BASE_ROUTE . '/new-pane') {
$selectedHome = $this->getPopulatedValue('home');
if (! $selectedHome || $selectedHome === self::CREATE_NEW_HOME) {
$selectedHome = $this->getPopulatedValue('new_home');
}
$currentHome = new DashboardHome($selectedHome);
if ($this->dashboard->hasEntry($currentHome->getName())) {
$currentHome = clone $this->dashboard->getEntry($currentHome->getName());
if ($currentHome->getName() !== $this->dashboard->getActiveHome()->getName()) {
$currentHome->setActive()->loadDashboardEntries();
}
}
$pane = new Pane($this->getPopulatedValue('title'));
$conn->beginTransaction();
try {
$this->dashboard->manageEntry($currentHome);
$currentHome->manageEntry($pane);
$conn->commitTransaction();
} catch (\Exception $err) {
$conn->rollBackTransaction();
throw $err;
}
Notification::success('Added dashboard successfully');
} else { // New home
$home = new DashboardHome($this->getPopulatedValue('title'));
if ($this->dashboard->hasEntry($home->getName())) {
Notification::error(sprintf(t('Dashboard home "%s" already exists'), $home->getName()));
return;
}
$this->dashboard->manageEntry($home);
Notification::success('Added dashboard home successfully');
}
}
}

View File

@ -1,53 +0,0 @@
<?php
/* Icinga Web 2 | (c) 2022 Icinga GmbH | GPLv2+ */
namespace Icinga\Forms\Dashboard;
use Icinga\Web\Notification;
use Icinga\Web\Dashboard\Dashboard;
use ipl\Html\HtmlElement;
use ipl\Web\Url;
class RemoveHomePaneForm extends BaseDashboardForm
{
public function hasBeenSubmitted()
{
return $this->hasBeenSent() && $this->getPopulatedValue('btn_remove');
}
protected function assemble()
{
$requestRoute = Url::fromRequest();
$label = t('Remove Home');
$message = sprintf(t('Please confirm removal of dashboard home "%s"'), $requestRoute->getParam('home'));
if ($requestRoute->getPath() === Dashboard::BASE_ROUTE . '/remove-pane') {
$label = t('Remove Pane');
$message = sprintf(t('Please confirm removal of dashboard pane "%s"'), $requestRoute->getParam('pane'));
}
$this->addHtml(HtmlElement::create('h1', null, $message));
$submit = $this->registerSubmitButton($label);
$submit->setName('btn_remove');
$this->addHtml($submit);
}
protected function onSuccess()
{
$requestUrl = Url::fromRequest();
$home = $this->dashboard->getActiveHome();
if ($requestUrl->getPath() === Dashboard::BASE_ROUTE . '/remove-home') {
$this->dashboard->removeEntry($home);
Notification::success(sprintf(t('Removed dashboard home "%s" successfully'), $home->getTitle()));
} else {
$pane = $home->getEntry($requestUrl->getParam('pane'));
$home->removeEntry($pane);
Notification::success(sprintf(t('Removed dashboard pane "%s" successfully'), $pane->getTitle()));
}
}
}

View File

@ -19,8 +19,6 @@ use ipl\Web\Widget\Icon;
class SetupNewDashboardForm extends BaseDashboardForm
{
const DATA_TOGGLE_ELEMENT = 'dashlets-list-info';
/**
* Caches all module dashlets
*
@ -83,16 +81,6 @@ class SetupNewDashboardForm extends BaseDashboardForm
self::$moduleDashlets = $chosenDashlets;
}
/**
* Get whether we are updating an existing dashlet
*
* @return bool
*/
protected function isUpdatingADashlet()
{
return Url::fromRequest()->getPath() === Dashboard::BASE_ROUTE . '/edit-dashlet';
}
/**
* Assemble the next page of the modal view
*
@ -100,7 +88,7 @@ class SetupNewDashboardForm extends BaseDashboardForm
*/
protected function assembleNextPage()
{
$strict = $this->isUpdatingADashlet() || $this->getPopulatedValue('btn_next') || ! $this->hasBeenSent();
$strict = $this->isUpdating() || $this->getPopulatedValue('btn_next') || ! $this->hasBeenSent();
$this->dumpArbitaryDashlets($strict);
$this->assembleNextPageDashboardPart();
$this->assembleNexPageDashletPart();
@ -167,7 +155,7 @@ class SetupNewDashboardForm extends BaseDashboardForm
*/
protected function assembleNexPageDashletPart()
{
if ($this->getPopulatedValue('custom_url') === 'y') {
if ($this->getPopulatedValue('custom_url') === 'y' && ! $this->isUpdating()) {
$this->addHtml(HtmlElement::create('hr'));
$this->assembleDashletElements();
}