diff options
Diffstat (limited to '')
-rw-r--r-- | application/clicommands/ConvertCommand.php | 104 | ||||
-rw-r--r-- | application/clicommands/LegacyCommand.php | 92 | ||||
-rw-r--r-- | application/controllers/EditController.php | 92 | ||||
-rw-r--r-- | application/controllers/IndexController.php | 24 | ||||
-rw-r--r-- | application/controllers/ShowController.php | 93 | ||||
-rw-r--r-- | application/forms/EditForm.php | 176 | ||||
-rw-r--r-- | application/locale/de_DE/LC_MESSAGES/toplevelview.mo | bin | 0 -> 2751 bytes | |||
-rw-r--r-- | application/locale/de_DE/LC_MESSAGES/toplevelview.po | 163 | ||||
-rw-r--r-- | application/views/helpers/Badges.php | 49 | ||||
-rw-r--r-- | application/views/helpers/Breadcrumb.php | 32 | ||||
-rw-r--r-- | application/views/helpers/Tiles.php | 55 | ||||
-rw-r--r-- | application/views/helpers/Tree.php | 110 | ||||
-rw-r--r-- | application/views/scripts/edit/index.phtml | 36 | ||||
-rw-r--r-- | application/views/scripts/index/index.phtml | 51 | ||||
-rw-r--r-- | application/views/scripts/show/actions.phtml | 43 | ||||
-rw-r--r-- | application/views/scripts/show/index.phtml | 23 | ||||
-rw-r--r-- | application/views/scripts/show/tree.phtml | 22 | ||||
-rw-r--r-- | application/views/scripts/text/index.phtml | 11 |
18 files changed, 1176 insertions, 0 deletions
diff --git a/application/clicommands/ConvertCommand.php b/application/clicommands/ConvertCommand.php new file mode 100644 index 0000000..a05538b --- /dev/null +++ b/application/clicommands/ConvertCommand.php @@ -0,0 +1,104 @@ +<?php +/* TopLevelView module for Icingaweb2 - Copyright (c) 2017 Icinga Development Team <info@icinga.com> */ + +namespace Icinga\Module\Toplevelview\Clicommands; + +use Icinga\Exception\ConfigurationError; +use Icinga\Module\Toplevelview\Command; +use Icinga\Module\Toplevelview\Config\ConfigEmitter; +use Icinga\Module\Toplevelview\Legacy\LegacyDbHelper; +use Icinga\Module\Toplevelview\ViewConfig; +use Zend_Db_Adapter_Pdo_Sqlite; + +/** + * Converts a TopLevelView database into the new YAML configuration format + */ +class ConvertCommand extends Command +{ + protected $dbConnections = array(); + + public function init() + { + parent::init(); + + if (! extension_loaded('pdo_sqlite')) { + throw new ConfigurationError('You need the PHP extension "pdo_sqlite" in order to convert TopLevelView'); + } + } + + /** + * List all hierarchies in the database + * + * Arguments: + * --db <file> SQLite3 data from from old TopLevelView module + */ + public function listAction() + { + $dbFile = $this->params->getRequired('db'); + $db = $this->sqlite($dbFile); + + $helper = new LegacyDbHelper($db); + foreach ($helper->fetchHierarchies() as $root) { + printf("[%d] %s\n", $root['id'], $root['name']); + } + } + + /** + * Generate a YAML config file for Icinga Web 2 module + * + * Arguments: + * --db <file> SQLite3 data from from old TopLevelView module + * --id <id> Database id to export (see list) + * --output <file> Write to file (default '-' for stdout) + * --name <name> If name is specified instead of file, + * config is saved under that name + */ + public function convertAction() + { + $dbFile = $this->params->getRequired('db'); + $db = $this->sqlite($dbFile); + + $id = $this->params->getRequired('id'); + + $output = $this->params->get('output', null); + $name = $this->params->get('name', null); + $format = $this->params->get('format', 'yaml'); + + $helper = new LegacyDbHelper($db, $this->monitoringBackend()); + $tree = $helper->fetchTree($id); + + $emitter = ConfigEmitter::fromLegacyTree($tree); + + if ($name !== null and $output === null) { + $viewConfig = new ViewConfig(); + $viewConfig->setConfigDir(); + $viewConfig->setFormat(ViewConfig::FORMAT_YAML); + $viewConfig->setName($name); + $viewConfig->setText($emitter->emitYAML($format)); + $viewConfig->store(); + printf("Saved as config %s\n", $name); + exit(0); + } + + $text = $emitter->emit($format); + if ($output === null || $output === '-') { + echo $text; + } else { + file_put_contents($output, $text); + } + } + + /** + * Sets up the Zend PDO resource for SQLite + * + * @param string $file + * + * @return Zend_Db_Adapter_Pdo_Sqlite + */ + protected function sqlite($file) + { + return new Zend_Db_Adapter_Pdo_Sqlite(array( + 'dbname' => $file, + )); + } +} diff --git a/application/clicommands/LegacyCommand.php b/application/clicommands/LegacyCommand.php new file mode 100644 index 0000000..f9784be --- /dev/null +++ b/application/clicommands/LegacyCommand.php @@ -0,0 +1,92 @@ +<?php +/* TopLevelView module for Icingaweb2 - Copyright (c) 2021 Icinga Development Team <info@icinga.com> */ + +namespace Icinga\Module\Toplevelview\Clicommands; + +use Icinga\Exception\ConfigurationError; +use Icinga\Module\Monitoring\Backend\MonitoringBackend; +use Icinga\Module\Toplevelview\Command; +use Icinga\Module\Toplevelview\Legacy\LegacyDbHelper; +use Zend_Db_Adapter_Pdo_Sqlite; + +/** + * Tools for the legacy DB + */ +class LegacyCommand extends Command +{ + public function init() + { + parent::init(); + + if (! extension_loaded('pdo_sqlite')) { + throw new ConfigurationError('You need the PHP extension "pdo_sqlite" in order to convert TopLevelView'); + } + } + + /** + * Delete unreferenced objects from the database + * + * Arguments: + * --db <file> SQLite3 data from from old TopLevelView module + * --noop Only show counts, don't delete + */ + public function cleanupAction() + { + $dbFile = $this->params->getRequired('db'); + $noop = $this->params->shift('noop'); + $db = $this->sqlite($dbFile); + + $helper = new LegacyDbHelper($db); + + $result = $helper->cleanupUnreferencedObjects($noop); + foreach ($result as $type => $c) { + printf("%s: %d\n", $type, $c); + } + } + + /** + * Migrate database ids from an IDO to another IDO + * + * Arguments: + * --db <file> SQLite3 data from from old TopLevelView module + * --target <file> Target database path (will be overwritten) + * --old <backend> OLD IDO backend (configured in monitoring module) + * --new <backend> New IDO backend (configured in monitoring module) (optional) + * --purge Remove unresolvable data during update (see log) + */ + public function idomigrateAction() + { + $dbFile = $this->params->getRequired('db'); + $old = $this->params->getRequired('old'); + $target = $this->params->getRequired('target'); + $new = $this->params->get('new'); + $purge = $this->params->shift('purge'); + + $db = $this->sqlite($dbFile); + + $helper = new LegacyDbHelper($db, MonitoringBackend::instance($new)); + $helper->setOldBackend(MonitoringBackend::instance($old)); + + // Use the copy as db + $helper->setDb($helper->copySqliteDb($db, $target)); + + $result = $helper->migrateObjectIds(false, $purge); + foreach ($result as $type => $c) { + printf("%s: %d\n", $type, $c); + } + } + + /** + * Sets up the Zend PDO resource for SQLite + * + * @param string $file + * + * @return Zend_Db_Adapter_Pdo_Sqlite + */ + protected function sqlite($file) + { + return new Zend_Db_Adapter_Pdo_Sqlite(array( + 'dbname' => $file, + )); + } +} diff --git a/application/controllers/EditController.php b/application/controllers/EditController.php new file mode 100644 index 0000000..b91255c --- /dev/null +++ b/application/controllers/EditController.php @@ -0,0 +1,92 @@ +<?php +/* Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Toplevelview\Controllers; + +use Icinga\Module\Toplevelview\Forms\EditForm; +use Icinga\Module\Toplevelview\ViewConfig; +use Icinga\Module\Toplevelview\Web\Controller; +use Icinga\Web\Url; + +class EditController extends Controller +{ + public function init() + { + $this->assertPermission('toplevelview/edit'); + + $tabs = $this->getTabs(); + + if ($name = $this->getParam('name')) { + $tabs->add( + 'tiles', + array( + 'title' => $this->translate('Tiles'), + 'url' => Url::fromPath('toplevelview/show', array( + 'name' => $name + )) + ) + ); + + $tabs->add( + 'index', + array( + 'title' => $this->translate('Edit'), + 'url' => Url::fromPath('toplevelview/edit', array( + 'name' => $name + )) + ) + ); + } + + + $action = $this->getRequest()->getActionName(); + if ($tab = $tabs->get($action)) { + $tab->setActive(); + } + } + + public function indexAction() + { + $action = $this->getRequest()->getActionName(); + if ($action === 'add') { + $this->view->title = sprintf( + '%s Top Level View', + $this->translate('Add') + ); + $view = new ViewConfig(); + $view->setConfigDir(); + } elseif ($action === 'clone') { + $name = $this->params->getRequired('name'); + $this->view->title = sprintf( + '%s Top Level View', + $this->translate('Clone') + ); + $view = clone ViewConfig::loadByName($name); + } else { + $this->view->name = $name = $this->params->getRequired('name'); + $this->view->title = sprintf( + '%s Top Level View: %s', + $this->translate('Edit'), + $this->params->getRequired('name') + ); + $view = ViewConfig::loadByName($name); + } + + $this->view->form = $form = new EditForm(); + $view->setFormat(ViewConfig::FORMAT_YAML); + $form->setViewConfig($view); + $form->handleRequest(); + + $this->setViewScript('edit/index'); + } + + public function addAction() + { + $this->indexAction(); + } + + public function cloneAction() + { + $this->indexAction(); + } +} diff --git a/application/controllers/IndexController.php b/application/controllers/IndexController.php new file mode 100644 index 0000000..e1353f3 --- /dev/null +++ b/application/controllers/IndexController.php @@ -0,0 +1,24 @@ +<?php +/* Copyright (C) 2017 Icinga Development Team <info@icinga.com> */ + +namespace Icinga\Module\Toplevelview\Controllers; + +use Icinga\Module\Toplevelview\ViewConfig; +use Icinga\Module\Toplevelview\Web\Controller; + +class IndexController extends Controller +{ + public function indexAction() + { + $this->getTabs()->add( + 'index', + array( + 'title' => 'Top Level View', + 'url' => 'toplevelview', + ) + )->activate('index'); + $this->view->views = ViewConfig::loadAll(); + + $this->setAutorefreshInterval(30); + } +} diff --git a/application/controllers/ShowController.php b/application/controllers/ShowController.php new file mode 100644 index 0000000..d0560f2 --- /dev/null +++ b/application/controllers/ShowController.php @@ -0,0 +1,93 @@ +<?php +/* Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Toplevelview\Controllers; + +use Icinga\Module\Toplevelview\ViewConfig; +use Icinga\Module\Toplevelview\Web\Controller; +use Icinga\Web\Url; +use Icinga\Web\Widget\Tab; + +class ShowController extends Controller +{ + public function init() + { + $tabs = $this->getTabs(); + + $tiles = Url::fromPath('toplevelview/show', array( + 'name' => $this->params->getRequired('name') + )); + + $tabs->add( + 'index', + array( + 'title' => $this->translate('Tiles'), + 'url' => $tiles + ) + ); + + if (($id = $this->getParam('id')) !== null) { + $tabs->add( + 'tree', + array( + 'title' => $this->translate('Tree'), + 'url' => Url::fromPath('toplevelview/show/tree', array( + 'name' => $this->params->getRequired('name'), + 'id' => $id + )) + ) + ); + } + + $fullscreen = new Tab(array( + 'title' => $this->translate('Go Fullscreen'), + 'icon' => 'dashboard', + 'url' => ((string) $tiles) . '&view=compact&showFullscreen' + )); + $fullscreen->setTargetBlank(); + $tabs->addAsDropdown('fullscreen', $fullscreen); + + $action = $this->getRequest()->getActionName(); + if ($tab = $tabs->get($action)) { + $tab->setActive(); + } + } + + public function indexAction() + { + $this->view->name = $name = $this->params->getRequired('name'); + $this->view->view = $view = ViewConfig::loadByName($name); + $tree = $view->getTree(); + $tree->setBackend($this->monitoringBackend()); + + if (($lifetime = $this->getParam('cache')) !== null) { + $tree->setCacheLifetime($lifetime); + } + + $this->setAutorefreshInterval(30); + } + + public function treeAction() + { + $this->view->name = $name = $this->params->getRequired('name'); + $this->view->view = $view = ViewConfig::loadByName($name); + $tree = $view->getTree(); + $this->view->node = $tree->getById($this->params->getRequired('id')); + $tree->setBackend($this->monitoringBackend()); + + if (($lifetime = $this->getParam('cache')) !== null) { + $tree->setCacheLifetime($lifetime); + } + + $this->setAutorefreshInterval(30); + } + + public function sourceAction() + { + $this->view->name = $name = $this->params->getRequired('name'); + $this->view->view = $view = ViewConfig::loadByName($name); + + $this->view->text = $view->getText(); + $this->setViewScript('index', 'text'); + } +} diff --git a/application/forms/EditForm.php b/application/forms/EditForm.php new file mode 100644 index 0000000..86e7880 --- /dev/null +++ b/application/forms/EditForm.php @@ -0,0 +1,176 @@ +<?php +/* Icinga Web 2 | (c) 2014 Icinga Development Team | GPLv2+ */ + +namespace Icinga\Module\Toplevelview\Forms; + +use Exception; +use Icinga\Module\Toplevelview\ViewConfig; +use Icinga\Web\Form; +use Icinga\Web\Notification; +use Icinga\Web\Url; + +class EditForm extends Form +{ + /** + * @var ViewConfig + */ + protected $viewConfig; + + /** + * {@inheritdoc} + */ + public function init() + { + $this->setName('form_toplevelview_edit'); + } + + public function setViewConfig(ViewConfig $viewConfig) + { + $this->viewConfig = $viewConfig; + return $this; + } + + /** + * @see Form::onSuccess() + */ + public function onSuccess() + { + try { + $this->viewConfig->setName($this->getValue('name')); + $this->viewConfig->setText($this->getValue('config')); + + // ensure config can be parsed... + $this->viewConfig->getMetaData(); + $this->viewConfig->getTree(); + + $this->viewConfig->storeToSession(); + + $cancel = $this->getElement('btn_submit_cancel'); + $delete = $this->getElement('btn_submit_delete'); + + if ($this->getElement('btn_submit_save_file')->getValue() !== null) { + $this->viewConfig->store(); + Notification::success($this->translate('Top Level View successfully saved')); + } elseif ($cancel !== null && $cancel->getValue() !== null) { + $this->viewConfig->clearSession(); + Notification::success($this->translate('Top Level View restored from disk')); + } elseif ($delete != null && $delete->getValue() !== null) { + $this->viewConfig->delete(); + $this->setRedirectUrl('toplevelview'); + Notification::success($this->translate('Top Level View successfully deleted')); + } else { + Notification::success($this->translate('Top Level View successfully saved for the current session')); + } + return true; + } catch (Exception $e) { + $this->addError(sprintf('Could not save config: %s', $e->getMessage())); + return false; + } + } + + public function getRedirectUrl() + { + if ($this->redirectUrl === null && ($name = $this->viewConfig->getName()) !== null) { + $this->redirectUrl = Url::fromPath('toplevelview/show', array('name' => $name)); + } + return parent::getRedirectUrl(); + } + + /** + * Populate form + * + * @see Form::onRequest() + */ + public function onRequest() + { + $values = array(); + $values['name'] = $this->viewConfig->getName(); + $values['config'] = $this->viewConfig->getText(); + + $this->populate($values); + } + + /** + * @see Form::createElements() + */ + public function createElements(array $formData) + { + if ($this->viewConfig->hasBeenLoadedFromSession()) { + $this->warning( + $this->translate( + 'This config is only stored in your session!' + . ' Make sure to save it to disk once your work is complete!' + ), + false + ); + } + + $this->addElement( + 'text', + 'name', + array( + 'label' => $this->translate('File name'), + 'required' => true + ) + ); + $this->addElement( + 'textarea', + 'config', + array( + //'required' => true, + 'label' => $this->translate('YAML Config'), + 'class' => 'code-editor codemirror', + 'decorators' => array( + array('Label', array('tag'=>'div', 'separator' => '')), + array('HtmlTag', array('tag' => 'div')), + 'ViewHelper' + ), + 'data-codemirror-mode' => 'yaml' + ) + ); + + $this->addElement( + 'submit', + 'btn_submit_save_session', + array( + 'ignore' => true, + 'label' => $this->translate('Save for the current Session'), + 'decorators' => array('ViewHelper') + ) + ); + + $this->addElement( + 'submit', + 'btn_submit_save_file', + array( + 'ignore' => true, + 'label' => $this->translate('Save to config file'), + 'decorators' => array('ViewHelper') + ) + ); + + if ($this->viewConfig->hasBeenLoadedFromSession()) { + $this->addElement( + 'submit', + 'btn_submit_cancel', + array( + 'ignore' => true, + 'label' => $this->translate('Cancel editing'), + 'decorators' => array('ViewHelper') + ) + ); + } + + if ($this->viewConfig->hasBeenLoaded()) { + $this->addElement( + 'submit', + 'btn_submit_delete', + array( + 'ignore' => true, + 'label' => $this->translate('Delete config'), + 'decorators' => array('ViewHelper') + ) + ); + } + } +} diff --git a/application/locale/de_DE/LC_MESSAGES/toplevelview.mo b/application/locale/de_DE/LC_MESSAGES/toplevelview.mo Binary files differnew file mode 100644 index 0000000..9964d3f --- /dev/null +++ b/application/locale/de_DE/LC_MESSAGES/toplevelview.mo diff --git a/application/locale/de_DE/LC_MESSAGES/toplevelview.po b/application/locale/de_DE/LC_MESSAGES/toplevelview.po new file mode 100644 index 0000000..d562ff3 --- /dev/null +++ b/application/locale/de_DE/LC_MESSAGES/toplevelview.po @@ -0,0 +1,163 @@ +# Icinga Web 2 - Head for multiple monitoring backends. +# Copyright (C) 2017 Icinga Development Team +# This file is distributed under the same license as Toplevelview Module. +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Toplevelview Module (0.0.0)\n" +"Report-Msgid-Bugs-To: dev@icinga.com\n" +"POT-Creation-Date: 2017-10-13 11:53+0000\n" +"PO-Revision-Date: 2017-10-13 14:00+0200\n" +"Language: de_DE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Poedit-Basepath: .\n" +"Last-Translator: Markus Frosch <markus.frosch@icinga.com>\n" +"Language-Team: \n" +"X-Generator: Poedit 1.8.11\n" +"X-Poedit-SearchPath-0: .\n" + +#: ../../../../modules/toplevelview/application/views/helpers/Tree.php:58 +#, php-format +msgid "%s host" +msgid_plural "%s hosts" +msgstr[0] "%s Host" +msgstr[1] "%s Hosts" + +#: ../../../../modules/toplevelview/application/views/helpers/Tree.php:54 +#, php-format +msgid "%s unhandled host" +msgid_plural "%s unhandled hosts" +msgstr[0] "%s unbehandelte Problem" +msgstr[1] "%s unbehandelte Probleme" + +#: ../../../../modules/toplevelview/application/views/scripts/index/index.phtml:13 +#: ../../../../modules/toplevelview/application/controllers/EditController.php:53 +msgid "Add" +msgstr "Hinzufügen" + +#: ../../../../modules/toplevelview/configuration.php:9 +msgid "Allow the user to edit Top Level Views" +msgstr "Erlauben dass Benutzer Top Level Views ändern" + +#: ../../../../modules/toplevelview/application/forms/EditForm.php:157 +msgid "Cancel editing" +msgstr "Bearbeitung abbrechen" + +#: ../../../../modules/toplevelview/application/views/scripts/show/actions.phtml:19 +#: ../../../../modules/toplevelview/application/controllers/EditController.php:60 +msgid "Clone" +msgstr "Klonen" + +#: ../../../../modules/toplevelview/application/forms/EditForm.php:169 +msgid "Delete config" +msgstr "Konfiguration löschen" + +#: ../../../../modules/toplevelview/application/views/scripts/index/index.phtml:38 +#: ../../../../modules/toplevelview/application/views/scripts/show/actions.phtml:9 +#: ../../../../modules/toplevelview/application/controllers/EditController.php:33 +#: ../../../../modules/toplevelview/application/controllers/EditController.php:66 +msgid "Edit" +msgstr "Bearbeiten" + +#: ../../../../modules/toplevelview/application/views/scripts/edit/index.phtml:9 +msgid "Editor Help" +msgstr "Editor Hilfe" + +#: ../../../../modules/toplevelview/application/forms/EditForm.php:111 +msgid "File name" +msgstr "Dateiname" + +#: ../../../../modules/toplevelview/application/views/scripts/edit/index.phtml:17 +msgid "Find next" +msgstr "Nächster Treffer" + +#: ../../../../modules/toplevelview/application/views/scripts/edit/index.phtml:21 +msgid "Find previous" +msgstr "Vorheriger Treffer" + +#: ../../../../modules/toplevelview/application/controllers/ShowController.php:43 +msgid "Go Fullscreen" +msgstr "Zur Vollbildansicht" + +#: ../../../../modules/toplevelview/application/views/scripts/edit/index.phtml:33 +msgid "Jump to line" +msgstr "Zu Zeile springen" + +#: ../../../../modules/toplevelview/application/views/scripts/show/tree.phtml:16 +#: ../../../../modules/toplevelview/application/views/scripts/show/index.phtml:14 +msgid "Last update" +msgstr "Letzte Aktualisierung" + +#: ../../../../modules/toplevelview/application/views/scripts/edit/index.phtml:13 +msgid "" +"Persistent search (dialog doesn't autoclose, enter to find next, Shift-Enter " +"to find previous)" +msgstr "" +"Dauerhafte Suche (Dialog schließt nicht automatisch, Enter für nächsten " +"Treffer, Shift-Enter für Vorherigen)" + +#: ../../../../modules/toplevelview/application/views/scripts/edit/index.phtml:25 +msgid "Replace" +msgstr "Ersetzen" + +#: ../../../../modules/toplevelview/application/views/scripts/edit/index.phtml:29 +msgid "Replace all" +msgstr "Alle Ersetzen" + +#: ../../../../modules/toplevelview/application/forms/EditForm.php:136 +msgid "Save for the current Session" +msgstr "Für die aktuelle Sitzung speichern" + +#: ../../../../modules/toplevelview/application/forms/EditForm.php:146 +msgid "Save to config file" +msgstr "Speichern in Konfigurationsdatei" + +#: ../../../../modules/toplevelview/application/views/scripts/show/actions.phtml:30 +msgid "Source" +msgstr "Quelle" + +#: ../../../../modules/toplevelview/application/views/scripts/show/actions.phtml:39 +#: ../../../../modules/toplevelview/application/forms/EditForm.php:101 +msgid "" +"This config is only stored in your session! Make sure to save it to disk " +"once your work is complete!" +msgstr "" +"Diese Konfiguration ist nur in Ihrer Sitzung gespeichert! Stellen Sie sicher " +"sie in eine Datei zu speichern wenn Ihre Änderung fertig ist!" + +#: ../../../../modules/toplevelview/application/controllers/ShowController.php:24 +#: ../../../../modules/toplevelview/application/controllers/EditController.php:23 +msgid "Tiles" +msgstr "Kacheln" + +#: ../../../../modules/toplevelview/application/forms/EditForm.php:56 +msgid "Top Level View restored from disk" +msgstr "Top Level View von Speicher wiederhergestellt" + +#: ../../../../modules/toplevelview/application/forms/EditForm.php:60 +msgid "Top Level View successfully deleted" +msgstr "Top Level View erfolgreich gelöscht" + +#: ../../../../modules/toplevelview/application/forms/EditForm.php:53 +msgid "Top Level View successfully saved" +msgstr "Top Level View erfolgreich gespeichert" + +#: ../../../../modules/toplevelview/application/forms/EditForm.php:62 +msgid "Top Level View successfully saved for the current session" +msgstr "Top Level View erfolgreich für Ihre Sitzung gespeichert" + +#: ../../../../modules/toplevelview/application/controllers/ShowController.php:33 +msgid "Tree" +msgstr "Baum" + +#: ../../../../modules/toplevelview/application/views/scripts/index/index.phtml:32 +msgid "Unsaved changes!" +msgstr "Nicht-Gespeicherte Änderungen!" + +#: ../../../../modules/toplevelview/application/forms/EditForm.php:120 +msgid "YAML Config" +msgstr "YAML Konfiguration" diff --git a/application/views/helpers/Badges.php b/application/views/helpers/Badges.php new file mode 100644 index 0000000..6066a72 --- /dev/null +++ b/application/views/helpers/Badges.php @@ -0,0 +1,49 @@ +<?php +/* Icinga Web 2 Top Level View | (c) 2017 Icinga Development Team | GPLv2+ */ + +use Icinga\Module\Toplevelview\Tree\TLVStatus; +use Icinga\Web\Url; + +class Zend_View_Helper_Badges extends Zend_View_Helper_Abstract +{ + /** @var \Icinga\Web\View */ + public $view; + + protected function prettyTitle($identifier) + { + $s = ''; + foreach (preg_split('/[\.\-_\s]+/', $identifier) as $p) { + $s .= ' ' . ucfirst($p); + } + return trim($s); + } + + public function badges(TLVStatus $status, $problemsOnly = true, $showTotal = false) + { + $htm = ''; + + $values = false; + $htm .= '<div class="badges">'; + foreach ($status->getProperties() as $key => $value) { + if ($problemsOnly === true && ($key === 'ok' || $key === 'downtime_active') + || ($key === 'total' && $showTotal !== true) + ) { + continue; + } + if ($value !== null && $value > 0) { + $values = true; + $title = $value . ' ' . $this->prettyTitle($key); + $class = 'tlv-status-tile ' . str_replace('_', ' ', $key); + $htm .= sprintf( + '<div class="badge status-badge %s" title="%s">%s</div>', + $class, + $title, + $value + ); + } + } + $htm .= '</div>'; + + return $values ? $htm : ''; + } +} diff --git a/application/views/helpers/Breadcrumb.php b/application/views/helpers/Breadcrumb.php new file mode 100644 index 0000000..3263712 --- /dev/null +++ b/application/views/helpers/Breadcrumb.php @@ -0,0 +1,32 @@ +<?php +/* Icinga Web 2 | (c) 2016 Icinga Development Team | GPLv2+ */ + +use Icinga\Module\Toplevelview\Tree\TLVTreeNode; + +class Zend_View_Helper_Breadcrumb extends Zend_View_Helper_Abstract +{ + /** @var \Icinga\Web\View */ + public $view; + + /** + * @param TLVTreeNode[] $breadcrumb + * + * @return string + */ + public function breadcrumb($breadcrumb, $config_name) + { + $htm = '<ul class="breadcrumb">'; + foreach ($breadcrumb as $crumb) { + $htm .= '<li>' . $this->view->qlink( + $crumb->getTitle(), + 'toplevelview/show/tree', + array( + 'name' => $config_name, + 'id' => $crumb->getFullId() + ) + ) . '</li>'; + } + $htm .= '</ul>'; + return $htm; + } +} diff --git a/application/views/helpers/Tiles.php b/application/views/helpers/Tiles.php new file mode 100644 index 0000000..dcefbfe --- /dev/null +++ b/application/views/helpers/Tiles.php @@ -0,0 +1,55 @@ +<?php +/* Icinga Web 2 Top Level View | (c) 2017 Icinga Development Team | GPLv2+ */ + +use Icinga\Module\Toplevelview\Tree\TLVTreeNode; + +class Zend_View_Helper_Tiles extends Zend_View_Helper_Abstract +{ + /** @var \Icinga\Web\View */ + public $view; + + public function tiles(TLVTreeNode $node, $levels = 2, $classes = array()) + { + $htm = ''; + $title = $this->view->escape($node->getTitle()); + + $status = $node->getStatus(); + if ($levels > 1) { + $statusClass = 'tlv-status-section'; + } else { + $statusClass = 'tlv-status-tile'; + } + $statusClasses = array($statusClass, $status->getOverall()); + + $htm .= sprintf( + '<div class="tlv-tile %s" title="%s" data-base-target="_next">' . "\n", + join(' ', $classes + $statusClasses), + $title + ); + $badges = $this->view->badges($status); + + $htm .= $this->view->qlink( + $title . $badges, + 'toplevelview/show/tree', + array( + 'name' => $node->getRoot()->getConfig()->getName(), + 'id' => $node->getFullId() + ), + array( + 'class' => 'tlv-tile-title' + ), + false + ); + + if ($levels > 1 && $node->hasChildren()) { + $htm .= '<div class="tlv-tiles">'; + foreach ($node->getChildren() as $child) { + $htm .= $this->tiles($child, $levels - 1, $classes); + } + $htm .= '</div>'; + } + + $htm .= "</div>\n"; + return $htm; + } +} diff --git a/application/views/helpers/Tree.php b/application/views/helpers/Tree.php new file mode 100644 index 0000000..a016b68 --- /dev/null +++ b/application/views/helpers/Tree.php @@ -0,0 +1,110 @@ +<?php +/* Icinga Web 2 Top Level View | (c) 2017 Icinga Development Team | GPLv2+ */ + +use Icinga\Module\Toplevelview\Tree\TLVTreeNode; +use Icinga\Web\Url; + +class Zend_View_Helper_Tree extends Zend_View_Helper_Abstract +{ + /** @var \Icinga\Web\View */ + public $view; + + public function tree(TLVTreeNode $node, $classes = array(), $level = 0) + { + $htm = ''; + $htmExtra = ''; + $title = $node->getTitle(); + $type = $node->getType(); + + $cssClasses = join(' ', $classes); + + $status = $node->getStatus(); + $statusClass = $status->getOverall(); + + if ($type === 'host') { + $icon = 'host'; + $url = Url::fromPath( + 'monitoring/host/show', + array( + 'host' => $node->get('host') + ) + ); + } elseif ($type === 'service') { + $icon = 'service'; + $url = Url::fromPath( + 'monitoring/service/show', + array( + 'host' => $node->get('host'), + 'service' => $node->get('service') + ) + ); + } elseif ($type === 'hostgroup') { + $icon = 'cubes'; + $url = Url::fromPath( + 'monitoring/list/services', + array( + 'hostgroup' => $node->get('hostgroup'), + 'sort' => 'service_severity', + 'dir' => 'desc', + ) + ); + + if (($h = $status->getMeta('hosts_unhandled')) > 0) { + $hostTitle = '(<strong>' + . sprintf($this->view->translatePlural('%s unhandled host', '%s unhandled hosts', $h), $h) + . '</strong>)'; + } else { + $h = $status->getMeta('hosts_total'); + $hostTitle = '(' . sprintf($this->view->translatePlural('%s host', '%s hosts', $h), $h) . ')'; + } + + $htmExtra .= ' ' . $this->view->qlink( + $hostTitle, + 'monitoring/list/hosts', + array( + 'hostgroup' => $node->get('hostgroup'), + 'sort' => 'host_severity', + 'dir' => 'desc', + ), + null, + false + ); + } else { + $icon = null; + $url = Url::fromPath( + 'toplevelview/show/tree', + array( + 'name' => $node->getRoot()->getConfig()->getName(), + 'id' => $node->getFullId() + ) + ); + } + + if ($type !== 'node') { + $htm .= "<div class=\"tlv-node-icinga tlv-node-\$type tlv-status-tile action $statusClass $cssClasses\"" + . " data-base-target=\"_next\" href=\"$url\">"; + $htm .= $this->view->icon($icon) . ' '; + $htm .= $this->view->qlink($title, $url); + $htm .= $htmExtra; + $htm .= ' ' . $this->view->badges($status, false); + $htm .= '</div>'; + } else { + $htm .= "<div class=\"tlv-tree-node tlv-status-section tlv-collapsible $statusClass $cssClasses\""; + $htm .= " title=\"$title\">"; + $htm .= '<div class="tlv-tree-title">'; + $htm .= $this->view->badges($status, false, $level === 0 ? true : false); + $htm .= '<i class="icon icon-bycss tlv-collapse-handle"></i> '; + $htm .= $this->view->qlink($title, $url); + $htm .= $htmExtra; + $htm .= '</div>'; + if ($node->hasChildren()) { + foreach ($node->getChildren() as $child) { + $htm .= $this->tree($child, $classes, $level + 1); + } + } + $htm .= '</div>'; + } + + return $htm; + } +} diff --git a/application/views/scripts/edit/index.phtml b/application/views/scripts/edit/index.phtml new file mode 100644 index 0000000..614e962 --- /dev/null +++ b/application/views/scripts/edit/index.phtml @@ -0,0 +1,36 @@ +<?php if (! $this->compact): ?> +<div class="controls"> + <?= $this->tabs ?> +</div> +<?php endif ?> +<div class="content full-form"> + <h1><?= $title ?></h1> + <?= $form ?> + <h2><?= $this->translate('Editor Help') ?></h2> + <table class="name-value-table"> + <tr> + <th>Ctrl-F / Cmd-F</th> + <td><?= $this->translate('Persistent search (dialog doesn\'t autoclose, enter to find next, Shift-Enter to find previous)') ?></td> + </tr> + <tr> + <th>Ctrl-G / Cmd-G</th> + <td><?= $this->translate('Find next') ?></td> + </tr> + <tr> + <th>Shift-Ctrl-G / Shift-Cmd-G</th> + <td><?= $this->translate('Find previous') ?></td> + </tr> + <tr> + <th>Shift-Ctrl-F / Cmd-Option-F</th> + <td><?= $this->translate('Replace') ?></td> + </tr> + <tr> + <th>Shift-Ctrl-R / Shift-Cmd-Option-F</th> + <td><?= $this->translate('Replace all') ?></td> + </tr> + <tr> + <th>Alt-G</th> + <td><?= $this->translate('Jump to line') ?></td> + </tr> + </table> +</div> diff --git a/application/views/scripts/index/index.phtml b/application/views/scripts/index/index.phtml new file mode 100644 index 0000000..3797583 --- /dev/null +++ b/application/views/scripts/index/index.phtml @@ -0,0 +1,51 @@ +<?php +/** @var array $views */ + +if (! $this->compact): ?> + <div class="controls"> + <?= $this->tabs ?> + </div> +<?php endif ?> +<div class="content"> + <div class="tlv-overview-tiles"> + <div class="action-links"> + <?= $this->qlink( + $this->translate('Add'), + 'toplevelview/edit/add', + array(), + array( + 'class' => 'action-link', + 'icon' => 'plus', + ) + ) ?> + </div> + + <?php + foreach ($views as $name => $view): + /** @var \Icinga\Module\Toplevelview\ViewConfig $view */ + $url = $this->url('toplevelview/show', array('name' => $name)); + ?> + <div class="tlv-overview-tile"> + <div class="tlv-title"><?= $this->qlink($view->getMeta('name'), $url) ?></div> + <div class="tlv-name"><?= $name ?></div> + <?php if ($view->hasBeenLoadedFromSession()): ?> + <div class="unsaved"><?= $this->translate('Unsaved changes!') ?></div> + <?php endif; ?> + + <?php if (! $this->compact && $this->hasPermission('toplevelview/edit')): ?> + <div class="action-links"> + <?= $this->qlink( + $this->translate('Edit'), + 'toplevelview/edit', + array('name' => $view->getName()), + array( + 'class' => 'action-link', + 'icon' => 'edit', + ) + ) ?> + </div> + <?php endif; ?> + </div> + <?php endforeach; ?> + </div> +</div> diff --git a/application/views/scripts/show/actions.phtml b/application/views/scripts/show/actions.phtml new file mode 100644 index 0000000..c72d5a6 --- /dev/null +++ b/application/views/scripts/show/actions.phtml @@ -0,0 +1,43 @@ +<?php +/** @var \Icinga\Module\Toplevelview\ViewConfig $view */ +?> +<div class="action-links"> + <?php + if (! $this->compact) { + if ($this->hasPermission('toplevelview/edit')) { + echo $this->qlink( + $this->translate('Edit'), + 'toplevelview/edit', + array('name' => $view->getName()), + array( + 'class' => 'action-link', + 'icon' => 'edit', + 'data-base-target' => '_next' + ) + ); + echo $this->qlink( + $this->translate('Clone'), + 'toplevelview/edit/clone', + array('name' => $view->getName()), + array( + 'class' => 'action-link', + 'icon' => 'rewind', + 'data-base-target' => '_next' + ) + ); + } else { + echo $this->qlink( + $this->translate('Source'), + 'toplevelview/show/source', + array('name' => $view->getName()) + ); + } + } + ?> + <?php if ($view->hasBeenLoadedFromSession()): ?> + <div class="warning-note"> + <?= $this->translate('This config is only stored in your session!' + . ' Make sure to save it to disk once your work is complete!') ?> + </div> + <?php endif; ?> +</div> diff --git a/application/views/scripts/show/index.phtml b/application/views/scripts/show/index.phtml new file mode 100644 index 0000000..8278ae4 --- /dev/null +++ b/application/views/scripts/show/index.phtml @@ -0,0 +1,23 @@ +<?php +/** @var \Icinga\Web\View $this */ +/** @var \Icinga\Module\Toplevelview\ViewConfig $view */ +$tree = $view->getTree(); +if (! $this->compact): +?> +<div class="controls"> + <?= $this->tabs ?> +</div> +<?php endif ?> +<div class="content tlv-content"> + <div class="tlv-header"> + <?= $this->badges($tree->getStatus(), false, true) ?> + <h1><?= $view->getMeta('name') ?></h1> + <?= $this->partial('show/actions.phtml', $this) ?> + <div class="last-refresh"><?= $this->timeAgo($tree->getFetchTime()) ?></div> + </div> + <div class="tlv-view-tiles"> + <?php foreach ($tree->getChildren() as $topTile): ?> + <?= $this->tiles($topTile) ?> + <?php endforeach; ?> + </div> +</div> diff --git a/application/views/scripts/show/tree.phtml b/application/views/scripts/show/tree.phtml new file mode 100644 index 0000000..52e4f80 --- /dev/null +++ b/application/views/scripts/show/tree.phtml @@ -0,0 +1,22 @@ +<?php +/** @var \Icinga\Module\Toplevelview\ViewConfig $view */ +/** @var \Icinga\Module\Toplevelview\Tree\TLVTreeNode $node */ + +$tree = $view->getTree(); + +if (! $this->compact): +?> +<div class="controls"> + <?= $this->tabs ?> +</div> +<?php endif ?> +<div class="content tlv-view-tree"> + <div class="tlv-header"> + <?= $this->badges($tree->getStatus(), false, true) ?> + <h1><?= $view->getMeta('name') ?></h1> + <?= $this->partial('show/actions.phtml', $this) ?> + <div class="last-refresh"><?= $this->timeAgo($tree->getFetchTime()) ?></div> + </div> + <?= $this->breadcrumb($node->getBreadCrumb(), $view->getName()) ?> + <?= $this->tree($node) ?> +</div> diff --git a/application/views/scripts/text/index.phtml b/application/views/scripts/text/index.phtml new file mode 100644 index 0000000..82b8ee8 --- /dev/null +++ b/application/views/scripts/text/index.phtml @@ -0,0 +1,11 @@ +<?php +/** @var \Icinga\Module\Toplevelview\ViewConfig $view */ +if (! $this->compact): +?> +<div class="controls"> + <?= $this->tabs ?> +</div> +<?php endif ?> +<div class="content"> + <pre><?= $this->text ?></pre> +</div> |