From 1f9d0547cda2d374d3cbcd5364629d48ee76f1f1 Mon Sep 17 00:00:00 2001 From: Yonas Habteab Date: Thu, 7 Apr 2022 17:58:29 +0200 Subject: [PATCH] Adjust dashbaord conent layouts & don't redirect when sorting only dashlets --- .../controllers/DashboardsController.php | 36 ++++++++++++++----- application/controllers/SearchController.php | 2 +- library/Icinga/Model/Dashlet.php | 12 ++++--- library/Icinga/Model/Home.php | 8 +++-- library/Icinga/Model/ModuleDashlet.php | 8 +++-- library/Icinga/Model/Pane.php | 11 +++--- library/Icinga/Model/SystemDashlet.php | 8 +++-- .../Web/Dashboard/Common/DashboardManager.php | 14 ++++---- library/Icinga/Web/Dashboard/Dashboard.php | 19 +++++----- .../Icinga/Web/Dashboard/DashboardHome.php | 4 +-- library/Icinga/Web/Dashboard/Dashlet.php | 2 +- library/Icinga/Web/Dashboard/Pane.php | 10 +++--- library/Icinga/Web/Dashboard/Settings.php | 2 +- public/css/icinga/dashboards.less | 13 ++++++- public/css/icinga/layout.less | 2 +- public/css/icinga/widgets.less | 2 +- public/js/icinga/behavior/dashboards.js | 20 +++++++---- 17 files changed, 106 insertions(+), 67 deletions(-) diff --git a/application/controllers/DashboardsController.php b/application/controllers/DashboardsController.php index d576a9535..c7506ad71 100644 --- a/application/controllers/DashboardsController.php +++ b/application/controllers/DashboardsController.php @@ -20,6 +20,7 @@ use Icinga\Web\Dashboard\Settings; use Icinga\Web\Dashboard\Setup\SetupNewDashboard; use Icinga\Web\Notification; use Icinga\Web\Widget\Tabextension\DashboardSettings; +use ipl\Html\HtmlElement; use ipl\Web\Compat\CompatController; use ipl\Web\Url; use ipl\Web\Widget\ActionLink; @@ -58,11 +59,16 @@ class DashboardsController extends CompatController })->handleRequest(ServerRequest::fromGlobals()); $this->dashboard->setWelcomeForm($welcomeForm); - } elseif (($pane = $this->getParam('pane'))) { + } else { + $pane = $this->getParam('pane'); + if (! $pane) { + $pane = $this->dashboard->getActivePane()->getName(); + } + $this->getTabs()->activate($pane); } - $this->content = $this->dashboard; + $this->addContent($this->dashboard); } /** @@ -84,16 +90,21 @@ class DashboardsController extends CompatController 'title' => $activeHome->getTitle(), 'url' => Url::fromRequest() ]); + } - // Not to render the cog icon before the above tab - $this->createTabs(); - } elseif (($pane = $this->getParam('pane'))) { - $this->createTabs(); + // Not to render the cog icon before the above tab + $this->createTabs(); + + if ($activeHome->hasEntries()) { + $pane = $this->getParam('pane'); + if (! $pane) { + $pane = $this->dashboard->getActivePane()->getName(); + } $this->dashboard->activate($pane); } - $this->content = $this->dashboard; + $this->addContent($this->dashboard); } public function editHomeAction() @@ -276,6 +287,7 @@ class DashboardsController extends CompatController $dashboards = Json::decode($dashboards['dashboardData'], true); $originals = $dashboards['originals']; + $widgetType = $dashboards['Type']; unset($dashboards['Type']); unset($dashboards['originals']); @@ -371,7 +383,13 @@ class DashboardsController extends CompatController } } - $this->redirectNow($reroutePath); + if ($widgetType !== 'Dashlets' || ($orgHome && $orgPane)) { + $this->redirectNow($reroutePath); + } + + // Just create a dummy content and ignore it, as we don't have any view scripts and aren't redirecting + $this->getResponse()->setHeader('X-Icinga-Container', 'ignore'); + $this->addContent(new HtmlElement('p')); } /** @@ -423,7 +441,7 @@ class DashboardsController extends CompatController ] )); - $this->content = new Settings($this->dashboard); + $this->addContent(new Settings($this->dashboard)); } /** diff --git a/application/controllers/SearchController.php b/application/controllers/SearchController.php index 0b8b55983..2fdba5662 100644 --- a/application/controllers/SearchController.php +++ b/application/controllers/SearchController.php @@ -17,7 +17,7 @@ class SearchController extends CompatController $searchDashboard->setUser($this->Auth()->getUser()); $this->controls->setTabs($searchDashboard->getTabs()); - $this->content = $searchDashboard->search($this->getParam('q')); + $this->addContent($searchDashboard->search($this->getParam('q'))); } public function hintAction() diff --git a/library/Icinga/Model/Dashlet.php b/library/Icinga/Model/Dashlet.php index eee06a1a2..ffb05e471 100644 --- a/library/Icinga/Model/Dashlet.php +++ b/library/Icinga/Model/Dashlet.php @@ -4,15 +4,15 @@ namespace Icinga\Model; +use Icinga\Web\Dashboard; use ipl\Orm\Model; use ipl\Orm\Relations; -use ipl\Sql\Expression; class Dashlet extends Model { public function getTableName() { - return 'dashlet'; + return Dashboard\Dashlet::TABLE; } public function getKeyName() @@ -54,11 +54,13 @@ class Dashlet extends Model public function createRelations(Relations $relations) { - $relations->belongsTo('dashboard', Pane::class); - //$relations->belongsTo('home', Home::class); + $relations->belongsTo(Dashboard\Pane::TABLE, Pane::class) + ->setCandidateKey('dashboard_id'); + //$relations->belongsTo(Dashboard\DashboardHome::TABLE, Home::class); - $relations->belongsToMany('module_dashlet', ModuleDashlet::class) + $relations->belongsToMany('icingaweb_module_dashlet', ModuleDashlet::class) ->through(SystemDashlet::class) + ->setForeignKey('dashlet_id') ->setJoinType('LEFT'); } } diff --git a/library/Icinga/Model/Home.php b/library/Icinga/Model/Home.php index ce9bd2c79..da331b16a 100644 --- a/library/Icinga/Model/Home.php +++ b/library/Icinga/Model/Home.php @@ -4,6 +4,8 @@ namespace Icinga\Model; +use Icinga\Web\Dashboard\DashboardHome; +use Icinga\Web\Dashboard; use ipl\Orm\Model; use ipl\Orm\Relations; @@ -11,7 +13,7 @@ class Home extends Model { public function getTableName() { - return 'dashboard_home'; + return DashboardHome::TABLE; } public function getKeyName() @@ -51,8 +53,8 @@ class Home extends Model public function createRelations(Relations $relations) { - $relations->hasMany('dashboard', Pane::class); + $relations->hasMany(Dashboard\Pane::TABLE, Pane::class); - //$relations->hasMany('dashlet', Dashlet::class); + //$relations->hasMany(Dashboard\Dashlet::TABLE, Dashlet::class); } } diff --git a/library/Icinga/Model/ModuleDashlet.php b/library/Icinga/Model/ModuleDashlet.php index dac1c4873..1a712a2f3 100644 --- a/library/Icinga/Model/ModuleDashlet.php +++ b/library/Icinga/Model/ModuleDashlet.php @@ -4,6 +4,7 @@ namespace Icinga\Model; +use Icinga\Web\Dashboard; use ipl\Orm\Model; use ipl\Orm\Relations; @@ -11,7 +12,7 @@ class ModuleDashlet extends Model { public function getTableName() { - return 'module_dashlet'; + return 'icingaweb_module_dashlet'; } public function getKeyName() @@ -52,13 +53,14 @@ class ModuleDashlet extends Model public function getDefaultSort() { - return ['module_dashlet.name', 'module_dashlet.priority']; + return ['name', 'priority']; } public function createRelations(Relations $relations) { - $relations->belongsToMany('dashlet', Dashlet::class) + $relations->belongsToMany(Dashboard\Dashlet::TABLE, Dashlet::class) ->through(SystemDashlet::class) + ->setForeignKey('module_dashlet_id') ->setJoinType('LEFT'); } } diff --git a/library/Icinga/Model/Pane.php b/library/Icinga/Model/Pane.php index fc843b572..2974d68ba 100644 --- a/library/Icinga/Model/Pane.php +++ b/library/Icinga/Model/Pane.php @@ -4,15 +4,15 @@ namespace Icinga\Model; +use Icinga\Web\Dashboard; use ipl\Orm\Model; use ipl\Orm\Relations; -use ipl\Sql\Expression; class Pane extends Model { public function getTableName() { - return 'dashboard'; + return Dashboard\Pane::TABLE; } public function getKeyName() @@ -48,15 +48,16 @@ class Pane extends Model public function getDefaultSort() { - return 'dashboard.name'; + return 'icingaweb_dashboard.name'; } public function createRelations(Relations $relations) { - $relations->belongsTo('home', Home::class) + $relations->belongsTo(Dashboard\DashboardHome::TABLE, Home::class) ->setCandidateKey('home_id'); - $relations->hasMany('dashlet', Dashlet::class) + $relations->hasMany(Dashboard\Dashlet::TABLE, Dashlet::class) + ->setForeignKey('dashboard_id') ->setJoinType('LEFT'); } } diff --git a/library/Icinga/Model/SystemDashlet.php b/library/Icinga/Model/SystemDashlet.php index 96bd8a717..bc64a967c 100644 --- a/library/Icinga/Model/SystemDashlet.php +++ b/library/Icinga/Model/SystemDashlet.php @@ -4,6 +4,7 @@ namespace Icinga\Model; +use Icinga\Web\Dashboard; use ipl\Orm\Model; use ipl\Orm\Relations; @@ -11,7 +12,7 @@ class SystemDashlet extends Model { public function getTableName() { - return 'dashlet_system'; + return 'icingaweb_system_dashlet'; } public function getKeyName() @@ -30,7 +31,8 @@ class SystemDashlet extends Model public function createRelations(Relations $relations) { - $relations->belongsTo('dashlet', Dashlet::class); - $relations->belongsTo('module_dashlet', ModuleDashlet::class); + $relations->belongsTo(Dashboard\Dashlet::TABLE, Dashlet::class); + $relations->belongsTo('icingaweb_module_dashlet', ModuleDashlet::class) + ->setCandidateKey('module_dashlet_id'); } } diff --git a/library/Icinga/Web/Dashboard/Common/DashboardManager.php b/library/Icinga/Web/Dashboard/Common/DashboardManager.php index e7db25689..ea4dab8bd 100644 --- a/library/Icinga/Web/Dashboard/Common/DashboardManager.php +++ b/library/Icinga/Web/Dashboard/Common/DashboardManager.php @@ -247,7 +247,7 @@ trait DashboardManager /** * Browse all enabled modules configuration file and import all dashboards - * provided by them into the DB table `module_dashlet` + * provided by them into the DB table `icingaweb_module_dashlet` * * @return void */ @@ -261,6 +261,7 @@ trait DashboardManager $pane->setTitle($dashboardPane->getLabel()); $pane->fromArray($dashboardPane->getAttributes()); + $priority = 0; foreach ($dashboardPane->getIterator()->getItems() as $dashletItem) { $uuid = self::getSHA1($module->getName() . $pane->getName() . $dashletItem->getName()); $dashlet = new Dashlet($dashletItem->getName(), $dashletItem->getUrl(), $pane); @@ -269,7 +270,7 @@ trait DashboardManager ->setUuid($uuid) ->setModule($module->getName()) ->setModuleDashlet(true) - ->setPriority($dashletItem->getPriority()); + ->setPriority($priority++); self::updateOrInsertModuleDashlet($dashlet); $pane->addEntry($dashlet); @@ -288,12 +289,9 @@ trait DashboardManager $newDashlet ->setUuid($identifier) ->setModule($module->getName()) + ->setPriority($priority++) ->setModuleDashlet(true); - if (! $newDashlet->getPriority()) { - $newDashlet->setPriority($priority); - } - self::updateOrInsertModuleDashlet($newDashlet); $priority++; } @@ -330,7 +328,7 @@ trait DashboardManager } if (! self::moduleDashletExist($dashlet)) { - self::getConn()->insert('module_dashlet', [ + self::getConn()->insert('icingaweb_module_dashlet', [ 'id' => $dashlet->getUuid(), 'name' => $dashlet->getName(), 'label' => $dashlet->getTitle(), @@ -341,7 +339,7 @@ trait DashboardManager 'priority' => $dashlet->getPriority() ]); } else { - self::getConn()->update('module_dashlet', [ + self::getConn()->update('icingaweb_module_dashlet', [ 'label' => $dashlet->getTitle(), 'url' => $dashlet->getUrl()->getRelativeUrl(), 'description' => $dashlet->getDescription(), diff --git a/library/Icinga/Web/Dashboard/Dashboard.php b/library/Icinga/Web/Dashboard/Dashboard.php index 6dfcc3870..b7f78fc9d 100644 --- a/library/Icinga/Web/Dashboard/Dashboard.php +++ b/library/Icinga/Web/Dashboard/Dashboard.php @@ -68,7 +68,7 @@ class Dashboard extends BaseHtmlElement implements DashboardEntry protected $tag = 'div'; - protected $defaultAttributes = ['class' => 'dashboard content']; + protected $defaultAttributes = ['class' => 'dashboard']; /** * The @see Tabs object for displaying displayable panes @@ -235,11 +235,10 @@ class Dashboard extends BaseHtmlElement implements DashboardEntry { $activeHome = $this->getActiveHome(); if (! $activeHome || (! $activeHome->hasEntries() && $activeHome->getName() === DashboardHome::DEFAULT_HOME)) { - $this->setAttribute('class', 'content welcome-view'); - $wrapper = HtmlElement::create('div', ['class' => 'dashboard-introduction']); + $this->setAttribute('class', 'dashboard-introduction welcome-view'); - $wrapper->addHtml(HtmlElement::create('h1', null, t('Welcome to Icinga Web 2!'))); - $wrapper->addHtml(HtmlElement::create( + $this->addHtml(HtmlElement::create('h1', null, t('Welcome to Icinga Web 2!'))); + $this->addHtml(HtmlElement::create( 'p', null, t('You will see this screen every time you log in and haven\'t created any dashboards yet.') @@ -249,25 +248,23 @@ class Dashboard extends BaseHtmlElement implements DashboardEntry 'At the moment this view is empty, but you can populate it with small portions of' . ' information called Dashlets.' ); - $wrapper->addHtml(HtmlElement::create('p', null, $message)); + $this->addHtml(HtmlElement::create('p', null, $message)); $message = t( 'Now you can either customize which dashlets to display, or use the system default dashlets.' . ' You will be always able to edit them afterwards.' ); - $wrapper->addHtml(HtmlElement::create('p', null, $message)); + $this->addHtml(HtmlElement::create('p', null, $message)); - $wrapper->addHtml($this->welcomeForm); - $this->addHtml($wrapper); + $this->addHtml($this->welcomeForm); + //$this->addHtml($wrapper); } elseif (! $activeHome->hasEntries()) { - $this->setAttribute('class', 'content'); $this->addHtml(HtmlElement::create('h1', null, t('No dashboard added to this dashboard home'))); } else { $activePane = $this->getActivePane(); $this->setAttribute('data-icinga-pane', $activeHome->getName() . '|' . $this->getActivePane()->getName()); if (! $activePane->hasEntries()) { - $this->setAttribute('class', 'content'); $this->addHtml(HtmlElement::create('h1', null, t('No dashlet added to this pane.'))); } else { foreach ($activePane->getEntries() as $dashlet) { diff --git a/library/Icinga/Web/Dashboard/DashboardHome.php b/library/Icinga/Web/Dashboard/DashboardHome.php index c7b6f5ab8..4080f4279 100644 --- a/library/Icinga/Web/Dashboard/DashboardHome.php +++ b/library/Icinga/Web/Dashboard/DashboardHome.php @@ -29,7 +29,7 @@ class DashboardHome extends BaseDashboard implements Sortable * * @var string */ - const TABLE = 'dashboard_home'; + const TABLE = 'icingaweb_dashboard_home'; /** * A type of this dashboard home @@ -139,7 +139,7 @@ class DashboardHome extends BaseDashboard implements Sortable } $this->setEntries([]); - $panes = \Icinga\Model\Pane::on(Dashboard::getConn())->utilize('home'); + $panes = \Icinga\Model\Pane::on(Dashboard::getConn())->utilize(self::TABLE); $panes ->filter(Filter::equal('home_id', $this->getUuid())) ->filter(Filter::equal('username', Dashboard::getUser()->getUsername())); diff --git a/library/Icinga/Web/Dashboard/Dashlet.php b/library/Icinga/Web/Dashboard/Dashlet.php index 78d2af887..0b086e991 100644 --- a/library/Icinga/Web/Dashboard/Dashlet.php +++ b/library/Icinga/Web/Dashboard/Dashlet.php @@ -22,7 +22,7 @@ class Dashlet extends BaseDashboard use ModuleDashlet; /** @var string Database table name */ - const TABLE = 'dashlet'; + const TABLE = 'icingaweb_dashlet'; /** * The url of this Dashlet diff --git a/library/Icinga/Web/Dashboard/Pane.php b/library/Icinga/Web/Dashboard/Pane.php index cfdde08d8..cb8d2ebdb 100644 --- a/library/Icinga/Web/Dashboard/Pane.php +++ b/library/Icinga/Web/Dashboard/Pane.php @@ -22,7 +22,7 @@ class Pane extends BaseDashboard implements Sortable { use DashboardControls; - const TABLE = 'dashboard'; + const TABLE = 'icingaweb_dashboard'; /** * A dashboard home this pane is a part of @@ -129,8 +129,8 @@ class Pane extends BaseDashboard implements Sortable public function loadDashboardEntries($name = '') { $dashlets = Model\Dashlet::on(Dashboard::getConn()) - ->utilize('dashboard') - ->with('module_dashlet'); + ->utilize(self::TABLE) + ->with('icingaweb_module_dashlet'); $dashlets->filter(Filter::equal('dashboard_id', $this->getUuid())); $this->setEntries([]); @@ -141,7 +141,7 @@ class Pane extends BaseDashboard implements Sortable 'title' => $dashlet->label, 'priority' => $dashlet->priority, 'pane' => $this, - 'description' => $dashlet->module_dashlet->description + 'description' => $dashlet->icingaweb_module_dashlet->description ]); $this->addDashlet($newDashlet); @@ -202,7 +202,7 @@ class Pane extends BaseDashboard implements Sortable } if ($systemUuid) { - $conn->insert('dashlet_system', [ + $conn->insert('icingaweb_system_dashlet', [ 'dashlet_id' => $uuid, 'module_dashlet_id' => $systemUuid ]); diff --git a/library/Icinga/Web/Dashboard/Settings.php b/library/Icinga/Web/Dashboard/Settings.php index 3e0479390..7ca9a83b1 100644 --- a/library/Icinga/Web/Dashboard/Settings.php +++ b/library/Icinga/Web/Dashboard/Settings.php @@ -12,7 +12,7 @@ use ipl\Web\Widget\ActionLink; class Settings extends BaseHtmlElement { - protected $defaultAttributes = ['class' => 'content dashboard-settings']; + protected $defaultAttributes = ['class' => 'dashboard-settings']; protected $tag = 'div'; diff --git a/public/css/icinga/dashboards.less b/public/css/icinga/dashboards.less index cc7e7adb1..6c2a1e2bb 100644 --- a/public/css/icinga/dashboards.less +++ b/public/css/icinga/dashboards.less @@ -137,6 +137,10 @@ } // Dashboard manager +:not(.dashboard) > .container > .content { + padding-top: 0; +} + .dashboard-settings { display: flex; flex-direction: column; @@ -306,8 +310,15 @@ form.icinga-form .control-group.form-controls .remove-button { } .control-group.form-controls .modal-cancel { - background-color: @low-sat-blue; + .button(); border: none; + color: @icinga-blue; + background-color: @low-sat-blue; + + &:hover { + color: @text-color-on-icinga-blue; + background-color: @icinga-blue; + } } // Drag and drop diff --git a/public/css/icinga/layout.less b/public/css/icinga/layout.less index f2a97e100..29e9cc836 100644 --- a/public/css/icinga/layout.less +++ b/public/css/icinga/layout.less @@ -183,7 +183,7 @@ // Dashboard grid .dashboard { - letter-spacing: -0.417em; + //letter-spacing: -0.417em; > .container { display: inline-block; diff --git a/public/css/icinga/widgets.less b/public/css/icinga/widgets.less index 8015537eb..20f32b8e6 100644 --- a/public/css/icinga/widgets.less +++ b/public/css/icinga/widgets.less @@ -119,7 +119,7 @@ } } -.dashboard.content > .container { +.dashboard > .container { overflow-x: auto; } diff --git a/public/js/icinga/behavior/dashboards.js b/public/js/icinga/behavior/dashboards.js index 3c4f3098a..4a59da31f 100644 --- a/public/js/icinga/behavior/dashboards.js +++ b/public/js/icinga/behavior/dashboards.js @@ -28,9 +28,10 @@ this.widgetTypes = { Dashlet : 'Dashlets', Dashboard : 'Dashboards', DashboardHome : 'Homes' }; this.on('rendered', '#main > .container', this.onRendered, this); - this.on('end', '.dashboard-settings, .dashboard-list-control, .dashlet-list-item', this.elementDropped, this); + // Registers all drop events for all the widget types + this.on('end', '.dashboard-settings', this.elementDropped, this); // This is for the normal dashboard/dashlets view - this.on('end', '.dashboard.content', this.elementDropped, this); + this.on('end', '.content > .dashboard', this.elementDropped, this); } /** @@ -49,7 +50,7 @@ return this.widgetTypes.DashboardHome; } else if (target.matches('.dashboard-item-list')) { return this.widgetTypes.Dashboard; - } else if (target.matches('.dashlet-item-list') || target.matches('.dashboard.content')) { + } else if (target.matches('.dashlet-item-list') || target.matches('.content > .dashboard')) { return this.widgetTypes.Dashlet; } @@ -98,7 +99,7 @@ pane, home; - if (orgEvt.to.matches('.dashboard.content')) { + if (orgEvt.to.matches('.content > .dashboard')) { let parentData = orgEvt.to.dataset.icingaPane.split('|', 2); home = parentData.shift(); pane = parentData.shift(); @@ -137,13 +138,18 @@ data = { dashboardData : JSON.stringify(data) }; let url = _this.icinga.config.baseUrl + '/dashboards/reorder-widgets'; - _this.icinga.loader.loadUrl(url, $('#col1'), data, 'post'); + let req = _this.icinga.loader.loadUrl(url, $('#col1'), data, 'post'); + + if (data.Type === _this.widgetTypes.Dashlet && data.originals === null) { + req.addToHistory = false; + req.scripted = true; + } } } onRendered(e) { let _this = e.data.self; - e.target.querySelectorAll('.dashboard-settings, .dashboard.content,' + e.target.querySelectorAll('.dashboard-settings, .content > .dashboard,' + ' .dashboard-item-list, .dashlet-item-list') .forEach(sortable => { let groupName = _this.getTypeFor(sortable), @@ -163,7 +169,7 @@ break; case _this.widgetTypes.Dashlet: groupName = _this.widgetTypes.Dashlet; - if (sortable.matches('.dashboard.content')) { + if (sortable.matches('.content > .dashboard')) { draggable = '> .container'; } else { draggable = '.dashlet-list-item';