mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-07-24 14:24:41 +02:00
parent
5f9d394bbe
commit
af799d42dc
@ -20,54 +20,6 @@ use Icinga\Web\Widget\Dashboard;
|
||||
*/
|
||||
class DashboardController extends ActionController
|
||||
{
|
||||
/**
|
||||
* Default configuration
|
||||
*/
|
||||
const DEFAULT_CONFIG = 'dashboard/dashboard';
|
||||
|
||||
/**
|
||||
* Retrieve a dashboard from the provided config
|
||||
*
|
||||
* @param string $config The config to read the dashboard from, or 'dashboard/dashboard' if none is given
|
||||
*
|
||||
* @return \Icinga\Web\Widget\Dashboard
|
||||
*/
|
||||
private function getDashboard($config = self::DEFAULT_CONFIG)
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
try {
|
||||
$dashboardConfig = Config::app($config);
|
||||
if (count($dashboardConfig) === 0) {
|
||||
return null;
|
||||
}
|
||||
$dashboard->readConfig($dashboardConfig);
|
||||
} catch (NotReadableError $e) {
|
||||
Logger::error(new IcingaException('Cannot load dashboard configuration. An exception was thrown:', $e));
|
||||
return null;
|
||||
}
|
||||
return $dashboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a component from the pane identified by the 'pane' parameter
|
||||
*/
|
||||
public function removecomponentAction()
|
||||
{
|
||||
$pane = $this->_getParam('pane');
|
||||
$dashboard = $this->getDashboard();
|
||||
try {
|
||||
$dashboard->removeComponent(
|
||||
$pane,
|
||||
$this->_getParam('component')
|
||||
)->store();
|
||||
$this->redirectNow(Url::fromPath('dashboard', array('pane' => $pane)));
|
||||
} catch (ConfigurationError $exc ) {
|
||||
$this->_helper->viewRenderer('show_configuration');
|
||||
$this->view->exceptionMessage = $exc->getMessage();
|
||||
$this->view->iniConfigurationString = $dashboard->toIni();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the form for adding new components or add the new component if submitted
|
||||
*/
|
||||
@ -93,7 +45,9 @@ class DashboardController extends ActionController
|
||||
*/
|
||||
public function indexAction()
|
||||
{
|
||||
$dashboard = Dashboard::load();
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->setUser($this->getRequest()->getUser());
|
||||
$dashboard->load();
|
||||
|
||||
if (! $dashboard->hasPanes()) {
|
||||
$this->view->title = 'Dashboard';
|
||||
@ -103,8 +57,6 @@ class DashboardController extends ActionController
|
||||
$dashboard->activate($pane);
|
||||
}
|
||||
|
||||
$this->view->configPath = Config::resolvePath(self::DEFAULT_CONFIG);
|
||||
|
||||
if ($dashboard === null) {
|
||||
$this->view->title = 'Dashboard';
|
||||
} else {
|
||||
@ -125,29 +77,4 @@ class DashboardController extends ActionController
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Store the given configuration as INI file
|
||||
*
|
||||
* @param Config $config The configuration to store
|
||||
* @param string $target The path where to store the configuration
|
||||
*
|
||||
* @return bool Whether the configuartion has been successfully stored
|
||||
*/
|
||||
protected function writeConfiguration(Config $config, $target)
|
||||
{
|
||||
$writer = new IniWriter(array('config' => $config, 'filename' => $target));
|
||||
|
||||
try {
|
||||
$writer->write();
|
||||
} catch (Exception $e) {
|
||||
Logger::error(new ConfiguationError("Cannot write dashboard to $target", 0, $e));
|
||||
$this->view->configString = $writer->render();
|
||||
$this->view->errorMessage = $e->getMessage();
|
||||
$this->view->filePath = $target;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
namespace Icinga\Forms\Dashboard;
|
||||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\File\Ini\IniWriter;
|
||||
use Icinga\Web\Widget\Dashboard;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Request;
|
||||
@ -14,6 +15,13 @@ use Icinga\Web\Request;
|
||||
*/
|
||||
class AddUrlForm extends Form
|
||||
{
|
||||
/**
|
||||
* Config file name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $configFile = 'dashboard/dashboard';
|
||||
|
||||
/**
|
||||
* Initialize this form
|
||||
*/
|
||||
@ -134,16 +142,42 @@ class AddUrlForm extends Form
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a dashboard object
|
||||
*
|
||||
* @return Dashboard
|
||||
*/
|
||||
private function createDashboard()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->readConfig(Config::app($this->getConfigFile()));
|
||||
return $dashboard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the names and titles of the available dashboard panes as key-value array
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getDashboardPaneSelectionValues()
|
||||
private function getDashboardPaneSelectionValues()
|
||||
{
|
||||
$dashboard = new Dashboard();
|
||||
$dashboard->readConfig(Config::app('dashboard/dashboard'));
|
||||
return $dashboard->getPaneKeyTitleArray();
|
||||
return $this->createDashboard()->getPaneKeyTitleArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $configFile
|
||||
*/
|
||||
public function setConfigFile($configFile)
|
||||
{
|
||||
$this->configFile = $configFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getConfigFile()
|
||||
{
|
||||
return $this->configFile;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -153,6 +187,22 @@ class AddUrlForm extends Form
|
||||
*/
|
||||
public function onSuccess(Request $request)
|
||||
{
|
||||
$dashboard = $this->createDashboard();
|
||||
$dashboard->setComponentUrl(
|
||||
$this->getValue('pane'),
|
||||
$this->getValue('component'),
|
||||
ltrim($this->getValue('url'), '/')
|
||||
);
|
||||
/*
|
||||
$writer = new IniWriter(
|
||||
array(
|
||||
'config' => new Config($dashboard->toArray()),
|
||||
'filename' => $dashboard->getConfig()->getConfigFile()
|
||||
)
|
||||
);
|
||||
|
||||
$writer->write();
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -163,6 +213,9 @@ class AddUrlForm extends Form
|
||||
*/
|
||||
public function onRequest(Request $request)
|
||||
{
|
||||
|
||||
$data = array(
|
||||
'url' => $request->getParam('url')
|
||||
);
|
||||
$this->populate($data);
|
||||
}
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
<br/>
|
||||
<div class="alert alert-error">
|
||||
<h4><i>{{WARNING_ICON}}</i>Saving Dashboard Failed</h4>
|
||||
<br/>
|
||||
<p>
|
||||
Your dashboard couldn't be stored (error: "<?= $this->exceptionMessage; ?>"). This could have one or more
|
||||
of the following reasons:
|
||||
</p>
|
||||
<ul>
|
||||
<li>You don't have permissions to write to the dashboard file</li>
|
||||
<li>Something went wrong while writing the file</li>
|
||||
<li>There's an application error preventing you from persisting the configuration</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Details can be seen in your application log (if you don't have access to this file, call your administrator in this case).
|
||||
<br/>
|
||||
In case you can access the configuration file (config/dashboard/dashboard.ini) by yourself, you can open it and
|
||||
insert the config manually:
|
||||
</p>
|
||||
<p>
|
||||
<pre>
|
||||
<code>
|
||||
<?= $this->escape($this->iniConfigurationString); ?>
|
||||
</code>
|
||||
</pre>
|
||||
</p>
|
@ -8,6 +8,7 @@ use Icinga\Application\Icinga;
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Exception\ConfigurationError;
|
||||
use Icinga\Exception\ProgrammingError;
|
||||
use Icinga\User;
|
||||
use Icinga\Web\Widget\Dashboard\Pane;
|
||||
use Icinga\Web\Widget\Dashboard\Component as DashboardComponent;
|
||||
use Icinga\Web\Url;
|
||||
@ -23,13 +24,6 @@ use Icinga\Web\Url;
|
||||
*/
|
||||
class Dashboard extends AbstractWidget
|
||||
{
|
||||
/**
|
||||
* The configuration containing information about this dashboard
|
||||
*
|
||||
* @var Config;
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* An array containing all panes of this dashboard
|
||||
*
|
||||
@ -51,6 +45,11 @@ class Dashboard extends AbstractWidget
|
||||
*/
|
||||
private $tabParam = 'pane';
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $user;
|
||||
|
||||
/**
|
||||
* Set the given tab name as active.
|
||||
*
|
||||
@ -67,24 +66,72 @@ class Dashboard extends AbstractWidget
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public static function load()
|
||||
public function load()
|
||||
{
|
||||
/** @var $dashboard Dashboard */
|
||||
$dashboard = new static('dashboard');
|
||||
$manager = Icinga::app()->getModuleManager();
|
||||
foreach ($manager->getLoadedModules() as $module) {
|
||||
/** @var $module \Icinga\Application\Modules\Module */
|
||||
$dashboard->mergePanes($module->getPaneItems());
|
||||
$this->mergePanes($module->getPaneItems());
|
||||
|
||||
}
|
||||
return $dashboard;
|
||||
if ($this->user !== null) {
|
||||
$this->loadUserDashboards();
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function loadUserDashboards()
|
||||
{
|
||||
$configFile = '/var/lib/icingaweb/' . $this->user->getUsername() . '/dashboard.ini';
|
||||
$config = Config::fromIni($configFile);
|
||||
if (! count($config)) {
|
||||
return false;
|
||||
}
|
||||
$panes = array();
|
||||
$components = array();
|
||||
foreach ($config as $key => $part) {
|
||||
if (strpos($key, '.') === false) {
|
||||
$panes[$key] = new Pane($key);
|
||||
$panes[$key]->setTitle($part->title);
|
||||
|
||||
} else {
|
||||
list($paneName, $componentName) = explode('.', $key, 2);
|
||||
$part->pane = $paneName;
|
||||
$part->component = $componentName;
|
||||
$components[] = $part;
|
||||
}
|
||||
}
|
||||
foreach ($components as $componentData) {
|
||||
$pane = null;
|
||||
|
||||
if (array_key_exists($componentData->pane, $panes) === true) {
|
||||
$pane = $panes[$componentData->pane];
|
||||
} elseif (array_key_exists($componentData->pane, $this->panes) === true) {
|
||||
$pane = $this->panes[$componentData->pane];
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
$pane->addComponent(
|
||||
new DashboardComponent(
|
||||
$componentData->title,
|
||||
$componentData->url,
|
||||
$pane
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->mergePanes($panes);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge panes with existing panes
|
||||
*
|
||||
* @param array $panes
|
||||
* @return $this
|
||||
* @param array $panes
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function mergePanes(array $panes)
|
||||
{
|
||||
@ -134,23 +181,10 @@ class Dashboard extends AbstractWidget
|
||||
*/
|
||||
public function getPanes()
|
||||
{
|
||||
return '';
|
||||
return $this->panes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populate this dashboard via the given configuration file
|
||||
*
|
||||
* @param Config $config The configuration file to populate this dashboard with
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function readConfig(Config $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
$this->panes = array();
|
||||
$this->loadConfigPanes();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new empty pane with the given title
|
||||
@ -168,34 +202,6 @@ class Dashboard extends AbstractWidget
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update or adds a new component with the given url to a pane
|
||||
*
|
||||
* @TODO: Should only allow component objects to be added directly as soon as we store more information
|
||||
*
|
||||
* @param string $pane The pane to add the component to
|
||||
* @param Component|string $component The component to add or the title of the newly created component
|
||||
* @param string|null $url The url to use for the component
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setComponentUrl($pane, $component, $url)
|
||||
{
|
||||
if ($component === null && strpos($pane, '.')) {
|
||||
list($pane, $component) = preg_split('~\.~', $pane, 2);
|
||||
}
|
||||
if (!isset($this->panes[$pane])) {
|
||||
$this->createPane($pane);
|
||||
}
|
||||
$pane = $this->getPane($pane);
|
||||
if ($pane->hasComponent($component)) {
|
||||
$pane->getComponent($component)->setUrl($url);
|
||||
} else {
|
||||
$pane->addComponent($component, $url);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the current dashboard has any panes
|
||||
*
|
||||
@ -206,52 +212,6 @@ class Dashboard extends AbstractWidget
|
||||
return ! empty($this->panes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this dashboard has a specific pane
|
||||
*
|
||||
* @param $pane string The name of the pane
|
||||
* @return bool
|
||||
*/
|
||||
public function hasPane($pane)
|
||||
{
|
||||
return array_key_exists($pane, $this->panes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a component $component from the given pane
|
||||
*
|
||||
* @param string $pane The pane to remove the component from
|
||||
* @param Component|string $component The component to remove or it's name
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function removeComponent($pane, $component)
|
||||
{
|
||||
if ($component === null && strpos($pane, '.')) {
|
||||
list($pane, $component) = preg_split('~\.~', $pane, 2);
|
||||
}
|
||||
$pane = $this->getPane($pane);
|
||||
if ($pane !== null) {
|
||||
$pane->removeComponent($component);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array with pane name=>title format used for comboboxes
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getPaneKeyTitleArray()
|
||||
{
|
||||
$list = array();
|
||||
foreach ($this->panes as $name => $pane) {
|
||||
$list[$name] = $pane->getTitle();
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a pane object to this dashboard
|
||||
*
|
||||
@ -319,7 +279,10 @@ class Dashboard extends AbstractWidget
|
||||
/**
|
||||
* Determine the active pane either by the selected tab or the current request
|
||||
*
|
||||
* @return Pane The currently active pane
|
||||
* @throws \Icinga\Exception\ConfigurationError
|
||||
* @throws \Icinga\Exception\ProgrammingError
|
||||
*
|
||||
* @return Pane The currently active pane
|
||||
*/
|
||||
public function determineActivePane()
|
||||
{
|
||||
@ -346,36 +309,18 @@ class Dashboard extends AbstractWidget
|
||||
}
|
||||
|
||||
/**
|
||||
* Return this dashboard's structure as array
|
||||
*
|
||||
* @return array
|
||||
* @param \Icinga\User $user
|
||||
*/
|
||||
public function toArray()
|
||||
public function setUser($user)
|
||||
{
|
||||
$array = array();
|
||||
foreach ($this->panes as $pane) {
|
||||
$array += $pane->toArray();
|
||||
}
|
||||
|
||||
return $array;
|
||||
$this->user = $user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all config panes from @see Dashboard::$config
|
||||
*
|
||||
* @return \Icinga\User
|
||||
*/
|
||||
private function loadConfigPanes()
|
||||
public function getUser()
|
||||
{
|
||||
$items = $this->config;
|
||||
foreach ($items->keys() as $key) {
|
||||
$item = $this->config->get($key, false);
|
||||
if (false === strstr($key, '.')) {
|
||||
$this->addPane(Pane::fromIni($key, $item));
|
||||
} else {
|
||||
list($paneName, $title) = explode('.', $key, 2);
|
||||
$pane = $this->getPane($paneName);
|
||||
$pane->addComponent(DashboardComponent::fromIni($title, $item, $pane));
|
||||
}
|
||||
}
|
||||
return $this->user;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user